Re: [PATCH 0/2] Two patches for fs/super.c

Previous thread: linux-next: Tree for March 24 by Stephen Rothwell on Tuesday, March 23, 2010 - 10:17 pm. (3 messages)

Next thread: [PATCH] Allow Intel platforms to declare unsynchronized TSC to kernel by Andi Kleen on Tuesday, March 23, 2010 - 10:32 pm. (4 messages)
From: NeilBrown
Date: Tuesday, March 23, 2010 - 10:12 pm

Two patches.

 The second removes S_BIAS which is unnecessary and so potentially
 confusing.

 The first I found the need for while preparing the second patch.  It
 seems that get_active_super doesn't follow the pattern of all other
 code that walks the super_blocks list.

NeilBrown

---

NeilBrown (2):
      VFS: use __put_super_and_need_restart in get_active_super.
      fs/super: remove S_BIAS


 fs/notify/inotify/inotify.c |   33 ++++++++++++++-------------------
 fs/super.c                  |   20 ++++++++------------
 include/linux/fs.h          |    1 -
 3 files changed, 22 insertions(+), 32 deletions(-)

-- 

--

From: NeilBrown
Date: Tuesday, March 23, 2010 - 10:12 pm

The recently-added get_active_super() walks the super_blocks
list but unlike all other code that walks this list it does
not use __put_super_and_need_restart().
I believe this is an omission that should be fixed.

cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: NeilBrown <neilb@suse.de>
---
 fs/super.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index f35ac60..34c8391 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -482,6 +482,7 @@ struct super_block *get_active_super(struct block_device *bdev)
 		return NULL;
 
 	spin_lock(&sb_lock);
+restart:
 	list_for_each_entry(sb, &super_blocks, s_list) {
 		if (sb->s_bdev != bdev)
 			continue;
@@ -500,9 +501,10 @@ struct super_block *get_active_super(struct block_device *bdev)
 			spin_unlock(&sb_lock);
 		}
 		up_write(&sb->s_umount);
-		put_super(sb);
 		yield();
 		spin_lock(&sb_lock);
+		if (__put_super_and_need_restart(sb))
+			goto restart;
 	}
 	spin_unlock(&sb_lock);
 	return NULL;


--

From: NeilBrown
Date: Tuesday, March 23, 2010 - 10:12 pm

The fact that S_BIAS is very large is only used four times,
all(*) with:
		if (s->s_count > S_BIAS) {
			atomic_inc(&s->s_active);

The statement "s->s_count > S_BIAS" is exactly equivalent
to "atomic_read(&s->s_active) != 0", as the bias is subtracted
as soon as s_active becomes zero.
So the above test can more simply become:

		if (atomic_inc_not_zero(&s->s_active)) {

With this in place, S_BIAS does not need to be large, and a value of
'1' will suit.  This simplifies code in a number of places and
removes the need to take a spinlock in several cases.

(*) full disclosure:  in two cases (inotify) it is
           if (s->s_count >= S_BIAS {
however the logic still holds - that can only be true if
s_active is not zero.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 fs/notify/inotify/inotify.c |   33 ++++++++++++++-------------------
 fs/super.c                  |   16 +++++-----------
 include/linux/fs.h          |    1 -
 3 files changed, 19 insertions(+), 31 deletions(-)

diff --git a/fs/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c
index 40b1cf9..44256e5 100644
--- a/fs/notify/inotify/inotify.c
+++ b/fs/notify/inotify/inotify.c
@@ -110,14 +110,10 @@ EXPORT_SYMBOL_GPL(get_inotify_watch);
 int pin_inotify_watch(struct inotify_watch *watch)
 {
 	struct super_block *sb = watch->inode->i_sb;
-	spin_lock(&sb_lock);
-	if (sb->s_count >= S_BIAS) {
-		atomic_inc(&sb->s_active);
-		spin_unlock(&sb_lock);
+	if (atomic_inc_not_zero(&sb->s_active)) {
 		atomic_inc(&watch->count);
 		return 1;
 	}
-	spin_unlock(&sb_lock);
 	return 0;
 }
 
@@ -518,16 +514,17 @@ EXPORT_SYMBOL_GPL(inotify_init_watch);
  * ->s_umount, which will almost certainly wait until the superblock is shut
  * down and the watch in question is pining for fjords.  That's fine, but
  * there is a problem - we might have hit the window between ->s_active
- * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock
- * is past the point of no return and is heading for shutdown) ...
From: Al Viro
Date: Wednesday, March 24, 2010 - 2:20 am

See #untested in vfs tree...
--

From: Neil Brown
Date: Wednesday, March 24, 2010 - 2:50 am

On Wed, 24 Mar 2010 09:20:11 +0000

Ahhh, I see I've been beaten to it by 2 days... I should have posted that
patch months ago :-)

Thanks anyway.

NeilBrown
--

Previous thread: linux-next: Tree for March 24 by Stephen Rothwell on Tuesday, March 23, 2010 - 10:17 pm. (3 messages)

Next thread: [PATCH] Allow Intel platforms to declare unsynchronized TSC to kernel by Andi Kleen on Tuesday, March 23, 2010 - 10:32 pm. (4 messages)