mirror of
https://github.com/fail0verflow/switch-linux.git
synced 2025-05-04 02:34:21 -04:00
autofs4: factor should_expire() out of autofs4_expire_indirect.
Future patch will potentially call this twice, so make it separate. Signed-off-by: NeilBrown <neilb@suse.de> Reviewed-by: Ian Kent <raven@themaw.net> Tested-by: Ian Kent <raven@themaw.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
23bfc2a24e
commit
a5d1dba143
1 changed files with 88 additions and 74 deletions
|
@ -339,6 +339,89 @@ out:
|
||||||
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,
|
||||||
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,
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue