Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+88 −74
Original line number Diff line number Diff line
@@ -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;