diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-03-22 19:36:35 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-05-21 18:31:14 -0400 |
commit | 551de6f34dfeefbeeadb32909c387d393114ecc8 (patch) | |
tree | 822af803e7e75ed476b0a176639c162e0395910d /fs/super.c | |
parent | 1712ac8fda7d8bc4dc921f5777b7423aacad7263 (diff) |
Leave superblocks on s_list until the end
We used to remove from s_list and s_instances at the same
time. So let's *not* do the former and skip superblocks
that have empty s_instances in the loops over s_list.
The next step, of course, will be to get rid of rescan logics
in those loops.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/super.c')
-rw-r--r-- | fs/super.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/super.c b/fs/super.c index 157657b32798..0390461dfca0 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -135,6 +135,7 @@ static int __put_super(struct super_block *sb) | |||
135 | int ret = 0; | 135 | int ret = 0; |
136 | 136 | ||
137 | if (!--sb->s_count) { | 137 | if (!--sb->s_count) { |
138 | list_del_init(&sb->s_list); | ||
138 | destroy_super(sb); | 139 | destroy_super(sb); |
139 | ret = 1; | 140 | ret = 1; |
140 | } | 141 | } |
@@ -151,7 +152,7 @@ static int __put_super(struct super_block *sb) | |||
151 | int __put_super_and_need_restart(struct super_block *sb) | 152 | int __put_super_and_need_restart(struct super_block *sb) |
152 | { | 153 | { |
153 | /* check for race with generic_shutdown_super() */ | 154 | /* check for race with generic_shutdown_super() */ |
154 | if (list_empty(&sb->s_list)) { | 155 | if (list_empty(&sb->s_instances)) { |
155 | /* super block is removed, need to restart... */ | 156 | /* super block is removed, need to restart... */ |
156 | __put_super(sb); | 157 | __put_super(sb); |
157 | return 1; | 158 | return 1; |
@@ -308,8 +309,7 @@ void generic_shutdown_super(struct super_block *sb) | |||
308 | } | 309 | } |
309 | spin_lock(&sb_lock); | 310 | spin_lock(&sb_lock); |
310 | /* should be initialized for __put_super_and_need_restart() */ | 311 | /* should be initialized for __put_super_and_need_restart() */ |
311 | list_del_init(&sb->s_list); | 312 | list_del_init(&sb->s_instances); |
312 | list_del(&sb->s_instances); | ||
313 | spin_unlock(&sb_lock); | 313 | spin_unlock(&sb_lock); |
314 | up_write(&sb->s_umount); | 314 | up_write(&sb->s_umount); |
315 | } | 315 | } |
@@ -400,6 +400,8 @@ void sync_supers(void) | |||
400 | spin_lock(&sb_lock); | 400 | spin_lock(&sb_lock); |
401 | restart: | 401 | restart: |
402 | list_for_each_entry(sb, &super_blocks, s_list) { | 402 | list_for_each_entry(sb, &super_blocks, s_list) { |
403 | if (list_empty(&sb->s_instances)) | ||
404 | continue; | ||
403 | if (sb->s_op->write_super && sb->s_dirt) { | 405 | if (sb->s_op->write_super && sb->s_dirt) { |
404 | sb->s_count++; | 406 | sb->s_count++; |
405 | spin_unlock(&sb_lock); | 407 | spin_unlock(&sb_lock); |
@@ -435,6 +437,8 @@ struct super_block * get_super(struct block_device *bdev) | |||
435 | spin_lock(&sb_lock); | 437 | spin_lock(&sb_lock); |
436 | rescan: | 438 | rescan: |
437 | list_for_each_entry(sb, &super_blocks, s_list) { | 439 | list_for_each_entry(sb, &super_blocks, s_list) { |
440 | if (list_empty(&sb->s_instances)) | ||
441 | continue; | ||
438 | if (sb->s_bdev == bdev) { | 442 | if (sb->s_bdev == bdev) { |
439 | sb->s_count++; | 443 | sb->s_count++; |
440 | spin_unlock(&sb_lock); | 444 | spin_unlock(&sb_lock); |
@@ -471,6 +475,8 @@ struct super_block *get_active_super(struct block_device *bdev) | |||
471 | 475 | ||
472 | spin_lock(&sb_lock); | 476 | spin_lock(&sb_lock); |
473 | list_for_each_entry(sb, &super_blocks, s_list) { | 477 | list_for_each_entry(sb, &super_blocks, s_list) { |
478 | if (list_empty(&sb->s_instances)) | ||
479 | continue; | ||
474 | if (sb->s_bdev != bdev) | 480 | if (sb->s_bdev != bdev) |
475 | continue; | 481 | continue; |
476 | 482 | ||
@@ -490,6 +496,8 @@ struct super_block * user_get_super(dev_t dev) | |||
490 | spin_lock(&sb_lock); | 496 | spin_lock(&sb_lock); |
491 | rescan: | 497 | rescan: |
492 | list_for_each_entry(sb, &super_blocks, s_list) { | 498 | list_for_each_entry(sb, &super_blocks, s_list) { |
499 | if (list_empty(&sb->s_instances)) | ||
500 | continue; | ||
493 | if (sb->s_dev == dev) { | 501 | if (sb->s_dev == dev) { |
494 | sb->s_count++; | 502 | sb->s_count++; |
495 | spin_unlock(&sb_lock); | 503 | spin_unlock(&sb_lock); |
@@ -600,6 +608,8 @@ static void do_emergency_remount(struct work_struct *work) | |||
600 | 608 | ||
601 | spin_lock(&sb_lock); | 609 | spin_lock(&sb_lock); |
602 | list_for_each_entry(sb, &super_blocks, s_list) { | 610 | list_for_each_entry(sb, &super_blocks, s_list) { |
611 | if (list_empty(&sb->s_instances)) | ||
612 | continue; | ||
603 | sb->s_count++; | 613 | sb->s_count++; |
604 | spin_unlock(&sb_lock); | 614 | spin_unlock(&sb_lock); |
605 | down_write(&sb->s_umount); | 615 | down_write(&sb->s_umount); |