cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

expire.c (14752B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
      4 * 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	if (child)
     77		child = list_next_entry(child, d_child);
     78	else
     79		child = list_first_entry(&p->d_subdirs, struct dentry, d_child);
     80
     81	list_for_each_entry_from(child, &p->d_subdirs, d_child) {
     82		spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
     83		if (simple_positive(child)) {
     84			dget_dlock(child);
     85			spin_unlock(&child->d_lock);
     86			return child;
     87		}
     88		spin_unlock(&child->d_lock);
     89	}
     90
     91	return NULL;
     92}
     93
     94/*
     95 * Calculate and dget next entry in the subdirs list under root.
     96 */
     97static struct dentry *get_next_positive_subdir(struct dentry *prev,
     98					       struct dentry *root)
     99{
    100	struct autofs_sb_info *sbi = autofs_sbi(root->d_sb);
    101	struct dentry *q;
    102
    103	spin_lock(&sbi->lookup_lock);
    104	spin_lock(&root->d_lock);
    105	q = positive_after(root, prev);
    106	spin_unlock(&root->d_lock);
    107	spin_unlock(&sbi->lookup_lock);
    108	dput(prev);
    109	return q;
    110}
    111
    112/*
    113 * Calculate and dget next entry in top down tree traversal.
    114 */
    115static struct dentry *get_next_positive_dentry(struct dentry *prev,
    116					       struct dentry *root)
    117{
    118	struct autofs_sb_info *sbi = autofs_sbi(root->d_sb);
    119	struct dentry *p = prev, *ret = NULL, *d = NULL;
    120
    121	if (prev == NULL)
    122		return dget(root);
    123
    124	spin_lock(&sbi->lookup_lock);
    125	spin_lock(&p->d_lock);
    126	while (1) {
    127		struct dentry *parent;
    128
    129		ret = positive_after(p, d);
    130		if (ret || p == root)
    131			break;
    132		parent = p->d_parent;
    133		spin_unlock(&p->d_lock);
    134		spin_lock(&parent->d_lock);
    135		d = p;
    136		p = parent;
    137	}
    138	spin_unlock(&p->d_lock);
    139	spin_unlock(&sbi->lookup_lock);
    140	dput(prev);
    141	return ret;
    142}
    143
    144/*
    145 * Check a direct mount point for busyness.
    146 * Direct mounts have similar expiry semantics to tree mounts.
    147 * The tree is not busy iff no mountpoints are busy and there are no
    148 * autofs submounts.
    149 */
    150static int autofs_direct_busy(struct vfsmount *mnt,
    151			      struct dentry *top,
    152			      unsigned long timeout,
    153			      unsigned int how)
    154{
    155	pr_debug("top %p %pd\n", top, top);
    156
    157	/* Forced expire, user space handles busy mounts */
    158	if (how & AUTOFS_EXP_FORCED)
    159		return 0;
    160
    161	/* If it's busy update the expiry counters */
    162	if (!may_umount_tree(mnt)) {
    163		struct autofs_info *ino;
    164
    165		ino = autofs_dentry_ino(top);
    166		if (ino)
    167			ino->last_used = jiffies;
    168		return 1;
    169	}
    170
    171	/* Timeout of a direct mount is determined by its top dentry */
    172	if (!autofs_can_expire(top, timeout, how))
    173		return 1;
    174
    175	return 0;
    176}
    177
    178/*
    179 * Check a directory tree of mount points for busyness
    180 * The tree is not busy iff no mountpoints are busy
    181 */
    182static int autofs_tree_busy(struct vfsmount *mnt,
    183			    struct dentry *top,
    184			    unsigned long timeout,
    185			    unsigned int how)
    186{
    187	struct autofs_info *top_ino = autofs_dentry_ino(top);
    188	struct dentry *p;
    189
    190	pr_debug("top %p %pd\n", top, top);
    191
    192	/* Negative dentry - give up */
    193	if (!simple_positive(top))
    194		return 1;
    195
    196	p = NULL;
    197	while ((p = get_next_positive_dentry(p, top))) {
    198		pr_debug("dentry %p %pd\n", p, p);
    199
    200		/*
    201		 * Is someone visiting anywhere in the subtree ?
    202		 * If there's no mount we need to check the usage
    203		 * count for the autofs dentry.
    204		 * If the fs is busy update the expiry counter.
    205		 */
    206		if (d_mountpoint(p)) {
    207			if (autofs_mount_busy(mnt, p, how)) {
    208				top_ino->last_used = jiffies;
    209				dput(p);
    210				return 1;
    211			}
    212		} else {
    213			struct autofs_info *ino = autofs_dentry_ino(p);
    214			unsigned int ino_count = READ_ONCE(ino->count);
    215
    216			/* allow for dget above and top is already dgot */
    217			if (p == top)
    218				ino_count += 2;
    219			else
    220				ino_count++;
    221
    222			if (d_count(p) > ino_count) {
    223				top_ino->last_used = jiffies;
    224				dput(p);
    225				return 1;
    226			}
    227		}
    228	}
    229
    230	/* Forced expire, user space handles busy mounts */
    231	if (how & AUTOFS_EXP_FORCED)
    232		return 0;
    233
    234	/* Timeout of a tree mount is ultimately determined by its top dentry */
    235	if (!autofs_can_expire(top, timeout, how))
    236		return 1;
    237
    238	return 0;
    239}
    240
    241static struct dentry *autofs_check_leaves(struct vfsmount *mnt,
    242					  struct dentry *parent,
    243					  unsigned long timeout,
    244					  unsigned int how)
    245{
    246	struct dentry *p;
    247
    248	pr_debug("parent %p %pd\n", parent, parent);
    249
    250	p = NULL;
    251	while ((p = get_next_positive_dentry(p, parent))) {
    252		pr_debug("dentry %p %pd\n", p, p);
    253
    254		if (d_mountpoint(p)) {
    255			/* Can we umount this guy */
    256			if (autofs_mount_busy(mnt, p, how))
    257				continue;
    258
    259			/* This isn't a submount so if a forced expire
    260			 * has been requested, user space handles busy
    261			 * mounts */
    262			if (how & AUTOFS_EXP_FORCED)
    263				return p;
    264
    265			/* Can we expire this guy */
    266			if (autofs_can_expire(p, timeout, how))
    267				return p;
    268		}
    269	}
    270	return NULL;
    271}
    272
    273/* Check if we can expire a direct mount (possibly a tree) */
    274static struct dentry *autofs_expire_direct(struct super_block *sb,
    275					   struct vfsmount *mnt,
    276					   struct autofs_sb_info *sbi,
    277					   unsigned int how)
    278{
    279	struct dentry *root = dget(sb->s_root);
    280	struct autofs_info *ino;
    281	unsigned long timeout;
    282
    283	if (!root)
    284		return NULL;
    285
    286	timeout = sbi->exp_timeout;
    287
    288	if (!autofs_direct_busy(mnt, root, timeout, how)) {
    289		spin_lock(&sbi->fs_lock);
    290		ino = autofs_dentry_ino(root);
    291		/* No point expiring a pending mount */
    292		if (ino->flags & AUTOFS_INF_PENDING) {
    293			spin_unlock(&sbi->fs_lock);
    294			goto out;
    295		}
    296		ino->flags |= AUTOFS_INF_WANT_EXPIRE;
    297		spin_unlock(&sbi->fs_lock);
    298		synchronize_rcu();
    299		if (!autofs_direct_busy(mnt, root, timeout, how)) {
    300			spin_lock(&sbi->fs_lock);
    301			ino->flags |= AUTOFS_INF_EXPIRING;
    302			init_completion(&ino->expire_complete);
    303			spin_unlock(&sbi->fs_lock);
    304			return root;
    305		}
    306		spin_lock(&sbi->fs_lock);
    307		ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
    308		spin_unlock(&sbi->fs_lock);
    309	}
    310out:
    311	dput(root);
    312
    313	return NULL;
    314}
    315
    316/* Check if 'dentry' should expire, or return a nearby
    317 * dentry that is suitable.
    318 * If returned dentry is different from arg dentry,
    319 * then a dget() reference was taken, else not.
    320 */
    321static struct dentry *should_expire(struct dentry *dentry,
    322				    struct vfsmount *mnt,
    323				    unsigned long timeout,
    324				    unsigned int how)
    325{
    326	struct autofs_info *ino = autofs_dentry_ino(dentry);
    327	unsigned int ino_count;
    328
    329	/* No point expiring a pending mount */
    330	if (ino->flags & AUTOFS_INF_PENDING)
    331		return NULL;
    332
    333	/*
    334	 * Case 1: (i) indirect mount or top level pseudo direct mount
    335	 *	   (autofs-4.1).
    336	 *	   (ii) indirect mount with offset mount, check the "/"
    337	 *	   offset (autofs-5.0+).
    338	 */
    339	if (d_mountpoint(dentry)) {
    340		pr_debug("checking mountpoint %p %pd\n", dentry, dentry);
    341
    342		/* Can we umount this guy */
    343		if (autofs_mount_busy(mnt, dentry, how))
    344			return NULL;
    345
    346		/* This isn't a submount so if a forced expire
    347		 * has been requested, user space handles busy
    348		 * mounts */
    349		if (how & AUTOFS_EXP_FORCED)
    350			return dentry;
    351
    352		/* Can we expire this guy */
    353		if (autofs_can_expire(dentry, timeout, how))
    354			return dentry;
    355		return NULL;
    356	}
    357
    358	if (d_is_symlink(dentry)) {
    359		pr_debug("checking symlink %p %pd\n", dentry, dentry);
    360
    361		/* Forced expire, user space handles busy mounts */
    362		if (how & AUTOFS_EXP_FORCED)
    363			return dentry;
    364
    365		/*
    366		 * A symlink can't be "busy" in the usual sense so
    367		 * just check last used for expire timeout.
    368		 */
    369		if (autofs_can_expire(dentry, timeout, how))
    370			return dentry;
    371		return NULL;
    372	}
    373
    374	if (simple_empty(dentry))
    375		return NULL;
    376
    377	/* Case 2: tree mount, expire iff entire tree is not busy */
    378	if (!(how & AUTOFS_EXP_LEAVES)) {
    379		/* Not a forced expire? */
    380		if (!(how & AUTOFS_EXP_FORCED)) {
    381			/* ref-walk currently on this dentry? */
    382			ino_count = READ_ONCE(ino->count) + 1;
    383			if (d_count(dentry) > ino_count)
    384				return NULL;
    385		}
    386
    387		if (!autofs_tree_busy(mnt, dentry, timeout, how))
    388			return dentry;
    389	/*
    390	 * Case 3: pseudo direct mount, expire individual leaves
    391	 *	   (autofs-4.1).
    392	 */
    393	} else {
    394		struct dentry *expired;
    395
    396		/* Not a forced expire? */
    397		if (!(how & AUTOFS_EXP_FORCED)) {
    398			/* ref-walk currently on this dentry? */
    399			ino_count = READ_ONCE(ino->count) + 1;
    400			if (d_count(dentry) > ino_count)
    401				return NULL;
    402		}
    403
    404		expired = autofs_check_leaves(mnt, dentry, timeout, how);
    405		if (expired) {
    406			if (expired == dentry)
    407				dput(dentry);
    408			return expired;
    409		}
    410	}
    411	return NULL;
    412}
    413
    414/*
    415 * Find an eligible tree to time-out
    416 * A tree is eligible if :-
    417 *  - it is unused by any user process
    418 *  - it has been unused for exp_timeout time
    419 */
    420static struct dentry *autofs_expire_indirect(struct super_block *sb,
    421					     struct vfsmount *mnt,
    422					     struct autofs_sb_info *sbi,
    423					     unsigned int how)
    424{
    425	unsigned long timeout;
    426	struct dentry *root = sb->s_root;
    427	struct dentry *dentry;
    428	struct dentry *expired;
    429	struct dentry *found;
    430	struct autofs_info *ino;
    431
    432	if (!root)
    433		return NULL;
    434
    435	timeout = sbi->exp_timeout;
    436
    437	dentry = NULL;
    438	while ((dentry = get_next_positive_subdir(dentry, root))) {
    439		spin_lock(&sbi->fs_lock);
    440		ino = autofs_dentry_ino(dentry);
    441		if (ino->flags & AUTOFS_INF_WANT_EXPIRE) {
    442			spin_unlock(&sbi->fs_lock);
    443			continue;
    444		}
    445		spin_unlock(&sbi->fs_lock);
    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 if
    458		 * things have changed.
    459		 */
    460		how &= ~AUTOFS_EXP_LEAVES;
    461		found = should_expire(expired, mnt, timeout, how);
    462		if (found != expired) { // something has changed, continue
    463			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 until
    510		 * 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	else
    584		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 a
    591		 * little easier
    592		 */
    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 nothing
    609 * 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}