{"id":849,"url":"http://patchwork.ozlabs.org/api/1.0/patches/849/?format=json","project":{"id":8,"url":"http://patchwork.ozlabs.org/api/1.0/projects/8/?format=json","name":"Linux ext4 filesystem development","link_name":"linux-ext4","list_id":"linux-ext4.vger.kernel.org","list_email":"linux-ext4@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<20080922195804t-sato@mail.jp.nec.com>","date":"2008-09-22T10:58:03","name":"[8/10] Implement generic freeze feature","commit_ref":null,"pull_url":null,"state":"superseded","archived":true,"hash":"89999a0c9d8cac6aa86a11360d3e77a1e51a9a5f","submitter":{"id":391,"url":"http://patchwork.ozlabs.org/api/1.0/people/391/?format=json","name":"Takashi Sato","email":"t-sato@yk.jp.nec.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-ext4/patch/20080922195804t-sato@mail.jp.nec.com/mbox/","series":[],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/849/checks/","tags":{},"headers":{"Return-Path":"<linux-ext4-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Received":["from vger.kernel.org (vger.kernel.org [209.132.176.167])\n\tby ozlabs.org (Postfix) with ESMTP id 9E13ADDEEE\n\tfor <patchwork-incoming@ozlabs.org>;\n\tMon, 22 Sep 2008 20:58:25 +1000 (EST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1753693AbYIVK6X (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 22 Sep 2008 06:58:23 -0400","(majordomo@vger.kernel.org) by vger.kernel.org id S1753703AbYIVK6W\n\t(ORCPT <rfc822;linux-ext4-outgoing>);\n\tMon, 22 Sep 2008 06:58:22 -0400","from TYO202.gate.nec.co.jp ([202.32.8.206]:50143 \"EHLO\n\ttyo202.gate.nec.co.jp\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1753582AbYIVK6Q (ORCPT\n\t<rfc822; linux-ext4@vger.kernel.org>); Mon, 22 Sep 2008 06:58:16 -0400","from mailgate3.nec.co.jp ([10.7.69.195])\n\tby tyo202.gate.nec.co.jp (8.13.8/8.13.4) with ESMTP id m8MAw5c5008131;\n\tMon, 22 Sep 2008 19:58:05 +0900 (JST)","(from root@localhost) by mailgate3.nec.co.jp\n\t(8.11.7/3.7W-MAILGATE-NEC)\n\tid m8MAw5X03265; Mon, 22 Sep 2008 19:58:05 +0900 (JST)","from matabe.jp.nec.com (matabe.jp.nec.com [10.26.220.20])\n\tby mailsv3.nec.co.jp (8.13.8/8.13.4) with ESMTP id m8MAw42Q013659;\n\tMon, 22 Sep 2008 19:58:04 +0900 (JST)","from TNESB07336 ([10.64.168.65] [10.64.168.65]) by mail.jp.nec.com\n\twith ESMTP; Mon, 22 Sep 2008 19:58:04 +0900"],"To":"Andrew Morton <akpm@linux-foundation.org>,\n\tChristoph Hellwig <hch@infradead.org>,\n\t\"linux-fsdevel@vger.kernel.org\" <linux-fsdevel@vger.kernel.org>,\n\t\"dm-devel@redhat.com\" <dm-devel@redhat.com>,\n\t\"viro@ZenIV.linux.org.uk\" <viro@ZenIV.linux.org.uk>,\n\t\"linux-ext4@vger.kernel.org\" <linux-ext4@vger.kernel.org>,\n\t\"xfs@oss.sgi.com\" <xfs@oss.sgi.com>, \"axboe@kernel.dk\" <axboe@kernel.dk>,\n\t\"mtk.manpages@googlemail.com\" <mtk.manpages@googlemail.com>","Cc":"\"linux-kernel@vger.kernel.org\" <linux-kernel@vger.kernel.org>","Subject":"[PATCH 8/10] Implement generic freeze feature","Message-Id":"<20080922195804t-sato@mail.jp.nec.com>","Mime-Version":"1.0","X-Mailer":"WeMail32[2.51] ID:1K0086","From":"Takashi Sato <t-sato@yk.jp.nec.com>","Date":"Mon, 22 Sep 2008 19:58:03 +0900","Content-Type":"text/plain; charset=us-ascii","Content-Transfer-Encoding":"7bit","Sender":"linux-ext4-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<linux-ext4.vger.kernel.org>","X-Mailing-List":"linux-ext4@vger.kernel.org"},"content":"The ioctls for the generic freeze feature are below.\no Freeze the filesystem\n  int ioctl(int fd, int FIFREEZE, arg)\n    fd: The file descriptor of the mountpoint\n    FIFREEZE: request code for the freeze\n    arg: Ignored\n    Return value: 0 if the operation succeeds. Otherwise, -1\n\no Unfreeze the filesystem\n  int ioctl(int fd, int FITHAW, arg)\n    fd: The file descriptor of the mountpoint\n    FITHAW: request code for unfreeze\n    arg: Ignored\n    Return value: 0 if the operation succeeds. Otherwise, -1\n\nSigned-off-by: Takashi Sato <t-sato@yk.jp.nec.com>\nSigned-off-by: Masayuki Hamaguchi <m-hamaguchi@ys.jp.nec.com>\n---\n fs/block_dev.c              |    2 +\n fs/buffer.c                 |   69 ++++++++++++++++++++++++++++++++++++++------\n fs/ioctl.c                  |   47 +++++++++++++++++++++++++++++\n include/linux/buffer_head.h |    2 -\n include/linux/fs.h          |    7 ++++\n\n--\nTo unsubscribe from this list: send the line \"unsubscribe linux-ext4\" in\nthe body of a message to majordomo@vger.kernel.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html","diff":"diff -uprN -X linux-2.6.27-rc7-lockfs-reiserfs/Documentation/dontdiff linux-2.6.27-rc7-lockfs-reiserfs/fs/block_dev.c li\nnux-2.6.27-rc7-freeze/fs/block_dev.c\n--- linux-2.6.27-rc7-lockfs-reiserfs/fs/block_dev.c\t2008-09-22 07:29:55.000000000 +0900\n+++ linux-2.6.27-rc7-freeze/fs/block_dev.c\t2008-09-22 13:11:03.000000000 +0900\n@@ -285,6 +285,8 @@ static void init_once(void *foo)\n \tINIT_LIST_HEAD(&bdev->bd_holder_list);\n #endif\n \tinode_init_once(&ei->vfs_inode);\n+\t/* Initialize mutex for freeze. */\n+\tmutex_init(&bdev->bd_fsfreeze_mutex);\n }\n \n static inline void __bd_forget(struct inode *inode)\ndiff -uprN -X linux-2.6.27-rc7-lockfs-reiserfs/Documentation/dontdiff linux-2.6.27-rc7-lockfs-reiserfs/fs/buffer.c linux\n-2.6.27-rc7-freeze/fs/buffer.c\n--- linux-2.6.27-rc7-lockfs-reiserfs/fs/buffer.c\t2008-09-22 07:29:55.000000000 +0900\n+++ linux-2.6.27-rc7-freeze/fs/buffer.c\t2008-09-22 16:30:45.000000000 +0900\n@@ -196,10 +196,25 @@ int fsync_bdev(struct block_device *bdev\n  * happen on bdev until thaw_bdev() is called.\n  * If a superblock is found on this device, we take the s_umount semaphore\n  * on it to make sure nobody unmounts until the snapshot creation is done.\n+ * The reference counter (bd_fsfreeze_count) guarantees that only the last\n+ * unfreeze process can unfreeze the frozen filesystem actually when multiple\n+ * freeze requests arrive simultaneously. It counts up in freeze_bdev() and\n+ * count down in thaw_bdev(). When it becomes 0, thaw_bdev() will unfreeze\n+ * actually.\n  */\n struct super_block *freeze_bdev(struct block_device *bdev)\n {\n \tstruct super_block *sb;\n+\tint error = 0;\n+\n+\tmutex_lock(&bdev->bd_fsfreeze_mutex);\n+\tif (bdev->bd_fsfreeze_count > 0) {\n+\t\tbdev->bd_fsfreeze_count++;\n+\t\tsb = get_super(bdev);\n+\t\tmutex_unlock(&bdev->bd_fsfreeze_mutex);\n+\t\treturn sb;\n+\t}\n+\tbdev->bd_fsfreeze_count++;\n \n \tdown(&bdev->bd_mount_sem);\n \tsb = get_super(bdev);\n@@ -214,11 +229,24 @@ struct super_block *freeze_bdev(struct b\n \n \t\tsync_blockdev(sb->s_bdev);\n \n-\t\tif (sb->s_op->write_super_lockfs)\n-\t\t\tsb->s_op->write_super_lockfs(sb);\n+\t\tif (sb->s_op->write_super_lockfs) {\n+\t\t\terror = sb->s_op->write_super_lockfs(sb);\n+\t\t\tif (error) {\n+\t\t\t\tprintk(KERN_ERR\n+\t\t\t\t\t\"VFS:Filesystem freeze failed\\n\");\n+\t\t\t\tsb->s_frozen = SB_UNFROZEN;\n+\t\t\t\tdrop_super(sb);\n+\t\t\t\tup(&bdev->bd_mount_sem);\n+\t\t\t\tbdev->bd_fsfreeze_count--;\n+\t\t\t\tmutex_unlock(&bdev->bd_fsfreeze_mutex);\n+\t\t\t\treturn ERR_PTR(error);\n+\t\t\t}\n+\t\t}\n \t}\n \n \tsync_blockdev(bdev);\n+\tmutex_unlock(&bdev->bd_fsfreeze_mutex);\n+\n \treturn sb;\t/* thaw_bdev releases s->s_umount and bd_mount_sem */\n }\n EXPORT_SYMBOL(freeze_bdev);\n@@ -230,20 +258,43 @@ EXPORT_SYMBOL(freeze_bdev);\n  *\n  * Unlocks the filesystem and marks it writeable again after freeze_bdev().\n  */\n-void thaw_bdev(struct block_device *bdev, struct super_block *sb)\n+int thaw_bdev(struct block_device *bdev, struct super_block *sb)\n {\n+\tint error = 0;\n+\n+\tmutex_lock(&bdev->bd_fsfreeze_mutex);\n+\tif (!bdev->bd_fsfreeze_count) {\n+\t\tmutex_unlock(&bdev->bd_fsfreeze_mutex);\n+\t\treturn 0;\n+\t}\n+\n+\tbdev->bd_fsfreeze_count--;\n+\tif (bdev->bd_fsfreeze_count > 0) {\n+\t\tif (sb)\n+\t\t\tdrop_super(sb);\n+\t\tmutex_unlock(&bdev->bd_fsfreeze_mutex);\n+\t\treturn 0;\n+\t}\n+\n \tif (sb) {\n \t\tBUG_ON(sb->s_bdev != bdev);\n-\n-\t\tif (sb->s_op->unlockfs)\n-\t\t\tsb->s_op->unlockfs(sb);\n-\t\tsb->s_frozen = SB_UNFROZEN;\n-\t\tsmp_wmb();\n-\t\twake_up(&sb->s_wait_unfrozen);\n+\t\tif (!(sb->s_flags & MS_RDONLY)) {\n+\t\t\tif (sb->s_op->unlockfs) {\n+\t\t\t\terror = sb->s_op->unlockfs(sb);\n+\t\t\t\tif (error)\n+\t\t\t\t\tprintk(KERN_ERR\n+\t\t\t\t\t\t\"VFS:Filesystem thaw failed\\n\");\n+\t\t\t}\n+\t\t\tsb->s_frozen = SB_UNFROZEN;\n+\t\t\tsmp_wmb();\n+\t\t\twake_up(&sb->s_wait_unfrozen);\n+\t\t}\n \t\tdrop_super(sb);\n \t}\n \n \tup(&bdev->bd_mount_sem);\n+\tmutex_unlock(&bdev->bd_fsfreeze_mutex);\n+\treturn error;\n }\n EXPORT_SYMBOL(thaw_bdev);\n \ndiff -uprN -X linux-2.6.27-rc7-lockfs-reiserfs/Documentation/dontdiff linux-2.6.27-rc7-lockfs-reiserfs/fs/ioctl.c linux-\n2.6.27-rc7-freeze/fs/ioctl.c\n--- linux-2.6.27-rc7-lockfs-reiserfs/fs/ioctl.c\t2008-09-22 07:29:55.000000000 +0900\n+++ linux-2.6.27-rc7-freeze/fs/ioctl.c\t2008-09-22 13:11:03.000000000 +0900\n@@ -13,6 +13,7 @@\n #include <linux/security.h>\n #include <linux/module.h>\n #include <linux/uaccess.h>\n+#include <linux/buffer_head.h>\n \n #include <asm/ioctls.h>\n \n@@ -140,6 +141,43 @@ static int ioctl_fioasync(unsigned int f\n \treturn error;\n }\n \n+static int ioctl_freeze(struct file *filp)\n+{\n+\tstruct super_block *sb = filp->f_path.dentry->d_inode->i_sb;\n+\n+\tif (!capable(CAP_SYS_ADMIN))\n+\t\treturn -EPERM;\n+\n+\t/* If filesystem doesn't support freeze feature, return. */\n+\tif (sb->s_op->write_super_lockfs == NULL)\n+\t\treturn -EOPNOTSUPP;\n+\n+\t/* If a blockdevice-backed filesystem isn't specified, return. */\n+\tif (sb->s_bdev == NULL)\n+\t\treturn -EINVAL;\n+\n+\t/* Freeze */\n+\tsb = freeze_bdev(sb->s_bdev);\n+\tif (IS_ERR(sb))\n+\t\treturn PTR_ERR(sb);\n+\treturn 0;\n+}\n+\n+static int ioctl_thaw(struct file *filp)\n+{\n+\tstruct super_block *sb = filp->f_path.dentry->d_inode->i_sb;\n+\n+\tif (!capable(CAP_SYS_ADMIN))\n+\t\treturn -EPERM;\n+\n+\t/* If a blockdevice-backed filesystem isn't specified, return EINVAL. */\n+\tif (sb->s_bdev == NULL)\n+\t\treturn -EINVAL;\n+\n+\t/* Thaw */\n+\treturn thaw_bdev(sb->s_bdev, sb);\n+}\n+\n /*\n  * When you add any new common ioctls to the switches above and below\n  * please update compat_sys_ioctl() too.\n@@ -181,6 +219,15 @@ int do_vfs_ioctl(struct file *filp, unsi\n \t\t} else\n \t\t\terror = -ENOTTY;\n \t\tbreak;\n+\n+\tcase FIFREEZE:\n+\t\terror = ioctl_freeze(filp);\n+\t\tbreak;\n+\n+\tcase FITHAW:\n+\t\terror = ioctl_thaw(filp);\n+\t\tbreak;\n+\n \tdefault:\n \t\tif (S_ISREG(filp->f_path.dentry->d_inode->i_mode))\n \t\t\terror = file_ioctl(filp, cmd, arg);\ndiff -uprN -X linux-2.6.27-rc7-lockfs-reiserfs/Documentation/dontdiff linux-2.6.27-rc7-lockfs-reiserfs/include/linux/buf\nfer_head.h linux-2.6.27-rc7-freeze/include/linux/buffer_head.h\n--- linux-2.6.27-rc7-lockfs-reiserfs/include/linux/buffer_head.h\t2008-09-22 07:29:55.000000000 +0900\n+++ linux-2.6.27-rc7-freeze/include/linux/buffer_head.h\t2008-09-22 13:11:03.000000000 +0900\n@@ -170,7 +170,7 @@ void __wait_on_buffer(struct buffer_head\n wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);\n int fsync_bdev(struct block_device *);\n struct super_block *freeze_bdev(struct block_device *);\n-void thaw_bdev(struct block_device *, struct super_block *);\n+int thaw_bdev(struct block_device *, struct super_block *);\n int fsync_super(struct super_block *);\n int fsync_no_super(struct block_device *);\n struct buffer_head *__find_get_block(struct block_device *bdev, sector_t block,\ndiff -uprN -X linux-2.6.27-rc7-lockfs-reiserfs/Documentation/dontdiff linux-2.6.27-rc7-lockfs-reiserfs/include/linux/fs.\nh linux-2.6.27-rc7-freeze/include/linux/fs.h\n--- linux-2.6.27-rc7-lockfs-reiserfs/include/linux/fs.h\t2008-09-22 09:53:46.000000000 +0900\n+++ linux-2.6.27-rc7-freeze/include/linux/fs.h\t2008-09-22 13:11:03.000000000 +0900\n@@ -226,6 +226,8 @@ extern int dir_notify_enable;\n #define BMAP_IOCTL 1\t\t/* obsolete - kept for compatibility */\n #define FIBMAP\t   _IO(0x00,1)\t/* bmap access */\n #define FIGETBSZ   _IO(0x00,2)\t/* get the block size used for bmap */\n+#define FIFREEZE\t_IOWR('X', 119, int)\t/* Freeze */\n+#define FITHAW\t\t_IOWR('X', 120, int)\t/* Thaw */\n \n #define\tFS_IOC_GETFLAGS\t\t\t_IOR('f', 1, long)\n #define\tFS_IOC_SETFLAGS\t\t\t_IOW('f', 2, long)\n@@ -574,6 +576,11 @@ struct block_device {\n \t * care to not mess up bd_private for that case.\n \t */\n \tunsigned long\t\tbd_private;\n+\n+\t/* The counter of freeze processes */\n+\tint\t\t\tbd_fsfreeze_count;\n+\t/* Mutex for freeze */\n+\tstruct mutex\t\tbd_fsfreeze_mutex;\n };\n \n /*\n","prefixes":["8/10"]}