diff options
author | Ian Kent <raven@themaw.net> | 2018-06-08 03:11:26 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-08 03:34:39 +0300 |
commit | 8547190490759608dfa51987374ada2ce8a2331d (patch) | |
tree | a03b9638048593648fd1af707178f5c40f6cafce /fs/autofs4/expire.c | |
parent | f7e095f5d113ab3b433c2302f5ea308285d370cb (diff) | |
download | linux-8547190490759608dfa51987374ada2ce8a2331d.tar.xz |
autofs: delete fs/autofs4 source files
Delete the now unused autofs4 module files.
Link: http://lkml.kernel.org/r/152626707391.28589.3553309771262313504.stgit@pluto.themaw.net
Signed-off-by: Ian Kent <raven@themaw.net>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/autofs4/expire.c')
-rw-r--r-- | fs/autofs4/expire.c | 632 |
1 files changed, 0 insertions, 632 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c deleted file mode 100644 index 36f16b67a3bf..000000000000 --- a/fs/autofs4/expire.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> - * Copyright 2001-2006 Ian Kent <raven@themaw.net> - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - */ - -#include "autofs_i.h" - -static unsigned long now; - -/* Check if a dentry can be expired */ -static inline int autofs_can_expire(struct dentry *dentry, - unsigned long timeout, int do_now) -{ - struct autofs_info *ino = autofs_dentry_ino(dentry); - - /* dentry in the process of being deleted */ - if (ino == NULL) - return 0; - - if (!do_now) { - /* Too young to die */ - if (!timeout || time_after(ino->last_used + timeout, now)) - return 0; - } - return 1; -} - -/* Check a mount point for busyness */ -static int autofs_mount_busy(struct vfsmount *mnt, struct dentry *dentry) -{ - 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; - } - - /* 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; -} - -/* - * 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 list_head *next; - struct dentry *q; - - spin_lock(&sbi->lookup_lock); - spin_lock(&root->d_lock); - - if (prev) - next = prev->d_child.next; - else { - prev = dget_dlock(root); - next = prev->d_subdirs.next; - } - -cont: - if (next == &root->d_subdirs) { - spin_unlock(&root->d_lock); - spin_unlock(&sbi->lookup_lock); - dput(prev); - return NULL; - } - - q = list_entry(next, struct dentry, d_child); - - spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); - /* Already gone or negative dentry (under construction) - try next */ - if (!d_count(q) || !simple_positive(q)) { - spin_unlock(&q->d_lock); - next = q->d_child.next; - goto cont; - } - dget_dlock(q); - spin_unlock(&q->d_lock); - 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 list_head *next; - struct dentry *p, *ret; - - if (prev == NULL) - return dget(root); - - spin_lock(&sbi->lookup_lock); -relock: - p = prev; - spin_lock(&p->d_lock); -again: - next = p->d_subdirs.next; - if (next == &p->d_subdirs) { - while (1) { - struct dentry *parent; - - if (p == root) { - spin_unlock(&p->d_lock); - spin_unlock(&sbi->lookup_lock); - dput(prev); - return NULL; - } - - parent = p->d_parent; - if (!spin_trylock(&parent->d_lock)) { - spin_unlock(&p->d_lock); - cpu_relax(); - goto relock; - } - spin_unlock(&p->d_lock); - next = p->d_child.next; - p = parent; - if (next != &parent->d_subdirs) - break; - } - } - ret = list_entry(next, struct dentry, d_child); - - spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED); - /* Negative dentry - try next */ - if (!simple_positive(ret)) { - spin_unlock(&p->d_lock); - lock_set_subclass(&ret->d_lock.dep_map, 0, _RET_IP_); - p = ret; - goto again; - } - dget_dlock(ret); - spin_unlock(&ret->d_lock); - 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, - int do_now) -{ - pr_debug("top %p %pd\n", top, top); - - /* 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, do_now)) - 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, - int do_now) -{ - 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)) { - top_ino->last_used = jiffies; - dput(p); - return 1; - } - } else { - struct autofs_info *ino = autofs_dentry_ino(p); - unsigned int ino_count = atomic_read(&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; - } - } - } - - /* Timeout of a tree mount is ultimately determined by its top dentry */ - if (!autofs_can_expire(top, timeout, do_now)) - return 1; - - return 0; -} - -static struct dentry *autofs_check_leaves(struct vfsmount *mnt, - struct dentry *parent, - unsigned long timeout, - int do_now) -{ - 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)) - continue; - - /* Can we expire this guy */ - if (autofs_can_expire(p, timeout, do_now)) - return p; - } - } - return NULL; -} - -/* Check if we can expire a direct mount (possibly a tree) */ -struct dentry *autofs_expire_direct(struct super_block *sb, - struct vfsmount *mnt, - struct autofs_sb_info *sbi, - int how) -{ - unsigned long timeout; - struct dentry *root = dget(sb->s_root); - int do_now = how & AUTOFS_EXP_IMMEDIATE; - struct autofs_info *ino; - - if (!root) - return NULL; - - now = jiffies; - timeout = sbi->exp_timeout; - - if (!autofs_direct_busy(mnt, root, timeout, do_now)) { - 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, do_now)) { - 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, - int how) -{ - int do_now = how & AUTOFS_EXP_IMMEDIATE; - int exp_leaves = how & AUTOFS_EXP_LEAVES; - 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)) - return NULL; - - /* Can we expire this guy */ - if (autofs_can_expire(dentry, timeout, do_now)) - return dentry; - return NULL; - } - - if (d_really_is_positive(dentry) && d_is_symlink(dentry)) { - pr_debug("checking symlink %p %pd\n", dentry, 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, 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 (!autofs_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 = autofs_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 - * A tree is eligible if :- - * - it is unused by any user process - * - it has been unused for exp_timeout time - */ -struct dentry *autofs_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 dentry *found; - struct autofs_info *ino; - - if (!root) - return NULL; - - now = jiffies; - timeout = sbi->exp_timeout; - - dentry = NULL; - while ((dentry = get_next_positive_subdir(dentry, root))) { - int flags = how; - - 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); - - expired = should_expire(dentry, mnt, timeout, flags); - 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. - */ - flags &= ~AUTOFS_EXP_LEAVES; - found = should_expire(expired, mnt, timeout, how); - if (!found || found != expired) - /* Something has changed, continue */ - 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'; - dput(dentry); - - 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 = now; - ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE); - complete_all(&ino->expire_complete); - spin_unlock(&sbi->fs_lock); - - return ret; -} - -int autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt, - struct autofs_sb_info *sbi, int when) -{ - struct dentry *dentry; - int ret = -EAGAIN; - - if (autofs_type_trigger(sbi->type)) - dentry = autofs_expire_direct(sb, mnt, sbi, when); - else - dentry = autofs_expire_indirect(sb, mnt, sbi, when); - - 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 = now; - 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) -{ - int do_now = 0; - - if (arg && get_user(do_now, arg)) - return -EFAULT; - - return autofs_do_expire_multi(sb, mnt, sbi, do_now); -} - |