public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
To: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>, Eric Sandeen <sandeen@redhat.com>,
	Josef Bacik <josef@redhat.com>,
	linux-fsdevel@vger.kernel.org, Ric Wheeler <rwheeler@redhat.com>,
	James Bottomley <jbottomley@parallels.com>,
	Theodore Ts'o <tytso@mit.edu>
Subject: [PATCH 4/4] fsfreeze: add freeze fd ioctls
Date: Wed, 27 Jul 2011 16:36:41 +0900	[thread overview]
Message-ID: <1311752201.2549.90.camel@nausicaa> (raw)
In-Reply-To: <1311751806.2549.83.camel@nausicaa>

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)



      parent reply	other threads:[~2011-07-27  7:36 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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   ` Fernando Luis Vazquez Cao [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1311752201.2549.90.camel@nausicaa \
    --to=fernando@oss.ntt.co.jp \
    --cc=hch@lst.de \
    --cc=jbottomley@parallels.com \
    --cc=josef@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=rwheeler@redhat.com \
    --cc=sandeen@redhat.com \
    --cc=tytso@mit.edu \
    --cc=viro@ZenIV.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox