brintos

brintos / linux-shallow public Read only

0
0
Text · 14.4 KiB · 5c2d459 Raw
621 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved4 * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>5 * Copyright 2001-2006 Ian Kent <raven@themaw.net>6 */7 8#include "autofs_i.h"9 10/* Check if a dentry can be expired */11static inline int autofs_can_expire(struct dentry *dentry,12				    unsigned long timeout, unsigned int how)13{14	struct autofs_info *ino = autofs_dentry_ino(dentry);15 16	/* dentry in the process of being deleted */17	if (ino == NULL)18		return 0;19 20	if (!(how & AUTOFS_EXP_IMMEDIATE)) {21		/* Too young to die */22		if (!timeout || time_after(ino->last_used + timeout, jiffies))23			return 0;24	}25	return 1;26}27 28/* Check a mount point for busyness */29static int autofs_mount_busy(struct vfsmount *mnt,30			     struct dentry *dentry, unsigned int how)31{32	struct dentry *top = dentry;33	struct path path = {.mnt = mnt, .dentry = dentry};34	int status = 1;35 36	pr_debug("dentry %p %pd\n", dentry, dentry);37 38	path_get(&path);39 40	if (!follow_down_one(&path))41		goto done;42 43	if (is_autofs_dentry(path.dentry)) {44		struct autofs_sb_info *sbi = autofs_sbi(path.dentry->d_sb);45 46		/* This is an autofs submount, we can't expire it */47		if (autofs_type_indirect(sbi->type))48			goto done;49	}50 51	/* Not a submount, has a forced expire been requested */52	if (how & AUTOFS_EXP_FORCED) {53		status = 0;54		goto done;55	}56 57	/* Update the expiry counter if fs is busy */58	if (!may_umount_tree(path.mnt)) {59		struct autofs_info *ino;60 61		ino = autofs_dentry_ino(top);62		ino->last_used = jiffies;63		goto done;64	}65 66	status = 0;67done:68	pr_debug("returning = %d\n", status);69	path_put(&path);70	return status;71}72 73/* p->d_lock held */74static struct dentry *positive_after(struct dentry *p, struct dentry *child)75{76	child = child ? d_next_sibling(child) : d_first_child(p);77 78	hlist_for_each_entry_from(child, d_sib) {79		spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);80		if (simple_positive(child)) {81			dget_dlock(child);82			spin_unlock(&child->d_lock);83			return child;84		}85		spin_unlock(&child->d_lock);86	}87 88	return NULL;89}90 91/*92 * Calculate and dget next entry in the subdirs list under root.93 */94static struct dentry *get_next_positive_subdir(struct dentry *prev,95					       struct dentry *root)96{97	struct autofs_sb_info *sbi = autofs_sbi(root->d_sb);98	struct dentry *q;99 100	spin_lock(&sbi->lookup_lock);101	spin_lock(&root->d_lock);102	q = positive_after(root, prev);103	spin_unlock(&root->d_lock);104	spin_unlock(&sbi->lookup_lock);105	dput(prev);106	return q;107}108 109/*110 * Calculate and dget next entry in top down tree traversal.111 */112static struct dentry *get_next_positive_dentry(struct dentry *prev,113					       struct dentry *root)114{115	struct autofs_sb_info *sbi = autofs_sbi(root->d_sb);116	struct dentry *p = prev, *ret = NULL, *d = NULL;117 118	if (prev == NULL)119		return dget(root);120 121	spin_lock(&sbi->lookup_lock);122	spin_lock(&p->d_lock);123	while (1) {124		struct dentry *parent;125 126		ret = positive_after(p, d);127		if (ret || p == root)128			break;129		parent = p->d_parent;130		spin_unlock(&p->d_lock);131		spin_lock(&parent->d_lock);132		d = p;133		p = parent;134	}135	spin_unlock(&p->d_lock);136	spin_unlock(&sbi->lookup_lock);137	dput(prev);138	return ret;139}140 141/*142 * Check a direct mount point for busyness.143 * Direct mounts have similar expiry semantics to tree mounts.144 * The tree is not busy iff no mountpoints are busy and there are no145 * autofs submounts.146 */147static int autofs_direct_busy(struct vfsmount *mnt,148			      struct dentry *top,149			      unsigned long timeout,150			      unsigned int how)151{152	pr_debug("top %p %pd\n", top, top);153 154	/* Forced expire, user space handles busy mounts */155	if (how & AUTOFS_EXP_FORCED)156		return 0;157 158	/* If it's busy update the expiry counters */159	if (!may_umount_tree(mnt)) {160		struct autofs_info *ino;161 162		ino = autofs_dentry_ino(top);163		if (ino)164			ino->last_used = jiffies;165		return 1;166	}167 168	/* Timeout of a direct mount is determined by its top dentry */169	if (!autofs_can_expire(top, timeout, how))170		return 1;171 172	return 0;173}174 175/*176 * Check a directory tree of mount points for busyness177 * The tree is not busy iff no mountpoints are busy178 */179static int autofs_tree_busy(struct vfsmount *mnt,180			    struct dentry *top,181			    unsigned long timeout,182			    unsigned int how)183{184	struct autofs_info *top_ino = autofs_dentry_ino(top);185	struct dentry *p;186 187	pr_debug("top %p %pd\n", top, top);188 189	/* Negative dentry - give up */190	if (!simple_positive(top))191		return 1;192 193	p = NULL;194	while ((p = get_next_positive_dentry(p, top))) {195		pr_debug("dentry %p %pd\n", p, p);196 197		/*198		 * Is someone visiting anywhere in the subtree ?199		 * If there's no mount we need to check the usage200		 * count for the autofs dentry.201		 * If the fs is busy update the expiry counter.202		 */203		if (d_mountpoint(p)) {204			if (autofs_mount_busy(mnt, p, how)) {205				top_ino->last_used = jiffies;206				dput(p);207				return 1;208			}209		} else {210			struct autofs_info *ino = autofs_dentry_ino(p);211			unsigned int ino_count = READ_ONCE(ino->count);212 213			/* allow for dget above and top is already dgot */214			if (p == top)215				ino_count += 2;216			else217				ino_count++;218 219			if (d_count(p) > ino_count) {220				top_ino->last_used = jiffies;221				dput(p);222				return 1;223			}224		}225	}226 227	/* Forced expire, user space handles busy mounts */228	if (how & AUTOFS_EXP_FORCED)229		return 0;230 231	/* Timeout of a tree mount is ultimately determined by its top dentry */232	if (!autofs_can_expire(top, timeout, how))233		return 1;234 235	return 0;236}237 238static struct dentry *autofs_check_leaves(struct vfsmount *mnt,239					  struct dentry *parent,240					  unsigned long timeout,241					  unsigned int how)242{243	struct dentry *p;244 245	pr_debug("parent %p %pd\n", parent, parent);246 247	p = NULL;248	while ((p = get_next_positive_dentry(p, parent))) {249		pr_debug("dentry %p %pd\n", p, p);250 251		if (d_mountpoint(p)) {252			/* Can we umount this guy */253			if (autofs_mount_busy(mnt, p, how))254				continue;255 256			/* This isn't a submount so if a forced expire257			 * has been requested, user space handles busy258			 * mounts */259			if (how & AUTOFS_EXP_FORCED)260				return p;261 262			/* Can we expire this guy */263			if (autofs_can_expire(p, timeout, how))264				return p;265		}266	}267	return NULL;268}269 270/* Check if we can expire a direct mount (possibly a tree) */271static struct dentry *autofs_expire_direct(struct super_block *sb,272					   struct vfsmount *mnt,273					   struct autofs_sb_info *sbi,274					   unsigned int how)275{276	struct dentry *root = dget(sb->s_root);277	struct autofs_info *ino;278	unsigned long timeout;279 280	if (!root)281		return NULL;282 283	timeout = sbi->exp_timeout;284 285	if (!autofs_direct_busy(mnt, root, timeout, how)) {286		spin_lock(&sbi->fs_lock);287		ino = autofs_dentry_ino(root);288		/* No point expiring a pending mount */289		if (ino->flags & AUTOFS_INF_PENDING) {290			spin_unlock(&sbi->fs_lock);291			goto out;292		}293		ino->flags |= AUTOFS_INF_WANT_EXPIRE;294		spin_unlock(&sbi->fs_lock);295		synchronize_rcu();296		if (!autofs_direct_busy(mnt, root, timeout, how)) {297			spin_lock(&sbi->fs_lock);298			ino->flags |= AUTOFS_INF_EXPIRING;299			init_completion(&ino->expire_complete);300			spin_unlock(&sbi->fs_lock);301			return root;302		}303		spin_lock(&sbi->fs_lock);304		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;305		spin_unlock(&sbi->fs_lock);306	}307out:308	dput(root);309 310	return NULL;311}312 313/* Check if 'dentry' should expire, or return a nearby314 * dentry that is suitable.315 * If returned dentry is different from arg dentry,316 * then a dget() reference was taken, else not.317 */318static struct dentry *should_expire(struct dentry *dentry,319				    struct vfsmount *mnt,320				    unsigned long timeout,321				    unsigned int how)322{323	struct autofs_info *ino = autofs_dentry_ino(dentry);324	unsigned int ino_count;325 326	/* No point expiring a pending mount */327	if (ino->flags & AUTOFS_INF_PENDING)328		return NULL;329 330	/*331	 * Case 1: (i) indirect mount or top level pseudo direct mount332	 *	   (autofs-4.1).333	 *	   (ii) indirect mount with offset mount, check the "/"334	 *	   offset (autofs-5.0+).335	 */336	if (d_mountpoint(dentry)) {337		pr_debug("checking mountpoint %p %pd\n", dentry, dentry);338 339		/* Can we umount this guy */340		if (autofs_mount_busy(mnt, dentry, how))341			return NULL;342 343		/* This isn't a submount so if a forced expire344		 * has been requested, user space handles busy345		 * mounts */346		if (how & AUTOFS_EXP_FORCED)347			return dentry;348 349		/* Can we expire this guy */350		if (autofs_can_expire(dentry, timeout, how))351			return dentry;352		return NULL;353	}354 355	if (d_is_symlink(dentry)) {356		pr_debug("checking symlink %p %pd\n", dentry, dentry);357 358		/* Forced expire, user space handles busy mounts */359		if (how & AUTOFS_EXP_FORCED)360			return dentry;361 362		/*363		 * A symlink can't be "busy" in the usual sense so364		 * just check last used for expire timeout.365		 */366		if (autofs_can_expire(dentry, timeout, how))367			return dentry;368		return NULL;369	}370 371	if (autofs_empty(ino))372		return NULL;373 374	/* Case 2: tree mount, expire iff entire tree is not busy */375	if (!(how & AUTOFS_EXP_LEAVES)) {376		/* Not a forced expire? */377		if (!(how & AUTOFS_EXP_FORCED)) {378			/* ref-walk currently on this dentry? */379			ino_count = READ_ONCE(ino->count) + 1;380			if (d_count(dentry) > ino_count)381				return NULL;382		}383 384		if (!autofs_tree_busy(mnt, dentry, timeout, how))385			return dentry;386	/*387	 * Case 3: pseudo direct mount, expire individual leaves388	 *	   (autofs-4.1).389	 */390	} else {391		struct dentry *expired;392 393		/* Not a forced expire? */394		if (!(how & AUTOFS_EXP_FORCED)) {395			/* ref-walk currently on this dentry? */396			ino_count = READ_ONCE(ino->count) + 1;397			if (d_count(dentry) > ino_count)398				return NULL;399		}400 401		expired = autofs_check_leaves(mnt, dentry, timeout, how);402		if (expired) {403			if (expired == dentry)404				dput(dentry);405			return expired;406		}407	}408	return NULL;409}410 411/*412 * Find an eligible tree to time-out413 * A tree is eligible if :-414 *  - it is unused by any user process415 *  - it has been unused for exp_timeout time416 */417static struct dentry *autofs_expire_indirect(struct super_block *sb,418					     struct vfsmount *mnt,419					     struct autofs_sb_info *sbi,420					     unsigned int how)421{422	unsigned long timeout;423	struct dentry *root = sb->s_root;424	struct dentry *dentry;425	struct dentry *expired;426	struct dentry *found;427	struct autofs_info *ino;428 429	if (!root)430		return NULL;431 432	dentry = NULL;433	while ((dentry = get_next_positive_subdir(dentry, root))) {434		spin_lock(&sbi->fs_lock);435		ino = autofs_dentry_ino(dentry);436		if (ino->flags & AUTOFS_INF_WANT_EXPIRE) {437			spin_unlock(&sbi->fs_lock);438			continue;439		}440		spin_unlock(&sbi->fs_lock);441 442		if (ino->flags & AUTOFS_INF_EXPIRE_SET)443			timeout = ino->exp_timeout;444		else445			timeout = sbi->exp_timeout;446 447		expired = should_expire(dentry, mnt, timeout, how);448		if (!expired)449			continue;450 451		spin_lock(&sbi->fs_lock);452		ino = autofs_dentry_ino(expired);453		ino->flags |= AUTOFS_INF_WANT_EXPIRE;454		spin_unlock(&sbi->fs_lock);455		synchronize_rcu();456 457		/* Make sure a reference is not taken on found if458		 * things have changed.459		 */460		how &= ~AUTOFS_EXP_LEAVES;461		found = should_expire(expired, mnt, timeout, how);462		if (found != expired) { // something has changed, continue463			dput(found);464			goto next;465		}466 467		if (expired != dentry)468			dput(dentry);469 470		spin_lock(&sbi->fs_lock);471		goto found;472next:473		spin_lock(&sbi->fs_lock);474		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;475		spin_unlock(&sbi->fs_lock);476		if (expired != dentry)477			dput(expired);478	}479	return NULL;480 481found:482	pr_debug("returning %p %pd\n", expired, expired);483	ino->flags |= AUTOFS_INF_EXPIRING;484	init_completion(&ino->expire_complete);485	spin_unlock(&sbi->fs_lock);486	return expired;487}488 489int autofs_expire_wait(const struct path *path, int rcu_walk)490{491	struct dentry *dentry = path->dentry;492	struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb);493	struct autofs_info *ino = autofs_dentry_ino(dentry);494	int status;495	int state;496 497	/* Block on any pending expire */498	if (!(ino->flags & AUTOFS_INF_WANT_EXPIRE))499		return 0;500	if (rcu_walk)501		return -ECHILD;502 503retry:504	spin_lock(&sbi->fs_lock);505	state = ino->flags & (AUTOFS_INF_WANT_EXPIRE | AUTOFS_INF_EXPIRING);506	if (state == AUTOFS_INF_WANT_EXPIRE) {507		spin_unlock(&sbi->fs_lock);508		/*509		 * Possibly being selected for expire, wait until510		 * it's selected or not.511		 */512		schedule_timeout_uninterruptible(HZ/10);513		goto retry;514	}515	if (state & AUTOFS_INF_EXPIRING) {516		spin_unlock(&sbi->fs_lock);517 518		pr_debug("waiting for expire %p name=%pd\n", dentry, dentry);519 520		status = autofs_wait(sbi, path, NFY_NONE);521		wait_for_completion(&ino->expire_complete);522 523		pr_debug("expire done status=%d\n", status);524 525		if (d_unhashed(dentry))526			return -EAGAIN;527 528		return status;529	}530	spin_unlock(&sbi->fs_lock);531 532	return 0;533}534 535/* Perform an expiry operation */536int autofs_expire_run(struct super_block *sb,537		      struct vfsmount *mnt,538		      struct autofs_sb_info *sbi,539		      struct autofs_packet_expire __user *pkt_p)540{541	struct autofs_packet_expire pkt;542	struct autofs_info *ino;543	struct dentry *dentry;544	int ret = 0;545 546	memset(&pkt, 0, sizeof(pkt));547 548	pkt.hdr.proto_version = sbi->version;549	pkt.hdr.type = autofs_ptype_expire;550 551	dentry = autofs_expire_indirect(sb, mnt, sbi, 0);552	if (!dentry)553		return -EAGAIN;554 555	pkt.len = dentry->d_name.len;556	memcpy(pkt.name, dentry->d_name.name, pkt.len);557	pkt.name[pkt.len] = '\0';558 559	if (copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)))560		ret = -EFAULT;561 562	spin_lock(&sbi->fs_lock);563	ino = autofs_dentry_ino(dentry);564	/* avoid rapid-fire expire attempts if expiry fails */565	ino->last_used = jiffies;566	ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);567	complete_all(&ino->expire_complete);568	spin_unlock(&sbi->fs_lock);569 570	dput(dentry);571 572	return ret;573}574 575int autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,576			   struct autofs_sb_info *sbi, unsigned int how)577{578	struct dentry *dentry;579	int ret = -EAGAIN;580 581	if (autofs_type_trigger(sbi->type))582		dentry = autofs_expire_direct(sb, mnt, sbi, how);583	else584		dentry = autofs_expire_indirect(sb, mnt, sbi, how);585 586	if (dentry) {587		struct autofs_info *ino = autofs_dentry_ino(dentry);588		const struct path path = { .mnt = mnt, .dentry = dentry };589 590		/* This is synchronous because it makes the daemon a591		 * little easier592		 */593		ret = autofs_wait(sbi, &path, NFY_EXPIRE);594 595		spin_lock(&sbi->fs_lock);596		/* avoid rapid-fire expire attempts if expiry fails */597		ino->last_used = jiffies;598		ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);599		complete_all(&ino->expire_complete);600		spin_unlock(&sbi->fs_lock);601		dput(dentry);602	}603 604	return ret;605}606 607/*608 * Call repeatedly until it returns -EAGAIN, meaning there's nothing609 * more to be done.610 */611int autofs_expire_multi(struct super_block *sb, struct vfsmount *mnt,612			struct autofs_sb_info *sbi, int __user *arg)613{614	unsigned int how = 0;615 616	if (arg && get_user(how, arg))617		return -EFAULT;618 619	return autofs_do_expire_multi(sb, mnt, sbi, how);620}621