aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2011-06-07 09:09:30 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-08-01 02:27:57 -0400
commit43c1c9cd244098012441b90c32304f11f1258d43 (patch)
treef6d924936b376cfa3bb7bc1eec5716900a61a2cf /fs/dcache.c
parentc6627c60c07c43b51ef88e352627fa786d1e1592 (diff)
VFS: Reorganise shrink_dcache_for_umount_subtree() after demise of dcache_lock
Reorganise shrink_dcache_for_umount_subtree() in light of the demise of dcache_lock. Without that dcache_lock, there is no need for the batching of removal of dentries from the system under it (we wanted to make intensive use of the locked data whilst we held it, but didn't want to hold it for long at a time). This works, provided the preceding patch is correct in its removal of locking on dentry->d_lock on the basis that no one should be locking these dentries any more as the whole superblock is defunct. With this patch, the calls to dentry_lru_del() and __d_shrink() are placed at the point where each dentry is detached handled. It is possible that, as an alternative, the batching should still be done - but only for dentry_lru_del() of all a dentry's children in one go. In such a case, the batching would be done under dcache_lru_lock. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c22
1 files changed, 5 insertions, 17 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 9df8b861e18e..2347cdb15abb 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -842,33 +842,21 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
842 842
843 BUG_ON(!IS_ROOT(dentry)); 843 BUG_ON(!IS_ROOT(dentry));
844 844
845 /* detach this root from the system */
846 dentry_lru_del(dentry);
847 __d_shrink(dentry);
848
849 for (;;) { 845 for (;;) {
850 /* descend to the first leaf in the current subtree */ 846 /* descend to the first leaf in the current subtree */
851 while (!list_empty(&dentry->d_subdirs)) { 847 while (!list_empty(&dentry->d_subdirs))
852 struct dentry *loop;
853
854 /* this is a branch with children - detach all of them
855 * from the system in one go */
856 list_for_each_entry(loop, &dentry->d_subdirs,
857 d_u.d_child) {
858 dentry_lru_del(loop);
859 __d_shrink(loop);
860 }
861
862 /* move to the first child */
863 dentry = list_entry(dentry->d_subdirs.next, 848 dentry = list_entry(dentry->d_subdirs.next,
864 struct dentry, d_u.d_child); 849 struct dentry, d_u.d_child);
865 }
866 850
867 /* consume the dentries from this leaf up through its parents 851 /* consume the dentries from this leaf up through its parents
868 * until we find one with children or run out altogether */ 852 * until we find one with children or run out altogether */
869 do { 853 do {
870 struct inode *inode; 854 struct inode *inode;
871 855
856 /* detach from the system */
857 dentry_lru_del(dentry);
858 __d_shrink(dentry);
859
872 if (dentry->d_count != 0) { 860 if (dentry->d_count != 0) {
873 printk(KERN_ERR 861 printk(KERN_ERR
874 "BUG: Dentry %p{i=%lx,n=%s}" 862 "BUG: Dentry %p{i=%lx,n=%s}"