Commit 43c1c9cd authored by David Howells's avatar David Howells Committed by Al Viro

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: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent c6627c60
...@@ -842,33 +842,21 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) ...@@ -842,33 +842,21 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
BUG_ON(!IS_ROOT(dentry)); BUG_ON(!IS_ROOT(dentry));
/* detach this root from the system */
dentry_lru_del(dentry);
__d_shrink(dentry);
for (;;) { for (;;) {
/* descend to the first leaf in the current subtree */ /* descend to the first leaf in the current subtree */
while (!list_empty(&dentry->d_subdirs)) { while (!list_empty(&dentry->d_subdirs))
struct dentry *loop;
/* this is a branch with children - detach all of them
* from the system in one go */
list_for_each_entry(loop, &dentry->d_subdirs,
d_u.d_child) {
dentry_lru_del(loop);
__d_shrink(loop);
}
/* move to the first child */
dentry = list_entry(dentry->d_subdirs.next, dentry = list_entry(dentry->d_subdirs.next,
struct dentry, d_u.d_child); struct dentry, d_u.d_child);
}
/* consume the dentries from this leaf up through its parents /* consume the dentries from this leaf up through its parents
* until we find one with children or run out altogether */ * until we find one with children or run out altogether */
do { do {
struct inode *inode; struct inode *inode;
/* detach from the system */
dentry_lru_del(dentry);
__d_shrink(dentry);
if (dentry->d_count != 0) { if (dentry->d_count != 0) {
printk(KERN_ERR printk(KERN_ERR
"BUG: Dentry %p{i=%lx,n=%s}" "BUG: Dentry %p{i=%lx,n=%s}"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment