提交 a5d1dba1 编写于 作者: N NeilBrown 提交者: 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: NNeilBrown <neilb@suse.de>
Reviewed-by: NIan Kent <raven@themaw.net>
Tested-by: NIan Kent <raven@themaw.net>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 23bfc2a2
...@@ -339,6 +339,89 @@ struct dentry *autofs4_expire_direct(struct super_block *sb, ...@@ -339,6 +339,89 @@ struct dentry *autofs4_expire_direct(struct super_block *sb,
return NULL; return NULL;
} }
/* 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.
*/
static struct dentry *should_expire(struct dentry *dentry,
struct vfsmount *mnt,
unsigned long timeout,
int how)
{
int do_now = how & AUTOFS_EXP_IMMEDIATE;
int exp_leaves = how & AUTOFS_EXP_LEAVES;
struct autofs_info *ino = autofs4_dentry_ino(dentry);
unsigned int ino_count;
/* No point expiring a pending mount */
if (ino->flags & AUTOFS_INF_PENDING)
return NULL;
/*
* Case 1: (i) indirect mount or top level pseudo direct mount
* (autofs-4.1).
* (ii) indirect mount with offset mount, check the "/"
* offset (autofs-5.0+).
*/
if (d_mountpoint(dentry)) {
DPRINTK("checking mountpoint %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/* Can we umount this guy */
if (autofs4_mount_busy(mnt, dentry))
return NULL;
/* Can we expire this guy */
if (autofs4_can_expire(dentry, timeout, do_now))
return dentry;
return NULL;
}
if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
DPRINTK("checking symlink %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/*
* 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))
return dentry;
return NULL;
}
if (simple_empty(dentry))
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)
return NULL;
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)
return NULL;
expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
if (expired) {
if (expired == dentry)
dput(dentry);
return expired;
}
}
return NULL;
}
/* /*
* Find an eligible tree to time-out * Find an eligible tree to time-out
* A tree is eligible if :- * A tree is eligible if :-
...@@ -353,11 +436,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, ...@@ -353,11 +436,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
unsigned long timeout; unsigned long timeout;
struct dentry *root = sb->s_root; struct dentry *root = sb->s_root;
struct dentry *dentry; struct dentry *dentry;
struct dentry *expired = NULL; struct dentry *expired;
int do_now = how & AUTOFS_EXP_IMMEDIATE;
int exp_leaves = how & AUTOFS_EXP_LEAVES;
struct autofs_info *ino; struct autofs_info *ino;
unsigned int ino_count;
if (!root) if (!root)
return NULL; return NULL;
...@@ -368,78 +448,12 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, ...@@ -368,78 +448,12 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
dentry = NULL; dentry = NULL;
while ((dentry = get_next_positive_subdir(dentry, root))) { while ((dentry = get_next_positive_subdir(dentry, root))) {
spin_lock(&sbi->fs_lock); spin_lock(&sbi->fs_lock);
ino = autofs4_dentry_ino(dentry); expired = should_expire(dentry, mnt, timeout, how);
/* No point expiring a pending mount */ if (expired) {
if (ino->flags & AUTOFS_INF_PENDING) if (expired != dentry)
goto next;
/*
* Case 1: (i) indirect mount or top level pseudo direct mount
* (autofs-4.1).
* (ii) indirect mount with offset mount, check the "/"
* offset (autofs-5.0+).
*/
if (d_mountpoint(dentry)) {
DPRINTK("checking mountpoint %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/* Can we umount this guy */
if (autofs4_mount_busy(mnt, dentry))
goto next;
/* Can we expire this guy */
if (autofs4_can_expire(dentry, timeout, do_now)) {
expired = dentry;
goto found;
}
goto next;
}
if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
DPRINTK("checking symlink %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/*
* 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 (simple_empty(dentry))
goto next;
/* 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;
if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
expired = dentry;
goto found;
}
/*
* Case 3: pseudo direct mount, expire individual leaves
* (autofs-4.1).
*/
} else {
/* Path walk currently on this dentry? */
ino_count = atomic_read(&ino->count) + 1;
if (d_count(dentry) > ino_count)
goto next;
expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
if (expired) {
dput(dentry); dput(dentry);
goto found; goto found;
}
} }
next:
spin_unlock(&sbi->fs_lock); spin_unlock(&sbi->fs_lock);
} }
return NULL; return NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册