// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
 * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
 * Copyright 2001-2006 Ian Kent <raven@themaw.net>
 */

#include "autofs_i.h"

/* Check if a dentry can be expired */
static inline int autofs_can_expire(struct dentry *dentry,
				    unsigned long timeout, unsigned int how)
{
	struct autofs_info *ino = autofs_dentry_ino(dentry);

	/* dentry in the process of being deleted */
	if (ino == NULL)
		return 0;

	if (!(how & AUTOFS_EXP_IMMEDIATE)) {
		/* Too young to die */
		if (!timeout || time_after(ino->last_used + timeout, jiffies))
			return 0;
	}
	return 1;
}

/* Check a mount point for busyness */
static int autofs_mount_busy(struct vfsmount *mnt,
			     struct dentry *dentry, unsigned int how)
{
	struct dentry *top = dentry;
	struct path path = {.mnt = mnt, .dentry = dentry};
	int status = 1;

	pr_debug("dentry %p %pd\n", dentry, dentry);

	path_get(&path);

	if (!follow_down_one(&path))
		goto done;

	if (is_autofs_dentry(path.dentry)) {
		struct autofs_sb_info *sbi = autofs_sbi(path.dentry->d_sb);

		/* This is an autofs submount, we can't expire it */
		if (autofs_type_indirect(sbi->type))
			goto done;
	}

	/* Not a submount, has a forced expire been requested */
	if (how & AUTOFS_EXP_FORCED) {
		status = 0;
		goto done;
	}

	/* Update the expiry counter if fs is busy */
	if (!may_umount_tree(path.mnt)) {
		struct autofs_info *ino;

		ino = autofs_dentry_ino(top);
		ino->last_used = jiffies;
		goto done;
	}

	status = 0;
done:
	pr_debug("returning = %d\n", status);
	path_put(&path);
	return status;
}

/* p->d_lock held */
static struct dentry *positive_after(struct dentry *p, struct dentry *child)
{
	child = child ? d_next_sibling(child) : d_first_child(p);

	hlist_for_each_entry_from(child, d_sib) {
		spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
		if (simple_positive(child)) {
			dget_dlock(child);
			spin_unlock(&child->d_lock);
			return child;
		}
		spin_unlock(&child->d_lock);
	}

	return NULL;
}

/*
 * Calculate and dget next entry in the subdirs list under root.
 */
static struct dentry *get_next_positive_subdir(struct dentry *prev,
					       struct dentry *root)
{
	struct autofs_sb_info *sbi = autofs_sbi(root->d_sb);
	struct dentry *q;

	spin_lock(&sbi->lookup_lock);
	spin_lock(&root->d_lock);
	q = positive_after(root, prev);
	spin_unlock(&root->d_lock);
	spin_unlock(&sbi->lookup_lock);
	dput(prev);
	return q;
}

/*
 * Calculate and dget next entry in top down tree traversal.
 */
static struct dentry *get_next_positive_dentry(struct dentry *prev,
					       struct dentry *root)
{
	struct autofs_sb_info *sbi = autofs_sbi(root->d_sb);
	struct dentry *p = prev, *ret = NULL, *d = NULL;

	if (prev == NULL)
		return dget(root);

	spin_lock(&sbi->lookup_lock);
	spin_lock(&p->d_lock);
	while (1) {
		struct dentry *parent;

		ret = positive_after(p, d);
		if (ret || p == root)
			break;
		parent = p->d_parent;
		spin_unlock(&p->d_lock);
		spin_lock(&parent->d_lock);
		d = p;
		p = parent;
	}
	spin_unlock(&p->d_lock);
	spin_unlock(&sbi->lookup_lock);
	dput(prev);
	return ret;
}

/*
 * Check a direct mount point for busyness.
 * Direct mounts have similar expiry semantics to tree mounts.
 * The tree is not busy iff no mountpoints are busy and there are no
 * autofs submounts.
 */
static int autofs_direct_busy(struct vfsmount *mnt,
			      struct dentry *top,
			      unsigned long timeout,
			      unsigned int how)
{
	pr_debug("top %p %pd\n", top, top);

	/* Forced expire, user space handles busy mounts */
	if (how & AUTOFS_EXP_FORCED)
		return 0;

	/* If it's busy update the expiry counters */
	if (!may_umount_tree(mnt)) {
		struct autofs_info *ino;

		ino = autofs_dentry_ino(top);
		if (ino)
			ino->last_used = jiffies;
		return 1;
	}

	/* Timeout of a direct mount is determined by its top dentry */
	if (!autofs_can_expire(top, timeout, how))
		return 1;

	return 0;
}

/*
 * Check a directory tree of mount points for busyness
 * The tree is not busy iff no mountpoints are busy
 */
static int autofs_tree_busy(struct vfsmount *mnt,
			    struct dentry *top,
			    unsigned long timeout,
			    unsigned int how)
{
	struct autofs_info *top_ino = autofs_dentry_ino(top);
	struct dentry *p;

	pr_debug("top %p %pd\n", top, top);

	/* Negative dentry - give up */
	if (!simple_positive(top))
		return 1;

	p = NULL;
	while ((p = get_next_positive_dentry(p, top))) {
		pr_debug("dentry %p %pd\n", p, p);

		/*
		 * Is someone visiting anywhere in the subtree ?
		 * If there's no mount we need to check the usage
		 * count for the autofs dentry.
		 * If the fs is busy update the expiry counter.
		 */
		if (d_mountpoint(p)) {
			if (autofs_mount_busy(mnt, p, how)) {
				top_ino->last_used = jiffies;
				dput(p);
				return 1;
			}
		} else {
			struct autofs_info *ino = autofs_dentry_ino(p);
			unsigned int ino_count = READ_ONCE(ino->count);

			/* allow for dget above and top is already dgot */
			if (p == top)
				ino_count += 2;
			else
				ino_count++;

			if (d_count(p) > ino_count) {
				top_ino->last_used = jiffies;
				dput(p);
				return 1;
			}
		}
	}

	/* Forced expire, user space handles busy mounts */
	if (how & AUTOFS_EXP_FORCED)
		return 0;

	/* Timeout of a tree mount is ultimately determined by its top dentry */
	if (!autofs_can_expire(top, timeout, how))
		return 1;

	return 0;
}

static struct dentry *autofs_check_leaves(struct vfsmount *mnt,
					  struct dentry *parent,
					  unsigned long timeout,
					  unsigned int how)
{
	struct dentry *p;

	pr_debug("parent %p %pd\n", parent, parent);

	p = NULL;
	while ((p = get_next_positive_dentry(p, parent))) {
		pr_debug("dentry %p %pd\n", p, p);

		if (d_mountpoint(p)) {
			/* Can we umount this guy */
			if (autofs_mount_busy(mnt, p, how))
				continue;

			/* This isn't a submount so if a forced expire
			 * has been requested, user space handles busy
			 * mounts */
			if (how & AUTOFS_EXP_FORCED)
				return p;

			/* Can we expire this guy */
			if (autofs_can_expire(p, timeout, how))
				return p;
		}
	}
	return NULL;
}

