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)
prev 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