aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index a1ff91eef108..fd4a428998ef 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -478,11 +478,12 @@ static void prune_dcache(int count, struct super_block *sb)
478 up_read(s_umount); 478 up_read(s_umount);
479 } 479 }
480 spin_unlock(&dentry->d_lock); 480 spin_unlock(&dentry->d_lock);
481 /* Cannot remove the first dentry, and it isn't appropriate 481 /*
482 * to move it to the head of the list, so give up, and try 482 * Insert dentry at the head of the list as inserting at the
483 * later 483 * tail leads to a cycle.
484 */ 484 */
485 break; 485 list_add(&dentry->d_lru, &dentry_unused);
486 dentry_stat.nr_unused++;
486 } 487 }
487 spin_unlock(&dcache_lock); 488 spin_unlock(&dcache_lock);
488} 489}
@@ -556,6 +557,7 @@ repeat:
556static void shrink_dcache_for_umount_subtree(struct dentry *dentry) 557static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
557{ 558{
558 struct dentry *parent; 559 struct dentry *parent;
560 unsigned detached = 0;
559 561
560 BUG_ON(!IS_ROOT(dentry)); 562 BUG_ON(!IS_ROOT(dentry));
561 563
@@ -620,7 +622,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
620 atomic_dec(&parent->d_count); 622 atomic_dec(&parent->d_count);
621 623
622 list_del(&dentry->d_u.d_child); 624 list_del(&dentry->d_u.d_child);
623 dentry_stat.nr_dentry--; /* For d_free, below */ 625 detached++;
624 626
625 inode = dentry->d_inode; 627 inode = dentry->d_inode;
626 if (inode) { 628 if (inode) {
@@ -638,7 +640,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
638 * otherwise we ascend to the parent and move to the 640 * otherwise we ascend to the parent and move to the
639 * next sibling if there is one */ 641 * next sibling if there is one */
640 if (!parent) 642 if (!parent)
641 return; 643 goto out;
642 644
643 dentry = parent; 645 dentry = parent;
644 646
@@ -647,6 +649,11 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
647 dentry = list_entry(dentry->d_subdirs.next, 649 dentry = list_entry(dentry->d_subdirs.next,
648 struct dentry, d_u.d_child); 650 struct dentry, d_u.d_child);
649 } 651 }
652out:
653 /* several dentries were freed, need to correct nr_dentry */
654 spin_lock(&dcache_lock);
655 dentry_stat.nr_dentry -= detached;
656 spin_unlock(&dcache_lock);
650} 657}
651 658
652/* 659/*