* [PATCH 0/2] fsfreeze: check ioctls
@ 2011-07-21 2:32 Fernando Luis Vazquez Cao
2011-07-21 2:36 ` [PATCH 1/2] fsfreeze: add FIISFROZEN ioctl Fernando Luis Vazquez Cao
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Fernando Luis Vazquez Cao @ 2011-07-21 2:32 UTC (permalink / raw)
To: Al Viro; +Cc: Christoph Hellwig, Eric Sandeen, Josef Bacik, linux-fsdevel
The current fsfreeze API lacks a method to check the current freeze
status of a superblock. One might be tempted to think that a new vfs
ioctl is all we need, but with the current implemetation of fsfreeze it
it is possible to umount a freezed filesystem, which means that the only
way to check the freeze status is through the block device. For a moment
I thought I could get without the vfs version but then I realized that
the block device ioctl would not play well with btrfs.
Because of all of the above I ended up implementing both. Al also
suggested [1] a thaw-by-block-device ioctl which I am currently working
on.
[1] http://marc.info/?l=linux-kernel&m=125361768208298&w=2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] fsfreeze: add FIISFROZEN ioctl
2011-07-21 2:32 [PATCH 0/2] fsfreeze: check ioctls Fernando Luis Vazquez Cao
@ 2011-07-21 2:36 ` Fernando Luis Vazquez Cao
2011-07-21 2:41 ` [PATCH 2/2] fsfreeze: add BLKISFROZEN ioctl Fernando Luis Vazquez Cao
2011-07-27 7:30 ` [RFC][PATCH 0/4] fsfreeze: new API Fernando Luis Vazquez Cao
2 siblings, 0 replies; 8+ messages in thread
From: Fernando Luis Vazquez Cao @ 2011-07-21 2:36 UTC (permalink / raw)
To: Al Viro; +Cc: Christoph Hellwig, Eric Sandeen, Josef Bacik, linux-fsdevel
The FIISFROZEN ioctl can be use by HA and monitoring software to check
the freeze state of a mounted filesystem.
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
diff -urNp linux-3.0-rc7-orig/fs/compat_ioctl.c linux-3.0-rc7/fs/compat_ioctl.c
--- linux-3.0-rc7-orig/fs/compat_ioctl.c 2011-05-19 13:06:34.000000000 +0900
+++ linux-3.0-rc7/fs/compat_ioctl.c 2011-07-20 15:33:40.615998033 +0900
@@ -883,6 +883,7 @@ COMPATIBLE_IOCTL(FIGETBSZ)
/* 'X' - originally XFS but some now in the VFS */
COMPATIBLE_IOCTL(FIFREEZE)
COMPATIBLE_IOCTL(FITHAW)
+COMPATIBLE_IOCTL(FIISFROZEN)
COMPATIBLE_IOCTL(KDGETKEYCODE)
COMPATIBLE_IOCTL(KDSETKEYCODE)
COMPATIBLE_IOCTL(KDGKBTYPE)
diff -urNp linux-3.0-rc7-orig/fs/ioctl.c linux-3.0-rc7/fs/ioctl.c
--- linux-3.0-rc7-orig/fs/ioctl.c 2011-05-19 13:06:34.000000000 +0900
+++ linux-3.0-rc7/fs/ioctl.c 2011-07-20 12:23:06.124003192 +0900
@@ -536,6 +536,16 @@ static int ioctl_fsthaw(struct file *fil
return thaw_super(sb);
}
+static int ioctl_fs_isfrozen(struct file *filp)
+{
+ struct super_block *sb = filp->f_path.dentry->d_inode->i_sb;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ return isfrozen_super(sb);
+}
+
/*
* When you add any new common ioctls to the switches above and below
* please update compat_sys_ioctl() too.
@@ -585,6 +595,12 @@ int do_vfs_ioctl(struct file *filp, unsi
error = ioctl_fsthaw(filp);
break;
+ case FIISFROZEN:
+ error = ioctl_fs_isfrozen(filp);
+ if (error >= 0)
+ return put_user(error, (int __user *)arg);
+ break;
+
case FS_IOC_FIEMAP:
return ioctl_fiemap(filp, arg);
diff -urNp linux-3.0-rc7-orig/fs/super.c linux-3.0-rc7/fs/super.c
--- linux-3.0-rc7-orig/fs/super.c 2011-07-12 09:55:50.804000002 +0900
+++ linux-3.0-rc7/fs/super.c 2011-07-19 17:45:56.816155171 +0900
@@ -1057,3 +1057,8 @@ out:
return 0;
}
EXPORT_SYMBOL(thaw_super);
+
+int isfrozen_super(struct super_block *sb)
+{
+ return sb->s_frozen > SB_UNFROZEN ? 1:0;
+}
diff -urNp linux-3.0-rc7-orig/include/linux/fs.h linux-3.0-rc7/include/linux/fs.h
--- linux-3.0-rc7-orig/include/linux/fs.h 2011-07-12 09:55:51.192000002 +0900
+++ linux-3.0-rc7/include/linux/fs.h 2011-07-20 12:27:59.443932676 +0900
@@ -324,6 +325,7 @@ struct inodes_stat_t {
#define FIFREEZE _IOWR('X', 119, int) /* Freeze */
#define FITHAW _IOWR('X', 120, int) /* Thaw */
#define FITRIM _IOWR('X', 121, struct fstrim_range) /* Trim */
+#define FIISFROZEN _IOR('X', 122, int) /* get sb freeze state */
#define FS_IOC_GETFLAGS _IOR('f', 1, long)
#define FS_IOC_SETFLAGS _IOW('f', 2, long)
@@ -1882,6 +1884,7 @@ extern int fd_statfs(int, struct kstatfs
extern int statfs_by_dentry(struct dentry *, struct kstatfs *);
extern int freeze_super(struct super_block *super);
extern int thaw_super(struct super_block *super);
+extern int isfrozen_super(struct super_block *sb);
extern int current_umask(void);
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] fsfreeze: add BLKISFROZEN ioctl
2011-07-21 2:32 [PATCH 0/2] fsfreeze: check ioctls Fernando Luis Vazquez Cao
2011-07-21 2:36 ` [PATCH 1/2] fsfreeze: add FIISFROZEN ioctl Fernando Luis Vazquez Cao
@ 2011-07-21 2:41 ` Fernando Luis Vazquez Cao
2011-07-27 7:30 ` [RFC][PATCH 0/4] fsfreeze: new API Fernando Luis Vazquez Cao
2 siblings, 0 replies; 8+ messages in thread
From: Fernando Luis Vazquez Cao @ 2011-07-21 2:41 UTC (permalink / raw)
To: Al Viro; +Cc: Christoph Hellwig, Eric Sandeen, Josef Bacik, linux-fsdevel
The FIISFROZEN ioctl can be use by HA and monitoring software to check
the freeze state of the filesystem sitting on top of a block device.
This will not work for filesystems that can handle multiple devices,
i.e. btrfs.
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
diff -urNp linux-3.0-rc7-orig/block/compat_ioctl.c linux-3.0-rc7/block/compat_ioctl.c
--- linux-3.0-rc7-orig/block/compat_ioctl.c 2011-05-19 13:06:34.000000000 +0900
+++ linux-3.0-rc7/block/compat_ioctl.c 2011-07-20 15:20:31.439999983 +0900
@@ -757,6 +757,13 @@ long compat_blkdev_ioctl(struct file *fi
case BLKTRACETEARDOWN: /* compatible */
ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
return ret;
+ case BLKISFROZEN:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ ret = isfrozen_bdev(bdev);
+ if (ret >= 0)
+ return compat_put_int(arg, ret);
+ return ret;
default:
if (disk->fops->compat_ioctl)
ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
diff -urNp linux-3.0-rc7-orig/block/ioctl.c linux-3.0-rc7/block/ioctl.c
--- linux-3.0-rc7-orig/block/ioctl.c 2011-05-19 13:06:34.000000000 +0900
+++ linux-3.0-rc7/block/ioctl.c 2011-07-20 15:20:22.140020393 +0900
@@ -322,6 +322,13 @@ int blkdev_ioctl(struct block_device *bd
case BLKTRACETEARDOWN:
ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg);
break;
+ case BLKISFROZEN:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ ret = isfrozen_bdev(bdev);
+ if (ret >= 0)
+ return put_int(arg, ret);
+ return ret;
default:
ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
}
diff -urNp linux-3.0-rc7-orig/fs/block_dev.c linux-3.0-rc7/fs/block_dev.c
--- linux-3.0-rc7-orig/fs/block_dev.c 2011-07-12 09:55:49.656000005 +0900
+++ linux-3.0-rc7/fs/block_dev.c 2011-07-21 09:40:36.900005798 +0900
@@ -310,6 +310,25 @@ out:
}
EXPORT_SYMBOL(thaw_bdev);
+int isfrozen_bdev(struct block_device *bdev)
+{
+ int ret;
+ struct super_block *sb;
+
+ mutex_lock(&bdev->bd_fsfreeze_mutex);
+
+ ret = -EINVAL;
+ sb = get_active_super(bdev);
+ if (!sb)
+ goto out;
+ ret = isfrozen_super(sb);
+ deactivate_super(sb);
+out:
+ mutex_unlock(&bdev->bd_fsfreeze_mutex);
+
+ return ret;
+}
+
static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page, blkdev_get_block, wbc);
diff -urNp linux-3.0-rc7-orig/include/linux/fs.h linux-3.0-rc7/include/linux/fs.h
--- linux-3.0-rc7-orig/include/linux/fs.h 2011-07-12 09:55:51.192000002 +0900
+++ linux-3.0-rc7/include/linux/fs.h 2011-07-20 12:27:59.443932676 +0900
@@ -317,6 +317,7 @@ struct inodes_stat_t {
#define BLKPBSZGET _IO(0x12,123)
#define BLKDISCARDZEROES _IO(0x12,124)
#define BLKSECDISCARD _IO(0x12,125)
+#define BLKISFROZEN _IOR(0x12,126, int) /* get file system freeze state */
#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
#define FIBMAP _IO(0x00,1) /* bmap access */
@@ -2036,6 +2039,7 @@ extern int sync_blockdev(struct block_de
extern struct super_block *freeze_bdev(struct block_device *);
extern void emergency_thaw_all(void);
extern int thaw_bdev(struct block_device *bdev, struct super_block *sb);
+extern int isfrozen_bdev(struct block_device *bdev);
extern int fsync_bdev(struct block_device *);
#else
static inline void bd_forget(struct inode *inode) {}
@@ -2051,6 +2055,11 @@ static inline int thaw_bdev(struct block
{
return 0;
}
+
+static int isfrozen_bdev(struct block_device *bdev)
+{
+ return 0;
+}
#endif
extern int sync_filesystem(struct super_block *);
extern const struct file_operations def_blk_fops;
^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC][PATCH 0/4] fsfreeze: new API
2011-07-21 2:32 [PATCH 0/2] fsfreeze: check ioctls Fernando Luis Vazquez Cao
2011-07-21 2:36 ` [PATCH 1/2] fsfreeze: add FIISFROZEN ioctl Fernando Luis Vazquez Cao
2011-07-21 2:41 ` [PATCH 2/2] fsfreeze: add BLKISFROZEN ioctl Fernando Luis Vazquez Cao
@ 2011-07-27 7:30 ` Fernando Luis Vazquez Cao
2011-07-27 7:32 ` [PATCH 1/4] fsfreeze: add vfs ioctl to check freeze state Fernando Luis Vazquez Cao
` (3 more replies)
2 siblings, 4 replies; 8+ messages in thread
From: Fernando Luis Vazquez Cao @ 2011-07-27 7:30 UTC (permalink / raw)
To: Al Viro
Cc: Christoph Hellwig, Eric Sandeen, Josef Bacik, linux-fsdevel,
Ric Wheeler, James Bottomley, Theodore Ts'o
There are a few with issues with how freeze works in current kernels:
- Unmounting: It is possible to umount a frozen filesystem; the freeze
code holds an active reference to the superblock so it does not go away.
Since it is not possible to thaw by block device, thawing an unmounted
filesystem involves mounting it again and using the current vfs freeze
API.
- There is no check API: There is no easy way to know whether a
filesystem is frozen or not.
- Foolproofness: Quite often the freeze/thaw process is handled from a
daemon. In such cases we have to make really sure that the process does
not go away or is killed while the filesystem is frozen; there is no
check API so it is not always easy to figure out what is going on. With
the advent of virtualization things got even funnier; in some cases not
even the root user is aware of the existence of such daemon (usually a
guest agent that freezes the guests filesystems before taking a storage
snapshot).
I cooked some patches that add the long missing check ioctls and a new
freeze API, which should (modulo bugs) the current situation:
- Check ioctls
[1/4] fsfreeze: add vfs ioctl to check freeze state
Adds a vfs ioctl to check the freeze state.
[2/4] fsfreeze: add block device ioctl to check freeze state
Adds a block device ioctl to check the freeze state. This is
needed because it possible to umount frozen filesystems.
- New freeze API
[3/4] fsfreeze: add ioctl to create a fd for freeze control
Adds a new ioctl that freezes the indicated filesystem and
returns a file descriptor; as long as that file descriptor is
held open, the filesystem remains open.
[4/4] fsfreeze: add freeze fd ioctls
Adds new ioctls that operate on the file descriptor described in
the previous patch; these can be used to freeze/thaw the
filesystem and check the freeze state of the filesystem, thus
avoiding the need to get new file descriptors constantly.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/4] fsfreeze: add vfs ioctl to check freeze state
2011-07-27 7:30 ` [RFC][PATCH 0/4] fsfreeze: new API Fernando Luis Vazquez Cao
@ 2011-07-27 7:32 ` Fernando Luis Vazquez Cao
2011-07-27 7:34 ` [PATCH 2/4] fsfreeze: add block device " Fernando Luis Vazquez Cao
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Fernando Luis Vazquez Cao @ 2011-07-27 7:32 UTC (permalink / raw)
To: Al Viro
Cc: Christoph Hellwig, Eric Sandeen, Josef Bacik, linux-fsdevel,
Ric Wheeler, James Bottomley, Theodore Ts'o
The FIISFROZEN ioctl can be use by HA and monitoring software to check
the freeze state of a mounted filesystem.
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
diff -urNp linux-3.0-rc7-orig/fs/compat_ioctl.c linux-3.0-rc7/fs/compat_ioctl.c
--- linux-3.0-rc7-orig/fs/compat_ioctl.c 2011-05-19 13:06:34.000000000 +0900
+++ linux-3.0-rc7/fs/compat_ioctl.c 2011-07-20 15:33:40.615998033 +0900
@@ -883,6 +883,7 @@ COMPATIBLE_IOCTL(FIGETBSZ)
/* 'X' - originally XFS but some now in the VFS */
COMPATIBLE_IOCTL(FIFREEZE)
COMPATIBLE_IOCTL(FITHAW)
+COMPATIBLE_IOCTL(FIISFROZEN)
COMPATIBLE_IOCTL(KDGETKEYCODE)
COMPATIBLE_IOCTL(KDSETKEYCODE)
COMPATIBLE_IOCTL(KDGKBTYPE)
diff -urNp linux-3.0-rc7-orig/fs/ioctl.c linux-3.0-rc7/fs/ioctl.c
--- linux-3.0-rc7-orig/fs/ioctl.c 2011-05-19 13:06:34.000000000 +0900
+++ linux-3.0-rc7/fs/ioctl.c 2011-07-20 12:23:06.124003192 +0900
@@ -536,6 +536,16 @@ static int ioctl_fsthaw(struct file *fil
return thaw_super(sb);
}
+static int ioctl_fs_isfrozen(struct file *filp)
+{
+ struct super_block *sb = filp->f_path.dentry->d_inode->i_sb;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ return isfrozen_super(sb);
+}
+
/*
* When you add any new common ioctls to the switches above and below
* please update compat_sys_ioctl() too.
@@ -585,6 +595,12 @@ int do_vfs_ioctl(struct file *filp, unsi
error = ioctl_fsthaw(filp);
break;
+ case FIISFROZEN:
+ error = ioctl_fs_isfrozen(filp);
+ if (error >= 0)
+ return put_user(error, (int __user *)arg);
+ break;
+
case FS_IOC_FIEMAP:
return ioctl_fiemap(filp, arg);
diff -urNp linux-3.0-rc7-orig/fs/super.c linux-3.0-rc7/fs/super.c
--- linux-3.0-rc7-orig/fs/super.c 2011-07-12 09:55:50.804000002 +0900
+++ linux-3.0-rc7/fs/super.c 2011-07-19 17:45:56.816155171 +0900
@@ -1057,3 +1057,8 @@ out:
return 0;
}
EXPORT_SYMBOL(thaw_super);
+
+int isfrozen_super(struct super_block *sb)
+{
+ return sb->s_frozen > SB_UNFROZEN ? 1:0;
+}
diff -urNp linux-3.0-rc7-orig/include/linux/fs.h linux-3.0-rc7/include/linux/fs.h
--- linux-3.0-rc7-orig/include/linux/fs.h 2011-07-12 09:55:51.192000002 +0900
+++ linux-3.0-rc7/include/linux/fs.h 2011-07-20 12:27:59.443932676 +0900
@@ -324,6 +325,7 @@ struct inodes_stat_t {
#define FIFREEZE _IOWR('X', 119, int) /* Freeze */
#define FITHAW _IOWR('X', 120, int) /* Thaw */
#define FITRIM _IOWR('X', 121, struct fstrim_range) /* Trim */
+#define FIISFROZEN _IOR('X', 122, int) /* get sb freeze state */
#define FS_IOC_GETFLAGS _IOR('f', 1, long)
#define FS_IOC_SETFLAGS _IOW('f', 2, long)
@@ -1882,6 +1884,7 @@ extern int fd_statfs(int, struct kstatfs
extern int statfs_by_dentry(struct dentry *, struct kstatfs *);
extern int freeze_super(struct super_block *super);
extern int thaw_super(struct super_block *super);
+extern int isfrozen_super(struct super_block *sb);
extern int current_umask(void);
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/4] fsfreeze: add block device ioctl to check freeze state
2011-07-27 7:30 ` [RFC][PATCH 0/4] fsfreeze: new API Fernando Luis Vazquez Cao
2011-07-27 7:32 ` [PATCH 1/4] fsfreeze: add vfs ioctl to check freeze state Fernando Luis Vazquez Cao
@ 2011-07-27 7:34 ` Fernando Luis Vazquez Cao
2011-07-27 7:35 ` [PATCH 3/4] fsfreeze: add ioctl to create a fd for freeze control Fernando Luis Vazquez Cao
2011-07-27 7:36 ` [PATCH 4/4] fsfreeze: add freeze fd ioctls Fernando Luis Vazquez Cao
3 siblings, 0 replies; 8+ messages in thread
From: Fernando Luis Vazquez Cao @ 2011-07-27 7:34 UTC (permalink / raw)
To: Al Viro
Cc: Christoph Hellwig, Eric Sandeen, Josef Bacik, linux-fsdevel,
Ric Wheeler, James Bottomley, Theodore Ts'o
The BLKISFROZEN ioctl can be use by HA and monitoring software to check
the freeze state of the filesystem sitting on top of a block device.
This will not work for filesystems that can handle multiple devices,
i.e. btrfs.
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
diff -urNp linux-3.0-rc7-orig/block/compat_ioctl.c linux-3.0-rc7/block/compat_ioctl.c
--- linux-3.0-rc7-orig/block/compat_ioctl.c 2011-05-19 13:06:34.000000000 +0900
+++ linux-3.0-rc7/block/compat_ioctl.c 2011-07-20 15:20:31.439999983 +0900
@@ -757,6 +757,13 @@ long compat_blkdev_ioctl(struct file *fi
case BLKTRACETEARDOWN: /* compatible */
ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
return ret;
+ case BLKISFROZEN:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ ret = isfrozen_bdev(bdev);
+ if (ret >= 0)
+ return compat_put_int(arg, ret);
+ return ret;
default:
if (disk->fops->compat_ioctl)
ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
diff -urNp linux-3.0-rc7-orig/block/ioctl.c linux-3.0-rc7/block/ioctl.c
--- linux-3.0-rc7-orig/block/ioctl.c 2011-05-19 13:06:34.000000000 +0900
+++ linux-3.0-rc7/block/ioctl.c 2011-07-20 15:20:22.140020393 +0900
@@ -322,6 +322,13 @@ int blkdev_ioctl(struct block_device *bd
case BLKTRACETEARDOWN:
ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg);
break;
+ case BLKISFROZEN:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ ret = isfrozen_bdev(bdev);
+ if (ret >= 0)
+ return put_int(arg, ret);
+ return ret;
default:
ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
}
diff -urNp linux-3.0-rc7-orig/fs/block_dev.c linux-3.0-rc7/fs/block_dev.c
--- linux-3.0-rc7-orig/fs/block_dev.c 2011-07-12 09:55:49.656000005 +0900
+++ linux-3.0-rc7/fs/block_dev.c 2011-07-21 09:40:36.900005798 +0900
@@ -310,6 +310,25 @@ out:
}
EXPORT_SYMBOL(thaw_bdev);
+int isfrozen_bdev(struct block_device *bdev)
+{
+ int ret;
+ struct super_block *sb;
+
+ mutex_lock(&bdev->bd_fsfreeze_mutex);
+
+ ret = -EINVAL;
+ sb = get_active_super(bdev);
+ if (!sb)
+ goto out;
+ ret = isfrozen_super(sb);
+ deactivate_super(sb);
+out:
+ mutex_unlock(&bdev->bd_fsfreeze_mutex);
+
+ return ret;
+}
+
static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page, blkdev_get_block, wbc);
diff -urNp linux-3.0-rc7-orig/include/linux/fs.h linux-3.0-rc7/include/linux/fs.h
--- linux-3.0-rc7-orig/include/linux/fs.h 2011-07-12 09:55:51.192000002 +0900
+++ linux-3.0-rc7/include/linux/fs.h 2011-07-20 12:27:59.443932676 +0900
@@ -317,6 +317,7 @@ struct inodes_stat_t {
#define BLKPBSZGET _IO(0x12,123)
#define BLKDISCARDZEROES _IO(0x12,124)
#define BLKSECDISCARD _IO(0x12,125)
+#define BLKISFROZEN _IOR(0x12,126, int) /* get file system freeze state */
#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
#define FIBMAP _IO(0x00,1) /* bmap access */
@@ -2036,6 +2039,7 @@ extern int sync_blockdev(struct block_de
extern struct super_block *freeze_bdev(struct block_device *);
extern void emergency_thaw_all(void);
extern int thaw_bdev(struct block_device *bdev, struct super_block *sb);
+extern int isfrozen_bdev(struct block_device *bdev);
extern int fsync_bdev(struct block_device *);
#else
static inline void bd_forget(struct inode *inode) {}
@@ -2051,6 +2055,11 @@ static inline int thaw_bdev(struct block
{
return 0;
}
+
+static int isfrozen_bdev(struct block_device *bdev)
+{
+ return 0;
+}
#endif
extern int sync_filesystem(struct super_block *);
extern const struct file_operations def_blk_fops;
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/4] fsfreeze: add ioctl to create a fd for freeze control
2011-07-27 7:30 ` [RFC][PATCH 0/4] fsfreeze: new API Fernando Luis Vazquez Cao
2011-07-27 7:32 ` [PATCH 1/4] fsfreeze: add vfs ioctl to check freeze state Fernando Luis Vazquez Cao
2011-07-27 7:34 ` [PATCH 2/4] fsfreeze: add block device " Fernando Luis Vazquez Cao
@ 2011-07-27 7:35 ` Fernando Luis Vazquez Cao
2011-07-27 7:36 ` [PATCH 4/4] fsfreeze: add freeze fd ioctls Fernando Luis Vazquez Cao
3 siblings, 0 replies; 8+ messages in thread
From: Fernando Luis Vazquez Cao @ 2011-07-27 7:35 UTC (permalink / raw)
To: Al Viro
Cc: Christoph Hellwig, Eric Sandeen, Josef Bacik, linux-fsdevel,
Ric Wheeler, James Bottomley, Theodore Ts'o
Adds a new ioctl, FIGETFREEZEFD, which freezes the indicated filesystem and
returns a file descriptor; as long as that file descriptor is held open, the
filesystem remains open.
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
diff -urNp linux-3.0-orig/fs/compat_ioctl.c linux-3.0/fs/compat_ioctl.c
--- linux-3.0-orig/fs/compat_ioctl.c 2011-07-27 11:32:10.188008559 +0900
+++ linux-3.0/fs/compat_ioctl.c 2011-07-27 11:34:42.844014535 +0900
@@ -882,6 +882,7 @@ COMPATIBLE_IOCTL(FIBMAP)
COMPATIBLE_IOCTL(FIGETBSZ)
/* 'X' - originally XFS but some now in the VFS */
COMPATIBLE_IOCTL(FIFREEZE)
+COMPATIBLE_IOCTL(FIGETFREEZEFD)
COMPATIBLE_IOCTL(FITHAW)
COMPATIBLE_IOCTL(FIISFROZEN)
COMPATIBLE_IOCTL(KDGETKEYCODE)
diff -urNp linux-3.0-orig/fs/ioctl.c linux-3.0/fs/ioctl.c
--- linux-3.0-orig/fs/ioctl.c 2011-07-27 11:32:10.188008559 +0900
+++ linux-3.0/fs/ioctl.c 2011-07-27 12:24:54.116004298 +0900
@@ -14,6 +14,7 @@
#include <linux/uaccess.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h>
+#include <linux/anon_inodes.h>
#include <linux/falloc.h>
#include <asm/ioctls.h>
@@ -525,6 +526,80 @@ static int ioctl_fsfreeze(struct file *f
return freeze_super(sb);
}
+struct freeze_fd_data {
+ struct super_block *sb;
+};
+
+static int freeze_fd_release(struct inode *inode, struct file *filp)
+{
+ struct freeze_fd_data *fd_data = filp->private_data;
+ struct super_block *sb = fd_data->sb;
+
+ thaw_super(sb);
+ deactivate_super(sb);
+ kfree(fd_data);
+
+ return 0;
+}
+
+static struct file_operations freeze_fd_fops = {
+ .release = freeze_fd_release,
+ .llseek = noop_llseek,
+};
+
+static int ioctl_get_freeze_fd(struct file *filp, int __user *argp)
+{
+ struct super_block *sb = filp->f_path.dentry->d_inode->i_sb;
+ int fd, ret;
+ struct file *file;
+ struct freeze_fd_data *fd_data;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ /* If filesystem doesn't support freeze feature, return. */
+ if (sb->s_op->freeze_fs == NULL)
+ return -EOPNOTSUPP;
+
+ fd_data = kmalloc(sizeof(struct freeze_fd_data), GFP_KERNEL);
+ if (!fd_data)
+ return -ENOMEM;
+
+ /* Get a file descriptor. */
+ ret = get_unused_fd_flags(O_RDWR);
+ if (ret < 0)
+ goto err_free_fd_data;
+ fd = ret;
+ fd_data->sb = sb;
+ file = anon_inode_getfile("freeze-fd",
+ &freeze_fd_fops, fd_data, O_RDWR);
+ if (IS_ERR(file)) {
+ ret = PTR_ERR(file);
+ goto err_put_fd;
+ }
+
+ /* Increment the active counter to keep the superblock around
+ * until the freeze fd is closed.
+ */
+ atomic_inc(&sb->s_active);
+
+ ret = freeze_super(sb);
+ if (ret < 0)
+ goto err_deact_super;
+
+ fd_install(fd, file);
+
+ return fd;
+
+err_deact_super:
+ deactivate_super(sb);
+err_put_fd:
+ put_unused_fd(fd);
+err_free_fd_data:
+ kfree(fd_data);
+ return ret;
+}
+
static int ioctl_fsthaw(struct file *filp)
{
struct super_block *sb = filp->f_path.dentry->d_inode->i_sb;
@@ -591,6 +666,10 @@ int do_vfs_ioctl(struct file *filp, unsi
error = ioctl_fsfreeze(filp);
break;
+ case FIGETFREEZEFD:
+ error = ioctl_get_freeze_fd(filp, argp);
+ break;
+
case FITHAW:
error = ioctl_fsthaw(filp);
break;
diff -urNp linux-3.0-orig/include/linux/fs.h linux-3.0/include/linux/fs.h
--- linux-3.0-orig/include/linux/fs.h 2011-07-27 11:32:12.700001748 +0900
+++ linux-3.0/include/linux/fs.h 2011-07-27 11:57:14.832000721 +0900
@@ -326,6 +326,7 @@ struct inodes_stat_t {
#define FITHAW _IOWR('X', 120, int) /* Thaw */
#define FITRIM _IOWR('X', 121, struct fstrim_range) /* Trim */
#define FIISFROZEN _IOR('X', 122, int) /* get sb freeze state */
+#define FIGETFREEZEFD _IOWR('X', 123, int)
#define FS_IOC_GETFLAGS _IOR('f', 1, long)
#define FS_IOC_SETFLAGS _IOW('f', 2, long)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/4] fsfreeze: add freeze fd ioctls
2011-07-27 7:30 ` [RFC][PATCH 0/4] fsfreeze: new API Fernando Luis Vazquez Cao
` (2 preceding siblings ...)
2011-07-27 7:35 ` [PATCH 3/4] fsfreeze: add ioctl to create a fd for freeze control Fernando Luis Vazquez Cao
@ 2011-07-27 7:36 ` Fernando Luis Vazquez Cao
3 siblings, 0 replies; 8+ messages in thread
From: Fernando Luis Vazquez Cao @ 2011-07-27 7:36 UTC (permalink / raw)
To: Al Viro
Cc: Christoph Hellwig, Eric Sandeen, Josef Bacik, linux-fsdevel,
Ric Wheeler, James Bottomley, Theodore Ts'o
Adds new ioctls (FS_FREEZE_FD, FS_THAW_FD, FS_ISFROZEN_FD) that operate on the
freeze file descriptor; these can be used to freeze/thaw the filesystem and
check the freeze state of the filesystem, thus avoiding the need to get new
file descriptors constantly.
Additionaly, the argument of the ioctl FIGETFREEZEFD can now be used to
indicate whether we want the filesystem frozen at fd creation time (a non-zero
value means "freeze", 0 means "leave as is").
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
diff -urNp linux-3.0-orig/Documentation/ioctl/ioctl-number.txt linux-3.0/Documentation/ioctl/ioctl-number.txt
--- linux-3.0-orig/Documentation/ioctl/ioctl-number.txt 2011-07-22 11:17:23.000000000 +0900
+++ linux-3.0/Documentation/ioctl/ioctl-number.txt 2011-07-27 15:13:45.583998849 +0900
@@ -301,6 +301,8 @@ Code Seq#(hex) Include File Comments
<mailto:rusty@rustcorp.com.au>
0xAE all linux/kvm.h Kernel-based Virtual Machine
<mailto:kvm@vger.kernel.org>
+0xAF 00-03 Filesystem freeze see fs/ioctl.c
+ <mailto:linux-fsdevel@vger.kernel.org>
0xB0 all RATIO devices in development:
<mailto:vgo@ratio.de>
0xB1 00-1F PPPoX <mailto:mostrows@styx.uwaterloo.ca>
diff -urNp linux-3.0-orig/fs/ioctl.c linux-3.0/fs/ioctl.c
--- linux-3.0-orig/fs/ioctl.c 2011-07-27 15:12:22.876000730 +0900
+++ linux-3.0/fs/ioctl.c 2011-07-27 15:46:57.923998173 +0900
@@ -528,14 +528,48 @@ static int ioctl_fsfreeze(struct file *f
struct freeze_fd_data {
struct super_block *sb;
+ int thaw_pending;
};
+static long freeze_fd_ioctl(struct file *filp,
+ unsigned int ioctl, unsigned long arg)
+{
+ struct freeze_fd_data *fd_data = filp->private_data;
+ struct super_block *sb = fd_data->sb;
+ int error = 0;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ switch (ioctl) {
+ case FS_FREEZE_FD:
+ error = freeze_super(sb);
+ if (!error)
+ fd_data->thaw_pending++;
+ break;
+ case FS_THAW_FD:
+ error = thaw_super(sb);
+ if (!error)
+ fd_data->thaw_pending--;
+ break;
+ case FS_ISFROZEN_FD:
+ error = isfrozen_super(sb);
+ if (error >= 0)
+ return put_user(error, (int __user *)arg);
+ break;
+ default:
+ error = -EINVAL;
+ }
+ return error;
+}
+
static int freeze_fd_release(struct inode *inode, struct file *filp)
{
struct freeze_fd_data *fd_data = filp->private_data;
struct super_block *sb = fd_data->sb;
- thaw_super(sb);
+ if (fd_data->thaw_pending)
+ thaw_super(sb);
deactivate_super(sb);
kfree(fd_data);
@@ -544,19 +578,25 @@ static int freeze_fd_release(struct inod
static struct file_operations freeze_fd_fops = {
.release = freeze_fd_release,
+ .unlocked_ioctl = freeze_fd_ioctl,
+ .compat_ioctl = freeze_fd_ioctl,
.llseek = noop_llseek,
};
static int ioctl_get_freeze_fd(struct file *filp, int __user *argp)
{
struct super_block *sb = filp->f_path.dentry->d_inode->i_sb;
- int fd, ret;
+ int fd, ret, should_freeze;
struct file *file;
struct freeze_fd_data *fd_data;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+ ret = get_user(should_freeze, argp);
+ if (ret)
+ return ret;
+
/* If filesystem doesn't support freeze feature, return. */
if (sb->s_op->freeze_fs == NULL)
return -EOPNOTSUPP;
@@ -571,6 +611,7 @@ static int ioctl_get_freeze_fd(struct fi
goto err_free_fd_data;
fd = ret;
fd_data->sb = sb;
+ fd_data->thaw_pending = 0;
file = anon_inode_getfile("freeze-fd",
&freeze_fd_fops, fd_data, O_RDWR);
if (IS_ERR(file)) {
@@ -580,12 +621,19 @@ static int ioctl_get_freeze_fd(struct fi
/* Increment the active counter to keep the superblock around
* until the freeze fd is closed.
+ *
+ * When should_freeze is set freeze_super() is called which takes an
+ * active reference to the superblock. However that reference could be
+ * released through ioctl_fsthaw, so we still need to take our own here.
*/
atomic_inc(&sb->s_active);
- ret = freeze_super(sb);
- if (ret < 0)
- goto err_deact_super;
+ if (should_freeze) {
+ ret = freeze_super(sb);
+ if (ret < 0)
+ goto err_deact_super;
+ fd_data->thaw_pending++;
+ }
fd_install(fd, file);
diff -urNp linux-3.0-orig/include/linux/fs.h linux-3.0/include/linux/fs.h
--- linux-3.0-orig/include/linux/fs.h 2011-07-27 15:12:22.876000730 +0900
+++ linux-3.0/include/linux/fs.h 2011-07-27 15:13:45.587999047 +0900
@@ -328,6 +328,10 @@ struct inodes_stat_t {
#define FIISFROZEN _IOR('X', 122, int) /* get sb freeze state */
#define FIGETFREEZEFD _IOWR('X', 123, int)
+#define FS_FREEZE_FD _IOWR(0xAF, 1, int)
+#define FS_THAW_FD _IOWR(0xAF, 2, int)
+#define FS_ISFROZEN_FD _IOR(0xAF, 3, int)
+
#define FS_IOC_GETFLAGS _IOR('f', 1, long)
#define FS_IOC_SETFLAGS _IOW('f', 2, long)
#define FS_IOC_GETVERSION _IOR('v', 1, long)
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2011-07-27 7:36 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-21 2:32 [PATCH 0/2] fsfreeze: check ioctls Fernando Luis Vazquez Cao
2011-07-21 2:36 ` [PATCH 1/2] fsfreeze: add FIISFROZEN ioctl Fernando Luis Vazquez Cao
2011-07-21 2:41 ` [PATCH 2/2] fsfreeze: add BLKISFROZEN ioctl Fernando Luis Vazquez Cao
2011-07-27 7:30 ` [RFC][PATCH 0/4] fsfreeze: new API Fernando Luis Vazquez Cao
2011-07-27 7:32 ` [PATCH 1/4] fsfreeze: add vfs ioctl to check freeze state Fernando Luis Vazquez Cao
2011-07-27 7:34 ` [PATCH 2/4] fsfreeze: add block device " Fernando Luis Vazquez Cao
2011-07-27 7:35 ` [PATCH 3/4] fsfreeze: add ioctl to create a fd for freeze control Fernando Luis Vazquez Cao
2011-07-27 7:36 ` [PATCH 4/4] fsfreeze: add freeze fd ioctls Fernando Luis Vazquez Cao
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.