Commit a5d1dba1 authored by NeilBrown's avatar NeilBrown Committed by Linus Torvalds

autofs4: factor should_expire() out of autofs4_expire_indirect.

Future patch will potentially call this twice, so make it separate.
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Reviewed-by: default avatarIan Kent <raven@themaw.net>
Tested-by: default avatarIan Kent <raven@themaw.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 23bfc2a2
......@@ -339,39 +339,24 @@ struct dentry *autofs4_expire_direct(struct super_block *sb,
return NULL;
}
/*
* Find an eligible tree to time-out
* A tree is eligible if :-
* - it is unused by any user process
* - it has been unused for exp_timeout time
/* Check if 'dentry' should expire, or return a nearby
* dentry that is suitable.
* If returned dentry is different from arg dentry,
* then a dget() reference was taken, else not.
*/
struct dentry *autofs4_expire_indirect(struct super_block *sb,
static struct dentry *should_expire(struct dentry *dentry,
struct vfsmount *mnt,
struct autofs_sb_info *sbi,
unsigned long timeout,
int how)
{
unsigned long timeout;
struct dentry *root = sb->s_root;
struct dentry *dentry;
struct dentry *expired = NULL;
int do_now = how & AUTOFS_EXP_IMMEDIATE;
int exp_leaves = how & AUTOFS_EXP_LEAVES;
struct autofs_info *ino;
struct autofs_info *ino = autofs4_dentry_ino(dentry);
unsigned int ino_count;
if (!root)
return NULL;
now = jiffies;
timeout = sbi->exp_timeout;
dentry = NULL;
while ((dentry = get_next_positive_subdir(dentry, root))) {
spin_lock(&sbi->fs_lock);
ino = autofs4_dentry_ino(dentry);
/* No point expiring a pending mount */
if (ino->flags & AUTOFS_INF_PENDING)
goto next;
return NULL;
/*
* Case 1: (i) indirect mount or top level pseudo direct mount
......@@ -385,14 +370,12 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
/* Can we umount this guy */
if (autofs4_mount_busy(mnt, dentry))
goto next;
return NULL;
/* Can we expire this guy */
if (autofs4_can_expire(dentry, timeout, do_now)) {
expired = dentry;
goto found;
}
goto next;
if (autofs4_can_expire(dentry, timeout, do_now))
return dentry;
return NULL;
}
if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
......@@ -402,44 +385,75 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
* A symlink can't be "busy" in the usual sense so
* just check last used for expire timeout.
*/
if (autofs4_can_expire(dentry, timeout, do_now)) {
expired = dentry;
goto found;
}
goto next;
if (autofs4_can_expire(dentry, timeout, do_now))
return dentry;
return NULL;
}
if (simple_empty(dentry))
goto next;
return NULL;
/* Case 2: tree mount, expire iff entire tree is not busy */
if (!exp_leaves) {
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 1;
if (d_count(dentry) > ino_count)
goto next;
return NULL;
if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
expired = dentry;
goto found;
}
if (!autofs4_tree_busy(mnt, dentry, timeout, do_now))
return dentry;
/*
* Case 3: pseudo direct mount, expire individual leaves
* (autofs-4.1).
*/
} else {
/* Path walk currently on this dentry? */
struct dentry *expired;
ino_count = atomic_read(&ino->count) + 1;
if (d_count(dentry) > ino_count)
goto next;
return NULL;
expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
if (expired) {
if (expired == dentry)
dput(dentry);
goto found;
return expired;
}
}
next:
return NULL;
}
/*
* Find an eligible tree to time-out
* A tree is eligible if :-
* - it is unused by any user process
* - it has been unused for exp_timeout time
*/
struct dentry *autofs4_expire_indirect(struct super_block *sb,
struct vfsmount *mnt,
struct autofs_sb_info *sbi,
int how)
{
unsigned long timeout;
struct dentry *root = sb->s_root;
struct dentry *dentry;
struct dentry *expired;
struct autofs_info *ino;
if (!root)
return NULL;
now = jiffies;
timeout = sbi->exp_timeout;
dentry = NULL;
while ((dentry = get_next_positive_subdir(dentry, root))) {
spin_lock(&sbi->fs_lock);
expired = should_expire(dentry, mnt, timeout, how);
if (expired) {
if (expired != dentry)
dput(dentry);
goto found;
}
spin_unlock(&sbi->fs_lock);
}
return NULL;
......
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