/* Check if we can expire a direct mount (possibly a tree) */
static struct dentry *autofs_expire_direct(struct super_block *sb,
					   struct vfsmount *mnt,
					   struct autofs_sb_info *sbi,
					   unsigned int how)
{
	struct dentry *root = dget(sb->s_root);
	struct autofs_info *ino;
	unsigned long timeout;

	if (!root)
		return NULL;

	timeout = sbi->exp_timeout;

	if (!autofs_direct_busy(mnt, root, timeout, how)) {
		spin_lock(&sbi->fs_lock);
		ino = autofs_dentry_ino(root);
		/* No point expiring a pending mount */
		if (ino->flags & AUTOFS_INF_PENDING) {
			spin_unlock(&sbi->fs_lock);
			goto out;
		}
		ino->flags |= AUTOFS_INF_WANT_EXPIRE;
		spin_unlock(&sbi->fs_lock);
		synchronize_rcu();
		if (!autofs_direct_busy(mnt, root, timeout, how)) {
			spin_lock(&sbi->fs_lock);
			ino->flags |= AUTOFS_INF_EXPIRING;
			init_completion(&ino->expire_complete);
			spin_unlock(&sbi->fs_lock);
			return root;
		}
		spin_lock(&sbi->fs_lock);
		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
		spin_unlock(&sbi->fs_lock);
	}
out:
	dput(root);

	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,
				    unsigned int how)
{
	struct autofs_info *ino = autofs_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)) {
		pr_debug("checking mountpoint %p %pd\n", dentry, dentry);

		/* Can we umount this guy */
		if (autofs_mount_busy(mnt, dentry, how))
			return NULL;

		/* This isn't a submount so if a forced expire
		 * has been requested, user space handles busy
		 * mounts */
		if (how & AUTOFS_EXP_FORCED)
			return dentry;

		/* Can we expire this guy */
		if (autofs_can_expire(dentry, timeout, how))
			return dentry;
		return NULL;
	}

	if (d_is_symlink(dentry)) {
		pr_debug("checking symlink %p %pd\n", dentry, dentry);

		/* Forced expire, user space handles busy mounts */
		if (how & AUTOFS_EXP_FORCED)
			return dentry;

		/*
		 * A symlink can't be "busy" in the usual sense so
		 * just check last used for expire timeout.
		 */
		if (autofs_can_expire(dentry, timeout, how))
			return dentry;
		return NULL;
	}

	if (autofs_empty(ino))
		return NULL;

	/* Case 2: tree mount, expire iff entire tree is not busy */
	if (!(how & AUTOFS_EXP_LEAVES)) {
		/* Not a forced expire? */
		if (!(how & AUTOFS_EXP_FORCED)) {
			/* ref-walk currently on this dentry? */
			ino_count = READ_ONCE(ino->count) + 1;
			if (d_count(dentry) > ino_count)
				return NULL;
		}

		if (!autofs_tree_busy(mnt, dentry, timeout, how))
			return dentry;
	/*
	 * Case 3: pseudo direct mount, expire individual leaves
	 *	   (autofs-4.1).
	 */
	} else {
		struct dentry *expired;

		/* Not a forced expire? */
		if (!(how & AUTOFS_EXP_FORCED)) {
			/* ref-walk currently on this dentry? */
			ino_count = READ_ONCE(ino->count) + 1;
			if (d_count(dentry) > ino_count)
				return NULL;
		}

		expired = autofs_check_leaves(mnt, dentry, timeout, how);
		if (expired) {
			if (expired == dentry)
				dput(dentry);
			return expired;
		}
	}
	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
 */
static struct dentry *autofs_expire_indirect(struct super_block *sb,
					     struct vfsmount *mnt,
					     struct autofs_sb_info *sbi,
					     unsigned int how)
{
	unsigned long timeout;
	struct dentry *root = sb->s_root;
	struct dentry *dentry;
	struct dentry *expired;
	struct dentry *found;
	struct autofs_info *ino;

	if (!root)
		return NULL;

	dentry = NULL;
	while ((dentry = get_next_positive_subdir(dentry, root))) {
		spin_lock(&sbi->fs_lock);
		ino = autofs_dentry_ino(dentry);
		if (ino->flags & AUTOFS_INF_WANT_EXPIRE) {
			spin_unlock(&sbi->fs_lock);
			continue;
		}
		spin_unlock(&sbi->fs_lock);

		if (ino->flags & AUTOFS_INF_EXPIRE_SET)
			timeout = ino->exp_timeout;
		else
			timeout = sbi->exp_timeout;

		expired = should_expire(dentry, mnt, timeout, how);
		if (!expired)
			continue;

		spin_lock(&sbi->fs_lock);
		ino = autofs_dentry_ino(expired);
		ino->flags |= AUTOFS_INF_WANT_EXPIRE;
		spin_unlock(&sbi->fs_lock);
		synchronize_rcu();

		/* Make sure a reference is not taken on found if
		 * things have changed.
		 */
		how &= ~AUTOFS_EXP_LEAVES;
		found = should_expire(expired, mnt, timeout, how);
		if (found != expired) { // something has changed, continue
			dput(found);
			goto next;
		}

		if (expired != dentry)
			dput(dentry);

		spin_lock(&sbi->fs_lock);
		goto found;
next:
		spin_lock(&sbi->fs_lock);
		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
		spin_unlock(&sbi->fs_lock);
		if (expired != dentry)
			dput(expired);
	}
	return NULL;

found:
	pr_debug("returning %p %pd\n", expired, expired);
	ino->flags |= AUTOFS_INF_EXPIRING;
	init_completion(&ino->expire_complete);
	spin_unlock(&sbi->fs_lock);
	return expired;
}

