All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nick Piggin <npiggin@suse.de>
To: Al Viro <viro@ZenIV.linux.org.uk>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	linux-fsdevel@vger.kernel.org
Subject: [patch] fs: fix superblock iteration race
Date: Sat, 12 Jun 2010 00:50:09 +1000	[thread overview]
Message-ID: <20100611145009.GE16436@laptop> (raw)

Not sure if this is really the _cleanest_ way to fix it. But open coding
the list walking is a bit annoying too. And I couldn't see any real way to
make the list macro safe. Better ideas?

Thanks,
Nick

--
list_for_each_entry_safe is not suitable to protect against concurrent
modification of the list. 6754af6 introduced a race in sb walking.

list_for_each_entry can use the trick of pinning the current entry in
the list before we drop and retake the lock because it subsequently
follows cur->next. However list_for_each_entry_safe saves n=cur->next
for following before entering the loop body, so when the lock is
dropped, n may be deleted.

Signed-off-by: Nick Piggin <npiggin@suse.de>
---
 fs/dcache.c |    2 ++
 fs/super.c  |    6 ++++++
 2 files changed, 8 insertions(+)

Index: linux-2.6/fs/dcache.c
===================================================================
--- linux-2.6.orig/fs/dcache.c	2010-06-12 00:00:10.000000000 +1000
+++ linux-2.6/fs/dcache.c	2010-06-12 00:38:21.000000000 +1000
@@ -590,6 +590,8 @@ static void prune_dcache(int count)
 			up_read(&sb->s_umount);
 		}
 		spin_lock(&sb_lock);
+		/* old n may have been deleted */
+		n = list_entry(sb->s_list.next, struct super_block, s_list);
 		count -= pruned;
 		__put_super(sb);
 		/* more work left to do? */
Index: linux-2.6/fs/super.c
===================================================================
--- linux-2.6.orig/fs/super.c	2010-06-11 23:55:40.000000000 +1000
+++ linux-2.6/fs/super.c	2010-06-12 00:38:40.000000000 +1000
@@ -374,6 +374,8 @@ void sync_supers(void)
 			up_read(&sb->s_umount);
 
 			spin_lock(&sb_lock);
+			/* old n may have been deleted */
+			n = list_entry(sb->s_list.next, struct super_block, s_list);
 			__put_super(sb);
 		}
 	}
@@ -405,6 +407,8 @@ void iterate_supers(void (*f)(struct sup
 		up_read(&sb->s_umount);
 
 		spin_lock(&sb_lock);
+		/* old n may have been deleted */
+		n = list_entry(sb->s_list.next, struct super_block, s_list);
 		__put_super(sb);
 	}
 	spin_unlock(&sb_lock);
@@ -585,6 +589,8 @@ static void do_emergency_remount(struct
 		}
 		up_write(&sb->s_umount);
 		spin_lock(&sb_lock);
+		/* old n may have been deleted */
+		n = list_entry(sb->s_list.next, struct super_block, s_list);
 		__put_super(sb);
 	}
 	spin_unlock(&sb_lock);

             reply	other threads:[~2010-06-11 14:50 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-11 14:50 Nick Piggin [this message]
2010-06-11 16:06 ` [patch] fs: fix superblock iteration race Linus Torvalds
2010-06-12  3:37   ` Nick Piggin
2010-06-12  3:57   ` Nick Piggin
2010-06-12  4:15     ` Linus Torvalds
2010-06-12  4:38       ` Nick Piggin
2010-06-12  4:46         ` Linus Torvalds
2010-06-14 15:07           ` Nick Piggin

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=20100611145009.GE16436@laptop \
    --to=npiggin@suse.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.