All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.