diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index f1358e5c3a59..c8c78ba07827 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -536,7 +536,7 @@ restart: | |||
536 | */ | 536 | */ |
537 | static void prune_dcache(int count) | 537 | static void prune_dcache(int count) |
538 | { | 538 | { |
539 | struct super_block *sb; | 539 | struct super_block *sb, *n; |
540 | int w_count; | 540 | int w_count; |
541 | int unused = dentry_stat.nr_unused; | 541 | int unused = dentry_stat.nr_unused; |
542 | int prune_ratio; | 542 | int prune_ratio; |
@@ -545,13 +545,14 @@ static void prune_dcache(int count) | |||
545 | if (unused == 0 || count == 0) | 545 | if (unused == 0 || count == 0) |
546 | return; | 546 | return; |
547 | spin_lock(&dcache_lock); | 547 | spin_lock(&dcache_lock); |
548 | restart: | ||
549 | if (count >= unused) | 548 | if (count >= unused) |
550 | prune_ratio = 1; | 549 | prune_ratio = 1; |
551 | else | 550 | else |
552 | prune_ratio = unused / count; | 551 | prune_ratio = unused / count; |
553 | spin_lock(&sb_lock); | 552 | spin_lock(&sb_lock); |
554 | list_for_each_entry(sb, &super_blocks, s_list) { | 553 | list_for_each_entry_safe(sb, n, &super_blocks, s_list) { |
554 | if (list_empty(&sb->s_instances)) | ||
555 | continue; | ||
555 | if (sb->s_nr_dentry_unused == 0) | 556 | if (sb->s_nr_dentry_unused == 0) |
556 | continue; | 557 | continue; |
557 | sb->s_count++; | 558 | sb->s_count++; |
@@ -589,15 +590,13 @@ restart: | |||
589 | up_read(&sb->s_umount); | 590 | up_read(&sb->s_umount); |
590 | } | 591 | } |
591 | spin_lock(&sb_lock); | 592 | spin_lock(&sb_lock); |
593 | /* lock was dropped, must reset next */ | ||
594 | list_safe_reset_next(sb, n, s_list); | ||
592 | count -= pruned; | 595 | count -= pruned; |
593 | /* | 596 | __put_super(sb); |
594 | * restart only when sb is no longer on the list and | 597 | /* more work left to do? */ |
595 | * we have more work to do. | 598 | if (count <= 0) |
596 | */ | 599 | break; |
597 | if (__put_super_and_need_restart(sb) && count > 0) { | ||
598 | spin_unlock(&sb_lock); | ||
599 | goto restart; | ||
600 | } | ||
601 | } | 600 | } |
602 | spin_unlock(&sb_lock); | 601 | spin_unlock(&sb_lock); |
603 | spin_unlock(&dcache_lock); | 602 | spin_unlock(&dcache_lock); |
@@ -1529,6 +1528,7 @@ void d_delete(struct dentry * dentry) | |||
1529 | spin_lock(&dentry->d_lock); | 1528 | spin_lock(&dentry->d_lock); |
1530 | isdir = S_ISDIR(dentry->d_inode->i_mode); | 1529 | isdir = S_ISDIR(dentry->d_inode->i_mode); |
1531 | if (atomic_read(&dentry->d_count) == 1) { | 1530 | if (atomic_read(&dentry->d_count) == 1) { |
1531 | dentry->d_flags &= ~DCACHE_CANT_MOUNT; | ||
1532 | dentry_iput(dentry); | 1532 | dentry_iput(dentry); |
1533 | fsnotify_nameremove(dentry, isdir); | 1533 | fsnotify_nameremove(dentry, isdir); |
1534 | return; | 1534 | return; |