Commit 551de6f34dfeefbeeadb32909c387d393114ecc8
1 parent
1712ac8fda
Exists in
master
and in
4 other branches
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>
Showing 6 changed files with 25 additions and 4 deletions Side-by-side Diff
fs/buffer.c
fs/dcache.c
fs/drop_caches.c
fs/quota/quota.c
fs/super.c
... | ... | @@ -135,6 +135,7 @@ |
135 | 135 | int ret = 0; |
136 | 136 | |
137 | 137 | if (!--sb->s_count) { |
138 | + list_del_init(&sb->s_list); | |
138 | 139 | destroy_super(sb); |
139 | 140 | ret = 1; |
140 | 141 | } |
... | ... | @@ -151,7 +152,7 @@ |
151 | 152 | int __put_super_and_need_restart(struct super_block *sb) |
152 | 153 | { |
153 | 154 | /* check for race with generic_shutdown_super() */ |
154 | - if (list_empty(&sb->s_list)) { | |
155 | + if (list_empty(&sb->s_instances)) { | |
155 | 156 | /* super block is removed, need to restart... */ |
156 | 157 | __put_super(sb); |
157 | 158 | return 1; |
... | ... | @@ -308,8 +309,7 @@ |
308 | 309 | } |
309 | 310 | spin_lock(&sb_lock); |
310 | 311 | /* should be initialized for __put_super_and_need_restart() */ |
311 | - list_del_init(&sb->s_list); | |
312 | - list_del(&sb->s_instances); | |
312 | + list_del_init(&sb->s_instances); | |
313 | 313 | spin_unlock(&sb_lock); |
314 | 314 | up_write(&sb->s_umount); |
315 | 315 | } |
... | ... | @@ -400,6 +400,8 @@ |
400 | 400 | spin_lock(&sb_lock); |
401 | 401 | restart: |
402 | 402 | list_for_each_entry(sb, &super_blocks, s_list) { |
403 | + if (list_empty(&sb->s_instances)) | |
404 | + continue; | |
403 | 405 | if (sb->s_op->write_super && sb->s_dirt) { |
404 | 406 | sb->s_count++; |
405 | 407 | spin_unlock(&sb_lock); |
... | ... | @@ -435,6 +437,8 @@ |
435 | 437 | spin_lock(&sb_lock); |
436 | 438 | rescan: |
437 | 439 | list_for_each_entry(sb, &super_blocks, s_list) { |
440 | + if (list_empty(&sb->s_instances)) | |
441 | + continue; | |
438 | 442 | if (sb->s_bdev == bdev) { |
439 | 443 | sb->s_count++; |
440 | 444 | spin_unlock(&sb_lock); |
... | ... | @@ -471,6 +475,8 @@ |
471 | 475 | |
472 | 476 | spin_lock(&sb_lock); |
473 | 477 | list_for_each_entry(sb, &super_blocks, s_list) { |
478 | + if (list_empty(&sb->s_instances)) | |
479 | + continue; | |
474 | 480 | if (sb->s_bdev != bdev) |
475 | 481 | continue; |
476 | 482 | |
... | ... | @@ -490,6 +496,8 @@ |
490 | 496 | spin_lock(&sb_lock); |
491 | 497 | rescan: |
492 | 498 | list_for_each_entry(sb, &super_blocks, s_list) { |
499 | + if (list_empty(&sb->s_instances)) | |
500 | + continue; | |
493 | 501 | if (sb->s_dev == dev) { |
494 | 502 | sb->s_count++; |
495 | 503 | spin_unlock(&sb_lock); |
... | ... | @@ -600,6 +608,8 @@ |
600 | 608 | |
601 | 609 | spin_lock(&sb_lock); |
602 | 610 | list_for_each_entry(sb, &super_blocks, s_list) { |
611 | + if (list_empty(&sb->s_instances)) | |
612 | + continue; | |
603 | 613 | sb->s_count++; |
604 | 614 | spin_unlock(&sb_lock); |
605 | 615 | down_write(&sb->s_umount); |
fs/sync.c
... | ... | @@ -99,10 +99,13 @@ |
99 | 99 | mutex_lock(&mutex); /* Could be down_interruptible */ |
100 | 100 | spin_lock(&sb_lock); |
101 | 101 | list_for_each_entry(sb, &super_blocks, s_list) |
102 | - sb->s_need_sync = 1; | |
102 | + if (!list_empty(&sb->s_instances)) | |
103 | + sb->s_need_sync = 1; | |
103 | 104 | |
104 | 105 | restart: |
105 | 106 | list_for_each_entry(sb, &super_blocks, s_list) { |
107 | + if (list_empty(&sb->s_instances)) | |
108 | + continue; | |
106 | 109 | if (!sb->s_need_sync) |
107 | 110 | continue; |
108 | 111 | sb->s_need_sync = 0; |