[PATCH] autofs4: simplify expire tree traversal
Simplify the expire tree traversal code by using a function from namespace.c to calculate the next entry in the top down tree traversals carried out during the expire operation. Signed-off-by: Ian Kent <raven@themaw.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
@@ -72,6 +72,27 @@ done:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate next entry in top down tree traversal.
|
||||||
|
* From next_mnt in namespace.c - elegant.
|
||||||
|
*/
|
||||||
|
static struct dentry *next_dentry(struct dentry *p, struct dentry *root)
|
||||||
|
{
|
||||||
|
struct list_head *next = p->d_subdirs.next;
|
||||||
|
|
||||||
|
if (next == &p->d_subdirs) {
|
||||||
|
while (1) {
|
||||||
|
if (p == root)
|
||||||
|
return NULL;
|
||||||
|
next = p->d_u.d_child.next;
|
||||||
|
if (next != &p->d_parent->d_subdirs)
|
||||||
|
break;
|
||||||
|
p = p->d_parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list_entry(next, struct dentry, d_u.d_child);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check a directory tree of mount points for busyness
|
/* Check a directory tree of mount points for busyness
|
||||||
* The tree is not busy iff no mountpoints are busy
|
* The tree is not busy iff no mountpoints are busy
|
||||||
*/
|
*/
|
||||||
@@ -80,8 +101,7 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
|
|||||||
unsigned long timeout,
|
unsigned long timeout,
|
||||||
int do_now)
|
int do_now)
|
||||||
{
|
{
|
||||||
struct dentry *this_parent = top;
|
struct dentry *p;
|
||||||
struct list_head *next;
|
|
||||||
|
|
||||||
DPRINTK("top %p %.*s",
|
DPRINTK("top %p %.*s",
|
||||||
top, (int)top->d_name.len, top->d_name.name);
|
top, (int)top->d_name.len, top->d_name.name);
|
||||||
@@ -99,49 +119,28 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
spin_lock(&dcache_lock);
|
spin_lock(&dcache_lock);
|
||||||
repeat:
|
for (p = top; p; p = next_dentry(p, top)) {
|
||||||
next = this_parent->d_subdirs.next;
|
|
||||||
resume:
|
|
||||||
while (next != &this_parent->d_subdirs) {
|
|
||||||
struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
|
|
||||||
|
|
||||||
/* Negative dentry - give up */
|
/* Negative dentry - give up */
|
||||||
if (!simple_positive(dentry)) {
|
if (!simple_positive(p))
|
||||||
next = next->next;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTK("dentry %p %.*s",
|
DPRINTK("dentry %p %.*s",
|
||||||
dentry, (int)dentry->d_name.len, dentry->d_name.name);
|
p, (int) p->d_name.len, p->d_name.name);
|
||||||
|
|
||||||
if (!simple_empty_nolock(dentry)) {
|
p = dget(p);
|
||||||
this_parent = dentry;
|
|
||||||
goto repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
dentry = dget(dentry);
|
|
||||||
spin_unlock(&dcache_lock);
|
spin_unlock(&dcache_lock);
|
||||||
|
|
||||||
if (d_mountpoint(dentry)) {
|
if (d_mountpoint(p)) {
|
||||||
/* First busy => tree busy */
|
/* First busy => tree busy */
|
||||||
if (autofs4_mount_busy(mnt, dentry)) {
|
if (autofs4_mount_busy(mnt, p)) {
|
||||||
dput(dentry);
|
dput(p);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dput(p);
|
||||||
dput(dentry);
|
|
||||||
spin_lock(&dcache_lock);
|
spin_lock(&dcache_lock);
|
||||||
next = next->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this_parent != top) {
|
|
||||||
next = this_parent->d_u.d_child.next;
|
|
||||||
this_parent = this_parent->d_parent;
|
|
||||||
goto resume;
|
|
||||||
}
|
}
|
||||||
spin_unlock(&dcache_lock);
|
spin_unlock(&dcache_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,59 +149,38 @@ static struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
|
|||||||
unsigned long timeout,
|
unsigned long timeout,
|
||||||
int do_now)
|
int do_now)
|
||||||
{
|
{
|
||||||
struct dentry *this_parent = parent;
|
struct dentry *p;
|
||||||
struct list_head *next;
|
|
||||||
|
|
||||||
DPRINTK("parent %p %.*s",
|
DPRINTK("parent %p %.*s",
|
||||||
parent, (int)parent->d_name.len, parent->d_name.name);
|
parent, (int)parent->d_name.len, parent->d_name.name);
|
||||||
|
|
||||||
spin_lock(&dcache_lock);
|
spin_lock(&dcache_lock);
|
||||||
repeat:
|
for (p = parent; p; p = next_dentry(p, parent)) {
|
||||||
next = this_parent->d_subdirs.next;
|
|
||||||
resume:
|
|
||||||
while (next != &this_parent->d_subdirs) {
|
|
||||||
struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
|
|
||||||
|
|
||||||
/* Negative dentry - give up */
|
/* Negative dentry - give up */
|
||||||
if (!simple_positive(dentry)) {
|
if (!simple_positive(p))
|
||||||
next = next->next;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTK("dentry %p %.*s",
|
DPRINTK("dentry %p %.*s",
|
||||||
dentry, (int)dentry->d_name.len, dentry->d_name.name);
|
p, (int) p->d_name.len, p->d_name.name);
|
||||||
|
|
||||||
if (!list_empty(&dentry->d_subdirs)) {
|
p = dget(p);
|
||||||
this_parent = dentry;
|
|
||||||
goto repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
dentry = dget(dentry);
|
|
||||||
spin_unlock(&dcache_lock);
|
spin_unlock(&dcache_lock);
|
||||||
|
|
||||||
if (d_mountpoint(dentry)) {
|
if (d_mountpoint(p)) {
|
||||||
/* Can we expire this guy */
|
/* Can we expire this guy */
|
||||||
if (!autofs4_can_expire(dentry, timeout, do_now))
|
if (!autofs4_can_expire(p, timeout, do_now))
|
||||||
goto cont;
|
goto cont;
|
||||||
|
|
||||||
/* Can we umount this guy */
|
/* Can we umount this guy */
|
||||||
if (!autofs4_mount_busy(mnt, dentry))
|
if (!autofs4_mount_busy(mnt, p))
|
||||||
return dentry;
|
return p;
|
||||||
|
|
||||||
}
|
}
|
||||||
cont:
|
cont:
|
||||||
dput(dentry);
|
dput(p);
|
||||||
spin_lock(&dcache_lock);
|
spin_lock(&dcache_lock);
|
||||||
next = next->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this_parent != parent) {
|
|
||||||
next = this_parent->d_u.d_child.next;
|
|
||||||
this_parent = this_parent->d_parent;
|
|
||||||
goto resume;
|
|
||||||
}
|
}
|
||||||
spin_unlock(&dcache_lock);
|
spin_unlock(&dcache_lock);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user