linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Fernando Luis Vázquez Cao" <fernando_b1@lab.ntt.co.jp>
To: Al Viro <viro@zeniv.linux.org.uk>
Cc: Josef Bacik <jbacik@fusionio.com>,
	Eric Sandeen <sandeen@redhat.com>,
	Dave Chinner <dchinner@redhat.com>,
	Christoph Hellwig <hch@infradead.org>, Jan Kara <jack@suse.cz>,
	Luiz Capitulino <lcapitulino@redhat.com>,
	linux-fsdevel@vger.kernel.org
Subject: [PATCH 1/17] vfs: add __iterate_supers() and helpers around it
Date: Mon, 07 Jan 2013 20:21:01 +0900	[thread overview]
Message-ID: <1357557661.8183.2.camel@nexus.lab.ntt.co.jp> (raw)
In-Reply-To: <1357557492.8183.1.camel@nexus.lab.ntt.co.jp>

iterate_supers() calls a function provided by the caller with the s_umount
semaphore taken in read mode. However, there may be cases where write mode
is preferable, so we add __iterate_supers(), which lets one
specify the mode of the lock, and replace iterate_supers with two helpers
around __iterate_supers(), iterate_supers_read() and iterate_supers_write().

This will be used to fix the emergency thaw (filesystem unfreeze) code, which
iterates over the list of superblocks but needs to hold the s_umount semaphore
in _write_ mode bebore carrying out the actual thaw operation.

This patch introduces no semantic changes since current iterate_supers()
callers are just updated to use iterate_supers_read() instead.

Cc: linux-fsdevel@vger.kernel.org
Cc: Josef Bacik <jbacik@fusionio.com>
Cc: Eric Sandeen <sandeen@redhat.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dave Chinner <dchinner@redhat.com>
Cc: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---

diff -urNp linux-3.8-rc1-orig/fs/buffer.c linux-3.8-rc1/fs/buffer.c
--- linux-3.8-rc1-orig/fs/buffer.c	2012-12-25 10:27:41.166737000 +0900
+++ linux-3.8-rc1/fs/buffer.c	2012-12-25 11:14:41.304018000 +0900
@@ -520,7 +520,7 @@ static void do_thaw_one(struct super_blo
 
 static void do_thaw_all(struct work_struct *work)
 {
-	iterate_supers(do_thaw_one, NULL);
+	iterate_supers_read(do_thaw_one, NULL);
 	kfree(work);
 	printk(KERN_WARNING "Emergency Thaw complete\n");
 }
diff -urNp linux-3.8-rc1-orig/fs/drop_caches.c linux-3.8-rc1/fs/drop_caches.c
--- linux-3.8-rc1-orig/fs/drop_caches.c	2012-12-11 12:30:57.000000000 +0900
+++ linux-3.8-rc1/fs/drop_caches.c	2012-12-25 11:14:41.304018000 +0900
@@ -59,7 +59,7 @@ int drop_caches_sysctl_handler(ctl_table
 		return ret;
 	if (write) {
 		if (sysctl_drop_caches & 1)
-			iterate_supers(drop_pagecache_sb, NULL);
+			iterate_supers_read(drop_pagecache_sb, NULL);
 		if (sysctl_drop_caches & 2)
 			drop_slab();
 	}
diff -urNp linux-3.8-rc1-orig/fs/quota/quota.c linux-3.8-rc1/fs/quota/quota.c
--- linux-3.8-rc1-orig/fs/quota/quota.c	2012-12-25 10:27:42.034737000 +0900
+++ linux-3.8-rc1/fs/quota/quota.c	2012-12-25 11:14:41.304018000 +0900
@@ -58,7 +58,7 @@ static int quota_sync_all(int type)
 		return -EINVAL;
 	ret = security_quotactl(Q_SYNC, type, 0, NULL);
 	if (!ret)
-		iterate_supers(quota_sync_one, &type);
+		iterate_supers_read(quota_sync_one, &type);
 	return ret;
 }
 
diff -urNp linux-3.8-rc1-orig/fs/super.c linux-3.8-rc1/fs/super.c
--- linux-3.8-rc1-orig/fs/super.c	2012-12-11 12:30:57.000000000 +0900
+++ linux-3.8-rc1/fs/super.c	2012-12-25 11:14:41.308018000 +0900
@@ -508,14 +508,16 @@ void drop_super(struct super_block *sb)
 EXPORT_SYMBOL(drop_super);
 
 /**
- *	iterate_supers - call function for all active superblocks
+ *	__iterate_supers - call function for all active superblocks
  *	@f: function to call
  *	@arg: argument to pass to it
+ *	@wlock: mode of superblock lock (false->read lock, true->write lock)
  *
  *	Scans the superblock list and calls given function, passing it
  *	locked superblock and given argument.
  */
-void iterate_supers(void (*f)(struct super_block *, void *), void *arg)
+static void __iterate_supers(void (*f)(struct super_block *, void *), void *arg,
+			     bool wlock)
 {
 	struct super_block *sb, *p = NULL;
 
@@ -526,10 +528,18 @@ void iterate_supers(void (*f)(struct sup
 		sb->s_count++;
 		spin_unlock(&sb_lock);
 
-		down_read(&sb->s_umount);
+		if (wlock)
+			down_write(&sb->s_umount);
+		else
+			down_read(&sb->s_umount);
+
 		if (sb->s_root && (sb->s_flags & MS_BORN))
 			f(sb, arg);
-		up_read(&sb->s_umount);
+
+		if (wlock)
+			up_write(&sb->s_umount);
+		else
+			up_read(&sb->s_umount);
 
 		spin_lock(&sb_lock);
 		if (p)
@@ -542,6 +552,34 @@ void iterate_supers(void (*f)(struct sup
 }
 
 /**
+ *	iterate_supers_read - call function for all active superblocks
+ *	@f: function to call
+ *	@arg: argument to pass to it
+ *
+ *	Scans the superblock list and calls given function, passing it
+ *	a superblock locked in _read_ mode and given argument. The lock
+ *	is automatically relased after the function returns.
+ */
+void iterate_supers_read(void (*f)(struct super_block *, void *), void *arg)
+{
+	__iterate_supers(f, arg , false);
+}
+
+/**
+ *	iterate_supers_write - call function for all active superblocks
+ *	@f: function to call
+ *	@arg: argument to pass to it
+ *
+ *	Scans the superblock list and calls given function, passing it
+ *	a superblock locked in _write_ mode and given argument. The lock
+ *	is automatically relased after the function returns.
+ */
+void iterate_supers_write(void (*f)(struct super_block *, void *), void *arg)
+{
+	__iterate_supers(f, arg , true);
+}
+
+/**
  *	iterate_supers_type - call function for superblocks of given type
  *	@type: fs type
  *	@f: function to call
diff -urNp linux-3.8-rc1-orig/fs/sync.c linux-3.8-rc1/fs/sync.c
--- linux-3.8-rc1-orig/fs/sync.c	2012-12-11 12:30:57.000000000 +0900
+++ linux-3.8-rc1/fs/sync.c	2012-12-25 11:14:41.312018000 +0900
@@ -104,9 +104,9 @@ SYSCALL_DEFINE0(sync)
 	int nowait = 0, wait = 1;
 
 	wakeup_flusher_threads(0, WB_REASON_SYNC);
-	iterate_supers(sync_inodes_one_sb, NULL);
-	iterate_supers(sync_fs_one_sb, &nowait);
-	iterate_supers(sync_fs_one_sb, &wait);
+	iterate_supers_read(sync_inodes_one_sb, NULL);
+	iterate_supers_read(sync_fs_one_sb, &nowait);
+	iterate_supers_read(sync_fs_one_sb, &wait);
 	iterate_bdevs(fdatawrite_one_bdev, NULL);
 	iterate_bdevs(fdatawait_one_bdev, NULL);
 	if (unlikely(laptop_mode))
@@ -122,11 +122,11 @@ static void do_sync_work(struct work_str
 	 * Sync twice to reduce the possibility we skipped some inodes / pages
 	 * because they were temporarily locked
 	 */
-	iterate_supers(sync_inodes_one_sb, &nowait);
-	iterate_supers(sync_fs_one_sb, &nowait);
+	iterate_supers_read(sync_inodes_one_sb, &nowait);
+	iterate_supers_read(sync_fs_one_sb, &nowait);
 	iterate_bdevs(fdatawrite_one_bdev, NULL);
-	iterate_supers(sync_inodes_one_sb, &nowait);
-	iterate_supers(sync_fs_one_sb, &nowait);
+	iterate_supers_read(sync_inodes_one_sb, &nowait);
+	iterate_supers_read(sync_fs_one_sb, &nowait);
 	iterate_bdevs(fdatawrite_one_bdev, NULL);
 	printk("Emergency Sync complete\n");
 	kfree(work);
diff -urNp linux-3.8-rc1-orig/include/linux/fs.h linux-3.8-rc1/include/linux/fs.h
--- linux-3.8-rc1-orig/include/linux/fs.h	2012-12-25 10:27:42.198737000 +0900
+++ linux-3.8-rc1/include/linux/fs.h	2012-12-25 11:14:41.312018000 +0900
@@ -2494,7 +2494,8 @@ extern struct super_block *get_super(str
 extern struct super_block *get_super_thawed(struct block_device *);
 extern struct super_block *get_active_super(struct block_device *bdev);
 extern void drop_super(struct super_block *sb);
-extern void iterate_supers(void (*)(struct super_block *, void *), void *);
+extern void iterate_supers_read(void (*)(struct super_block *, void *), void *);
+extern void iterate_supers_write(void (*)(struct super_block *, void *), void *);
 extern void iterate_supers_type(struct file_system_type *,
 			        void (*)(struct super_block *, void *), void *);
 
diff -urNp linux-3.8-rc1-orig/security/selinux/hooks.c linux-3.8-rc1/security/selinux/hooks.c
--- linux-3.8-rc1-orig/security/selinux/hooks.c	2012-12-11 12:30:57.000000000 +0900
+++ linux-3.8-rc1/security/selinux/hooks.c	2012-12-25 11:14:41.312018000 +0900
@@ -5720,7 +5720,7 @@ void selinux_complete_init(void)
 
 	/* Set up any superblocks initialized prior to the policy load. */
 	printk(KERN_DEBUG "SELinux:  Setting up existing superblocks.\n");
-	iterate_supers(delayed_superblock_init, NULL);
+	iterate_supers_read(delayed_superblock_init, NULL);
 }
 
 /* SELinux requires early initialization in order to label



  reply	other threads:[~2013-01-07 12:13 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-07 11:18 [PATCH v6 0/17] fsfreeze: miscellaneous fixes and cleanups Fernando Luis Vázquez Cao
2013-01-07 11:21 ` Fernando Luis Vázquez Cao [this message]
2013-01-07 11:22 ` [PATCH 2/17] fsfreeze: add unlocked version of thaw_super Fernando Luis Vázquez Cao
2013-01-07 11:23 ` [PATCH 3/17] fsfreeze: fix emergency thaw infinite loop Fernando Luis Vázquez Cao
2013-01-07 11:26 ` [PATCH 4/17] fsfreeze: emergency thaw will deadlock on s_umount Fernando Luis Vázquez Cao
2013-01-09 16:12   ` Jan Kara
2013-01-07 11:27 ` [PATCH 5/17] xfs: switch to using super methods for fsfreeze Fernando Luis Vázquez Cao
2013-01-07 11:29 ` [PATCH 6/17] fsfreeze: move emergency thaw code to fs/super.c Fernando Luis Vázquez Cao
2013-01-07 11:30 ` [PATCH 7/17] fsfreeze: fix nested freezing of sb-less bdevs Fernando Luis Vázquez Cao
2013-01-09 16:24   ` Jan Kara
2013-01-07 11:32 ` [PATCH 8/17] fsfreeze: allow bdev level thaws when the sb is unfrozen Fernando Luis Vázquez Cao
2013-01-09 16:26   ` Jan Kara
2013-01-07 11:34 ` [PATCH 9/17] fsfreeze: freeze_super and thaw_bdev don't play well together Fernando Luis Vázquez Cao
2013-01-07 11:35 ` [PATCH 10/17] fsfreeze: automatically thaw on umount Fernando Luis Vázquez Cao
2013-01-09 17:20   ` Jan Kara
2013-01-10  9:14     ` Fernando Luis Vazquez Cao
2013-01-07 11:36 ` [PATCH 11/17] fsfreeze: add thaw_super_force Fernando Luis Vázquez Cao
2013-01-07 11:38 ` [PATCH 12/17] fsfreeze: sb-level/bdev-level fsfreeze integration Fernando Luis Vázquez Cao
2013-01-09 16:37   ` Jan Kara
2013-01-10  9:57     ` Fernando Luis Vazquez Cao
2013-01-07 11:39 ` [PATCH 13/17] fsfreeze: unfreeze bdevs in addition to filesystems during emergency thaw Fernando Luis Vázquez Cao
2013-01-09 16:41   ` Jan Kara
2013-01-07 11:41 ` [PATCH 14/17] vfs: leverage bd_super in get_super and get_active_super Fernando Luis Vázquez Cao
2013-01-09 16:44   ` Jan Kara
2013-01-07 11:42 ` [PATCH 15/17] btrfs: store pointer to superblock in bd_super Fernando Luis Vázquez Cao
2013-01-07 11:43 ` [PATCH 16/17] fsfreeze: allow freeze counter lock nesting Fernando Luis Vázquez Cao
2013-01-07 11:44 ` [PATCH 17/17] fsfreeze: export freeze_count through mountinfo Fernando Luis Vázquez Cao

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=1357557661.8183.2.camel@nexus.lab.ntt.co.jp \
    --to=fernando_b1@lab.ntt.co.jp \
    --cc=dchinner@redhat.com \
    --cc=hch@infradead.org \
    --cc=jack@suse.cz \
    --cc=jbacik@fusionio.com \
    --cc=lcapitulino@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=sandeen@redhat.com \
    --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;
as well as URLs for NNTP newsgroup(s).