Add timeout feature
Subsystems (4)
RFC PATCH 3/3 Add timeout feature
The timeout feature is added to freeze ioctl. And new ioctl to reset the timeout period is added.
o Freeze the filesystem
int ioctl(int fd, int FIFREEZE, long *timeval)
fd: The file descriptor of the mountpoint
FIFREEZE: request code for the freeze
timeval: the timeout period in seconds
If it's 0 or 1, the timeout isn't set. This special case of "1" is implemented to keep the compatibility with XFS applications.
Return value: 0 if the operation succeeds. Otherwise, -1
o Reset the timeout period
int ioctl(int fd, int FIFREEZE_RESET_TIMEOUT, long *timeval)
fd:file descriptor of mountpoint
FIFREEZE_RESET_TIMEOUT: request code for reset of timeout period
timeval: new timeout period in seconds
Return value: 0 if the operation succeeds. Otherwise, -1 Error number: If the filesystem has already been unfrozen,
errno is set to EINVAL.
--- drivers/md/dm.c | 2 - fs/block_dev.c | 2 + fs/buffer.c | 14 ++++++++- fs/ioctl.c | 64 +++++++++++++++++++++++++++++++++++++++++++- fs/super.c | 52 +++++++++++++++++++++++++++++++++++ fs/xfs/xfs_fsops.c | 2 - include/linux/buffer_head.h | 2 - include/linux/fs.h | 8 +++++ 8 files changed, 140 insertions(+), 6 deletions(-)
drivers/md/dm.c +1 -1
@@ -1407,7 +1407,7 @@ static int lock_fs(struct mapped_deviceWARN_ON (md->frozen_sb); - md->frozen_sb =freeze_bdev (md->suspended_bdev); + md->frozen_sb =freeze_bdev (md->suspended_bdev,0 );if (IS_ERR (md->frozen_sb)) { r =PTR_ERR (md->frozen_sb); md->frozen_sb =NULL ;
fs/block_dev.c +2 -0
@@ -287,6 +287,8 @@ static void init_once(struct kmem_cache/* Initialize semaphore for freeze. */ sema_init (&bdev->bd_freeze_sem,1 ); +/* Setup freeze timeout function. */ +INIT_DELAYED_WORK (&bdev->bd_freeze_timeout, freeze_timeout); }static inline void __bd_forget (struct inode *inode)
fs/buffer.c +12 -2
@@ -190,14 +190,17 @@ int fsync_bdev(struct block_device *bdev/** * freeze_bdev -- lock a filesystem and force it into a consistent state -* @bdev: blockdevice to lock +* @bdev: blockdevice to lock +* @timeout_msec: timeout period * * This takes the block device bd_mount_sem to make sure no new mounts * happen on bdev until thaw_bdev() is called. * If a superblock is found on this device, we take the s_umount semaphore * on it to make sure nobody unmounts until the snapshot creation is done. +* If timeout_msec is bigger than 0, this registers the delayed work for +* timeout of the freeze feature. */ -struct super_block *freeze_bdev (struct block_device *bdev) +struct super_block *freeze_bdev (struct block_device *bdev,long timeout_msec) {struct super_block *sb;
@@ -233,6 +236,10 @@ struct super_block *freeze_bdev(struct bsync_blockdev (bdev); +/* Setup unfreeze timer. */ +if (timeout_msec >0 ) +add_freeze_timeout (bdev, timeout_msec); +up (&bdev->bd_freeze_sem);return sb;/* thaw_bdev releases s->s_umount and bd_mount_sem */
@@ -255,6 +262,9 @@ void thaw_bdev(struct block_device *bdevreturn ; } +/* Delete unfreeze timer. */ +del_freeze_timeout (bdev); +if (sb) {BUG_ON (sb->s_bdev != bdev);
fs/ioctl.c +63 -1
83 lines not on this page · raw message
fs/super.c +52 -0
55 lines not on this page · raw message
diff -uprN -X /home/sho/pub/MC/freeze-set/dontdiff linux-2.6.25-xfs/fs/xfs/xfs_fsops.c linux-2.6.25-timeout/fs/xfs/xfs_f sops.c
fs/xfs/xfs_fsops.c +1 -1
@@ -623,7 +623,7 @@ xfs_fs_goingdown( {switch (inflags) {case XFS_FSOP_GOING_FLAGS_DEFAULT : { -struct super_block *sb =freeze_bdev (mp->m_super->s_bdev); +struct super_block *sb =freeze_bdev (mp->m_super->s_bdev,0 );if (sb && !IS_ERR (sb)) {xfs_force_shutdown (mp,SHUTDOWN_FORCE_UMOUNT );
diff -uprN -X /home/sho/pub/MC/freeze-set/dontdiff linux-2.6.25-xfs/include/linux/buffer_head.h linux-2.6.25-timeout/inc lude/linux/buffer_head.h
include/linux/buffer_head.h +1 -1
@@ -170,7 +170,7 @@ int sync_blockdev(struct block_device *bvoid __wait_on_buffer (struct buffer_head *);wait_queue_head_t *bh_waitq_head (struct buffer_head *bh);int fsync_bdev (struct block_device *); -struct super_block *freeze_bdev (struct block_device *); +struct super_block *freeze_bdev (struct block_device *,long timeout_msec);void thaw_bdev (struct block_device *,struct super_block *);int fsync_super (struct super_block *);int fsync_no_super (struct block_device *);
diff -uprN -X /home/sho/pub/MC/freeze-set/dontdiff linux-2.6.25-xfs/include/linux/fs.h linux-2.6.25-timeout/include/linu x/fs.h
include/linux/fs.h +8 -0
@@ -8,6 +8,7 @@#include <linux/limits.h> #include <linux/ioctl.h> +#include <linux/workqueue.h> /* * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
@@ -225,6 +226,7 @@ extern int dir_notify_enable;#define FIGETBSZ _IO(0x00,2)/* get the block size used for bmap */ #define FIFREEZE _IOWR('X', 119, int)/* Freeze */ #define FITHAW _IOWR('X', 120, int)/* Thaw */ +#define FIFREEZE_RESET_TIMEOUT _IO(0x00, 3)/* Reset freeze timeout */ #define FS_IOC_GETFLAGS _IOR('f', 1, long)#define FS_IOC_SETFLAGS _IOW('f', 2, long)
@@ -551,6 +553,8 @@ struct block_device {*/ unsigned long bd_private; +/* Delayed work for freeze */ +struct delayed_work bd_freeze_timeout;/* Semaphore for freeze */ struct semaphore bd_freeze_sem; };
@@ -2104,5 +2108,9 @@ int proc_nr_files(struct ctl_table *tablint get_filesystem_list (char * buf); +extern void add_freeze_timeout (struct block_device *bdev,long timeout_msec); +extern void del_freeze_timeout (struct block_device *bdev); +extern void freeze_timeout (struct work_struct *work); +#endif /* __KERNEL__ */ #endif /* _LINUX_FS_H */