aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-03-22 20:15:33 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-05-21 18:31:15 -0400
commit1494583de59dfad2e3a6788ce9817e658d32df22 (patch)
tree6f0a0fe022af703aa18ecc5f65a616fe44b9f8ad
parente7fe0585ca8793e2d43c57e77d4ca79042806acf (diff)
fix get_active_super()/umount() race
This one needs restarts... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/super.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/fs/super.c b/fs/super.c
index 4df8233dfb61..44971d7df1ce 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -471,17 +471,17 @@ struct super_block *get_active_super(struct block_device *bdev)
471 if (!bdev) 471 if (!bdev)
472 return NULL; 472 return NULL;
473 473
474restart:
474 spin_lock(&sb_lock); 475 spin_lock(&sb_lock);
475 list_for_each_entry(sb, &super_blocks, s_list) { 476 list_for_each_entry(sb, &super_blocks, s_list) {
476 if (list_empty(&sb->s_instances)) 477 if (list_empty(&sb->s_instances))
477 continue; 478 continue;
478 if (sb->s_bdev != bdev) 479 if (sb->s_bdev == bdev) {
479 continue; 480 if (grab_super(sb)) /* drops sb_lock */
480 481 return sb;
481 if (grab_super(sb)) /* drops sb_lock */ 482 else
482 return sb; 483 goto restart;
483 484 }
484 spin_lock(&sb_lock);
485 } 485 }
486 spin_unlock(&sb_lock); 486 spin_unlock(&sb_lock);
487 return NULL; 487 return NULL;