int autofs_expire_wait(const struct path *path, int rcu_walk)
{
	struct dentry *dentry = path->dentry;
	struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb);
	struct autofs_info *ino = autofs_dentry_ino(dentry);
	int status;
	int state;

	/* Block on any pending expire */
	if (!(ino->flags & AUTOFS_INF_WANT_EXPIRE))
		return 0;
	if (rcu_walk)
		return -ECHILD;

retry:
	spin_lock(&sbi->fs_lock);
	state = ino->flags & (AUTOFS_INF_WANT_EXPIRE | AUTOFS_INF_EXPIRING);
	if (state == AUTOFS_INF_WANT_EXPIRE) {
		spin_unlock(&sbi->fs_lock);
		/*
		 * Possibly being selected for expire, wait until
		 * it's selected or not.
		 */
		schedule_timeout_uninterruptible(HZ/10);
		goto retry;
	}
	if (state & AUTOFS_INF_EXPIRING) {
		spin_unlock(&sbi->fs_lock);

		pr_debug("waiting for expire %p name=%pd\n", dentry, dentry);

		status = autofs_wait(sbi, path, NFY_NONE);
		wait_for_completion(&ino->expire_complete);

		pr_debug("expire done status=%d\n", status);

		if (d_unhashed(dentry))
			return -EAGAIN;

		return status;
	}
	spin_unlock(&sbi->fs_lock);

	return 0;
}

/* Perform an expiry operation */
int autofs_expire_run(struct super_block *sb,
		      struct vfsmount *mnt,
		      struct autofs_sb_info *sbi,
		      struct autofs_packet_expire __user *pkt_p)
{
	struct autofs_packet_expire pkt;
	struct autofs_info *ino;
	struct dentry *dentry;
	int ret = 0;

	memset(&pkt, 0, sizeof(pkt));

	pkt.hdr.proto_version = sbi->version;
	pkt.hdr.type = autofs_ptype_expire;

	dentry = autofs_expire_indirect(sb, mnt, sbi, 0);
	if (!dentry)
		return -EAGAIN;

	pkt.len = dentry->d_name.len;
	memcpy(pkt.name, dentry->d_name.name, pkt.len);
	pkt.name[pkt.len] = '\0';

	if (copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)))
		ret = -EFAULT;

	spin_lock(&sbi->fs_lock);
	ino = autofs_dentry_ino(dentry);
	/* avoid rapid-fire expire attempts if expiry fails */
	ino->last_used = jiffies;
	ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
	complete_all(&ino->expire_complete);
	spin_unlock(&sbi->fs_lock);

	dput(dentry);

	return ret;
}

int autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
			   struct autofs_sb_info *sbi, unsigned int how)
{
	struct dentry *dentry;
	int ret = -EAGAIN;

	if (autofs_type_trigger(sbi->type))
		dentry = autofs_expire_direct(sb, mnt, sbi, how);
	else
		dentry = autofs_expire_indirect(sb, mnt, sbi, how);

	if (dentry) {
		struct autofs_info *ino = autofs_dentry_ino(dentry);
		const struct path path = { .mnt = mnt, .dentry = dentry };

		/* This is synchronous because it makes the daemon a
		 * little easier
		 */
		ret = autofs_wait(sbi, &path, NFY_EXPIRE);

		spin_lock(&sbi->fs_lock);
		/* avoid rapid-fire expire attempts if expiry fails */
		ino->last_used = jiffies;
		ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
		complete_all(&ino->expire_complete);
		spin_unlock(&sbi->fs_lock);
		dput(dentry);
	}

	return ret;
}

/*
 * Call repeatedly until it returns -EAGAIN, meaning there's nothing
 * more to be done.
 */
int autofs_expire_multi(struct super_block *sb, struct vfsmount *mnt,
			struct autofs_sb_info *sbi, int __user *arg)
{
	unsigned int how = 0;

	if (arg && get_user(how, arg))
		return -EFAULT;

	return autofs_do_expire_multi(sb, mnt, sbi, how);
}
