diff options
author | Ian Kent <raven@themaw.net> | 2018-06-07 17:11:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-07 17:34:39 -0700 |
commit | 8547190490759608dfa51987374ada2ce8a2331d (patch) | |
tree | a03b9638048593648fd1af707178f5c40f6cafce | |
parent | f7e095f5d113ab3b433c2302f5ea308285d370cb (diff) |
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>
-rw-r--r-- | fs/autofs4/autofs_i.h | 273 | ||||
-rw-r--r-- | fs/autofs4/dev-ioctl.c | 761 | ||||
-rw-r--r-- | fs/autofs4/expire.c | 632 | ||||
-rw-r--r-- | fs/autofs4/init.c | 48 | ||||
-rw-r--r-- | fs/autofs4/inode.c | 375 | ||||
-rw-r--r-- | fs/autofs4/root.c | 942 | ||||
-rw-r--r-- | fs/autofs4/symlink.c | 29 | ||||
-rw-r--r-- | fs/autofs4/waitq.c | 559 |
8 files changed, 0 insertions, 3619 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h deleted file mode 100644 index 9110b66c7ef1..000000000000 --- a/fs/autofs4/autofs_i.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved - * Copyright 2005-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. - */ - -/* Internal header file for autofs */ - -#include <linux/auto_fs.h> -#include <linux/auto_dev-ioctl.h> - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/time.h> -#include <linux/string.h> -#include <linux/wait.h> -#include <linux/sched.h> -#include <linux/mount.h> -#include <linux/namei.h> -#include <linux/uaccess.h> -#include <linux/mutex.h> -#include <linux/spinlock.h> -#include <linux/list.h> -#include <linux/completion.h> -#include <asm/current.h> - -/* This is the range of ioctl() numbers we claim as ours */ -#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY -#define AUTOFS_IOC_COUNT 32 - -#define AUTOFS_DEV_IOCTL_IOC_FIRST (AUTOFS_DEV_IOCTL_VERSION) -#define AUTOFS_DEV_IOCTL_IOC_COUNT \ - (AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD - AUTOFS_DEV_IOCTL_VERSION_CMD) - -#ifdef pr_fmt -#undef pr_fmt -#endif -#define pr_fmt(fmt) KBUILD_MODNAME ":pid:%d:%s: " fmt, current->pid, __func__ - -/* - * Unified info structure. This is pointed to by both the dentry and - * inode structures. Each file in the filesystem has an instance of this - * structure. It holds a reference to the dentry, so dentries are never - * flushed while the file exists. All name lookups are dealt with at the - * dentry level, although the filesystem can interfere in the validation - * process. Readdir is implemented by traversing the dentry lists. - */ -struct autofs_info { - struct dentry *dentry; - struct inode *inode; - - int flags; - - struct completion expire_complete; - - struct list_head active; - int active_count; - - struct list_head expiring; - - struct autofs_sb_info *sbi; - unsigned long last_used; - atomic_t count; - - kuid_t uid; - kgid_t gid; -}; - -#define AUTOFS_INF_EXPIRING (1<<0) /* dentry in the process of expiring */ -#define AUTOFS_INF_WANT_EXPIRE (1<<1) /* the dentry is being considered - * for expiry, so RCU_walk is - * not permitted. If it progresses to - * actual expiry attempt, the flag is - * not cleared when EXPIRING is set - - * in that case it gets cleared only - * when it comes to clearing EXPIRING. - */ -#define AUTOFS_INF_PENDING (1<<2) /* dentry pending mount */ - -struct autofs_wait_queue { - wait_queue_head_t queue; - struct autofs_wait_queue *next; - autofs_wqt_t wait_queue_token; - /* We use the following to see what we are waiting for */ - struct qstr name; - u32 dev; - u64 ino; - kuid_t uid; - kgid_t gid; - pid_t pid; - pid_t tgid; - /* This is for status reporting upon return */ - int status; - unsigned int wait_ctr; -}; - -#define AUTOFS_SBI_MAGIC 0x6d4a556d - -struct autofs_sb_info { - u32 magic; - int pipefd; - struct file *pipe; - struct pid *oz_pgrp; - int catatonic; - int version; - int sub_version; - int min_proto; - int max_proto; - unsigned long exp_timeout; - unsigned int type; - struct super_block *sb; - struct mutex wq_mutex; - struct mutex pipe_mutex; - spinlock_t fs_lock; - struct autofs_wait_queue *queues; /* Wait queue pointer */ - spinlock_t lookup_lock; - struct list_head active_list; - struct list_head expiring_list; - struct rcu_head rcu; -}; - -static inline struct autofs_sb_info *autofs_sbi(struct super_block *sb) -{ - return (struct autofs_sb_info *)(sb->s_fs_info); -} - -static inline struct autofs_info *autofs_dentry_ino(struct dentry *dentry) -{ - return (struct autofs_info *)(dentry->d_fsdata); -} - -/* autofs_oz_mode(): do we see the man behind the curtain? (The - * processes which do manipulations for us in user space sees the raw - * filesystem without "magic".) - */ -static inline int autofs_oz_mode(struct autofs_sb_info *sbi) -{ - return sbi->catatonic || task_pgrp(current) == sbi->oz_pgrp; -} - -struct inode *autofs_get_inode(struct super_block *, umode_t); -void autofs_free_ino(struct autofs_info *); - -/* Expiration */ -int is_autofs_dentry(struct dentry *); -int autofs_expire_wait(const struct path *path, int rcu_walk); -int autofs_expire_run(struct super_block *, struct vfsmount *, - struct autofs_sb_info *, - struct autofs_packet_expire __user *); -int autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt, - struct autofs_sb_info *sbi, int when); -int autofs_expire_multi(struct super_block *, struct vfsmount *, - struct autofs_sb_info *, int __user *); -struct dentry *autofs_expire_direct(struct super_block *sb, - struct vfsmount *mnt, - struct autofs_sb_info *sbi, int how); -struct dentry *autofs_expire_indirect(struct super_block *sb, - struct vfsmount *mnt, - struct autofs_sb_info *sbi, int how); - -/* Device node initialization */ - -int autofs_dev_ioctl_init(void); -void autofs_dev_ioctl_exit(void); - -/* Operations structures */ - -extern const struct inode_operations autofs_symlink_inode_operations; -extern const struct inode_operations autofs_dir_inode_operations; -extern const struct file_operations autofs_dir_operations; -extern const struct file_operations autofs_root_operations; -extern const struct dentry_operations autofs_dentry_operations; - -/* VFS automount flags management functions */ -static inline void __managed_dentry_set_managed(struct dentry *dentry) -{ - dentry->d_flags |= (DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT); -} - -static inline void managed_dentry_set_managed(struct dentry *dentry) -{ - spin_lock(&dentry->d_lock); - __managed_dentry_set_managed(dentry); - spin_unlock(&dentry->d_lock); -} - -static inline void __managed_dentry_clear_managed(struct dentry *dentry) -{ - dentry->d_flags &= ~(DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT); -} - -static inline void managed_dentry_clear_managed(struct dentry *dentry) -{ - spin_lock(&dentry->d_lock); - __managed_dentry_clear_managed(dentry); - spin_unlock(&dentry->d_lock); -} - -/* Initializing function */ - -int autofs_fill_super(struct super_block *, void *, int); -struct autofs_info *autofs_new_ino(struct autofs_sb_info *); -void autofs_clean_ino(struct autofs_info *); - -static inline int autofs_prepare_pipe(struct file *pipe) -{ - if (!(pipe->f_mode & FMODE_CAN_WRITE)) - return -EINVAL; - if (!S_ISFIFO(file_inode(pipe)->i_mode)) - return -EINVAL; - /* We want a packet pipe */ - pipe->f_flags |= O_DIRECT; - return 0; -} - -/* Queue management functions */ - -int autofs_wait(struct autofs_sb_info *, - const struct path *, enum autofs_notify); -int autofs_wait_release(struct autofs_sb_info *, autofs_wqt_t, int); -void autofs_catatonic_mode(struct autofs_sb_info *); - -static inline u32 autofs_get_dev(struct autofs_sb_info *sbi) -{ - return new_encode_dev(sbi->sb->s_dev); -} - -static inline u64 autofs_get_ino(struct autofs_sb_info *sbi) -{ - return d_inode(sbi->sb->s_root)->i_ino; -} - -static inline void __autofs_add_expiring(struct dentry *dentry) -{ - struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb); - struct autofs_info *ino = autofs_dentry_ino(dentry); - - if (ino) { - if (list_empty(&ino->expiring)) - list_add(&ino->expiring, &sbi->expiring_list); - } -} - -static inline void autofs_add_expiring(struct dentry *dentry) -{ - struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb); - struct autofs_info *ino = autofs_dentry_ino(dentry); - - if (ino) { - spin_lock(&sbi->lookup_lock); - if (list_empty(&ino->expiring)) - list_add(&ino->expiring, &sbi->expiring_list); - spin_unlock(&sbi->lookup_lock); - } -} - -static inline void autofs_del_expiring(struct dentry *dentry) -{ - struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb); - struct autofs_info *ino = autofs_dentry_ino(dentry); - - if (ino) { - spin_lock(&sbi->lookup_lock); - if (!list_empty(&ino->expiring)) - list_del_init(&ino->expiring); - spin_unlock(&sbi->lookup_lock); - } -} - -void autofs_kill_sb(struct super_block *); diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c deleted file mode 100644 index a2281ab2b957..000000000000 --- a/fs/autofs4/dev-ioctl.c +++ /dev/null @@ -1,761 +0,0 @@ -/* - * Copyright 2008 Red Hat, Inc. All rights reserved. - * Copyright 2008 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 <linux/module.h> -#include <linux/vmalloc.h> -#include <linux/miscdevice.h> -#include <linux/init.h> -#include <linux/wait.h> -#include <linux/namei.h> -#include <linux/fcntl.h> -#include <linux/file.h> -#include <linux/fdtable.h> -#include <linux/sched.h> -#include <linux/cred.h> -#include <linux/compat.h> -#include <linux/syscalls.h> -#include <linux/magic.h> -#include <linux/dcache.h> -#include <linux/uaccess.h> -#include <linux/slab.h> - -#include "autofs_i.h" - -/* - * This module implements an interface for routing autofs ioctl control - * commands via a miscellaneous device file. - * - * The alternate interface is needed because we need to be able open - * an ioctl file descriptor on an autofs mount that may be covered by - * another mount. This situation arises when starting automount(8) - * or other user space daemon which uses direct mounts or offset - * mounts (used for autofs lazy mount/umount of nested mount trees), - * which have been left busy at at service shutdown. - */ - -typedef int (*ioctl_fn)(struct file *, struct autofs_sb_info *, - struct autofs_dev_ioctl *); - -static int check_name(const char *name) -{ - if (!strchr(name, '/')) - return -EINVAL; - return 0; -} - -/* - * Check a string doesn't overrun the chunk of - * memory we copied from user land. - */ -static int invalid_str(char *str, size_t size) -{ - if (memchr(str, 0, size)) - return 0; - return -EINVAL; -} - -/* - * Check that the user compiled against correct version of autofs - * misc device code. - * - * As well as checking the version compatibility this always copies - * the kernel interface version out. - */ -static int check_dev_ioctl_version(int cmd, struct autofs_dev_ioctl *param) -{ - int err = 0; - - if ((param->ver_major != AUTOFS_DEV_IOCTL_VERSION_MAJOR) || - (param->ver_minor > AUTOFS_DEV_IOCTL_VERSION_MINOR)) { - pr_warn("ioctl control interface version mismatch: " - "kernel(%u.%u), user(%u.%u), cmd(0x%08x)\n", - AUTOFS_DEV_IOCTL_VERSION_MAJOR, - AUTOFS_DEV_IOCTL_VERSION_MINOR, - param->ver_major, param->ver_minor, cmd); - err = -EINVAL; - } - - /* Fill in the kernel version. */ - param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; - param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; - - return err; -} - -/* - * Copy parameter control struct, including a possible path allocated - * at the end of the struct. - */ -static struct autofs_dev_ioctl * -copy_dev_ioctl(struct autofs_dev_ioctl __user *in) -{ - struct autofs_dev_ioctl tmp, *res; - - if (copy_from_user(&tmp, in, AUTOFS_DEV_IOCTL_SIZE)) - return ERR_PTR(-EFAULT); - - if (tmp.size < AUTOFS_DEV_IOCTL_SIZE) - return ERR_PTR(-EINVAL); - - if (tmp.size > AUTOFS_DEV_IOCTL_SIZE + PATH_MAX) - return ERR_PTR(-ENAMETOOLONG); - - res = memdup_user(in, tmp.size); - if (!IS_ERR(res)) - res->size = tmp.size; - - return res; -} - -static inline void free_dev_ioctl(struct autofs_dev_ioctl *param) -{ - kfree(param); -} - -/* - * Check sanity of parameter control fields and if a path is present - * check that it is terminated and contains at least one "/". - */ -static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param) -{ - int err; - - err = check_dev_ioctl_version(cmd, param); - if (err) { - pr_warn("invalid device control module version " - "supplied for cmd(0x%08x)\n", cmd); - goto out; - } - - if (param->size > AUTOFS_DEV_IOCTL_SIZE) { - err = invalid_str(param->path, param->size - AUTOFS_DEV_IOCTL_SIZE); - if (err) { - pr_warn( - "path string terminator missing for cmd(0x%08x)\n", - cmd); - goto out; - } - - err = check_name(param->path); - if (err) { - pr_warn("invalid path supplied for cmd(0x%08x)\n", - cmd); - goto out; - } - } - - err = 0; -out: - return err; -} - -/* - * Get the autofs super block info struct from the file opened on - * the autofs mount point. - */ -static struct autofs_sb_info *autofs_dev_ioctl_sbi(struct file *f) -{ - struct autofs_sb_info *sbi = NULL; - struct inode *inode; - - if (f) { - inode = file_inode(f); - sbi = autofs_sbi(inode->i_sb); - } - return sbi; -} - -/* Return autofs dev ioctl version */ -static int autofs_dev_ioctl_version(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - /* This should have already been set. */ - param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; - param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; - return 0; -} - -/* Return autofs module protocol version */ -static int autofs_dev_ioctl_protover(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - param->protover.version = sbi->version; - return 0; -} - -/* Return autofs module protocol sub version */ -static int autofs_dev_ioctl_protosubver(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - param->protosubver.sub_version = sbi->sub_version; - return 0; -} - -/* Find the topmost mount satisfying test() */ -static int find_autofs_mount(const char *pathname, - struct path *res, - int test(const struct path *path, void *data), - void *data) -{ - struct path path; - int err; - - err = kern_path_mountpoint(AT_FDCWD, pathname, &path, 0); - if (err) - return err; - err = -ENOENT; - while (path.dentry == path.mnt->mnt_root) { - if (path.dentry->d_sb->s_magic == AUTOFS_SUPER_MAGIC) { - if (test(&path, data)) { - path_get(&path); - *res = path; - err = 0; - break; - } - } - if (!follow_up(&path)) - break; - } - path_put(&path); - return err; -} - -static int test_by_dev(const struct path *path, void *p) -{ - return path->dentry->d_sb->s_dev == *(dev_t *)p; -} - -static int test_by_type(const struct path *path, void *p) -{ - struct autofs_info *ino = autofs_dentry_ino(path->dentry); - - return ino && ino->sbi->type & *(unsigned *)p; -} - -/* - * Open a file descriptor on the autofs mount point corresponding - * to the given path and device number (aka. new_encode_dev(sb->s_dev)). - */ -static int autofs_dev_ioctl_open_mountpoint(const char *name, dev_t devid) -{ - int err, fd; - - fd = get_unused_fd_flags(O_CLOEXEC); - if (likely(fd >= 0)) { - struct file *filp; - struct path path; - - err = find_autofs_mount(name, &path, test_by_dev, &devid); - if (err) - goto out; - - filp = dentry_open(&path, O_RDONLY, current_cred()); - path_put(&path); - if (IS_ERR(filp)) { - err = PTR_ERR(filp); - goto out; - } - - fd_install(fd, filp); - } - - return fd; - -out: - put_unused_fd(fd); - return err; -} - -/* Open a file descriptor on an autofs mount point */ -static int autofs_dev_ioctl_openmount(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - const char *path; - dev_t devid; - int err, fd; - - /* param->path has already been checked */ - if (!param->openmount.devid) - return -EINVAL; - - param->ioctlfd = -1; - - path = param->path; - devid = new_decode_dev(param->openmount.devid); - - err = 0; - fd = autofs_dev_ioctl_open_mountpoint(path, devid); - if (unlikely(fd < 0)) { - err = fd; - goto out; - } - - param->ioctlfd = fd; -out: - return err; -} - -/* Close file descriptor allocated above (user can also use close(2)). */ -static int autofs_dev_ioctl_closemount(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - return ksys_close(param->ioctlfd); -} - -/* - * Send "ready" status for an existing wait (either a mount or an expire - * request). - */ -static int autofs_dev_ioctl_ready(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - autofs_wqt_t token; - - token = (autofs_wqt_t) param->ready.token; - return autofs_wait_release(sbi, token, 0); -} - -/* - * Send "fail" status for an existing wait (either a mount or an expire - * request). - */ -static int autofs_dev_ioctl_fail(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - autofs_wqt_t token; - int status; - - token = (autofs_wqt_t) param->fail.token; - status = param->fail.status < 0 ? param->fail.status : -ENOENT; - return autofs_wait_release(sbi, token, status); -} - -/* - * Set the pipe fd for kernel communication to the daemon. - * - * Normally this is set at mount using an option but if we - * are reconnecting to a busy mount then we need to use this - * to tell the autofs mount about the new kernel pipe fd. In - * order to protect mounts against incorrectly setting the - * pipefd we also require that the autofs mount be catatonic. - * - * This also sets the process group id used to identify the - * controlling process (eg. the owning automount(8) daemon). - */ -static int autofs_dev_ioctl_setpipefd(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - int pipefd; - int err = 0; - struct pid *new_pid = NULL; - - if (param->setpipefd.pipefd == -1) - return -EINVAL; - - pipefd = param->setpipefd.pipefd; - - mutex_lock(&sbi->wq_mutex); - if (!sbi->catatonic) { - mutex_unlock(&sbi->wq_mutex); - return -EBUSY; - } else { - struct file *pipe; - - new_pid = get_task_pid(current, PIDTYPE_PGID); - - if (ns_of_pid(new_pid) != ns_of_pid(sbi->oz_pgrp)) { - pr_warn("not allowed to change PID namespace\n"); - err = -EINVAL; - goto out; - } - - pipe = fget(pipefd); - if (!pipe) { - err = -EBADF; - goto out; - } - if (autofs_prepare_pipe(pipe) < 0) { - err = -EPIPE; - fput(pipe); - goto out; - } - swap(sbi->oz_pgrp, new_pid); - sbi->pipefd = pipefd; - sbi->pipe = pipe; - sbi->catatonic = 0; - } -out: - put_pid(new_pid); - mutex_unlock(&sbi->wq_mutex); - return err; -} - -/* - * Make the autofs mount point catatonic, no longer responsive to - * mount requests. Also closes the kernel pipe file descriptor. - */ -static int autofs_dev_ioctl_catatonic(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - autofs_catatonic_mode(sbi); - return 0; -} - -/* Set the autofs mount timeout */ -static int autofs_dev_ioctl_timeout(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - unsigned long timeout; - - timeout = param->timeout.timeout; - param->timeout.timeout = sbi->exp_timeout / HZ; - sbi->exp_timeout = timeout * HZ; - return 0; -} - -/* - * Return the uid and gid of the last request for the mount - * - * When reconstructing an autofs mount tree with active mounts - * we need to re-connect to mounts that may have used the original - * process uid and gid (or string variations of them) for mount - * lookups within the map entry. - */ -static int autofs_dev_ioctl_requester(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - struct autofs_info *ino; - struct path path; - dev_t devid; - int err = -ENOENT; - - if (param->size <= AUTOFS_DEV_IOCTL_SIZE) { - err = -EINVAL; - goto out; - } - - devid = sbi->sb->s_dev; - - param->requester.uid = param->requester.gid = -1; - - err = find_autofs_mount(param->path, &path, test_by_dev, &devid); - if (err) - goto out; - - ino = autofs_dentry_ino(path.dentry); - if (ino) { - err = 0; - autofs_expire_wait(&path, 0); - spin_lock(&sbi->fs_lock); - param->requester.uid = - from_kuid_munged(current_user_ns(), ino->uid); - param->requester.gid = - from_kgid_munged(current_user_ns(), ino->gid); - spin_unlock(&sbi->fs_lock); - } - path_put(&path); -out: - return err; -} - -/* - * Call repeatedly until it returns -EAGAIN, meaning there's nothing - * more that can be done. - */ -static int autofs_dev_ioctl_expire(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - struct vfsmount *mnt; - int how; - - how = param->expire.how; - mnt = fp->f_path.mnt; - - return autofs_do_expire_multi(sbi->sb, mnt, sbi, how); -} - -/* Check if autofs mount point is in use */ -static int autofs_dev_ioctl_askumount(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - param->askumount.may_umount = 0; - if (may_umount(fp->f_path.mnt)) - param->askumount.may_umount = 1; - return 0; -} - -/* - * Check if the given path is a mountpoint. - * - * If we are supplied with the file descriptor of an autofs - * mount we're looking for a specific mount. In this case - * the path is considered a mountpoint if it is itself a - * mountpoint or contains a mount, such as a multi-mount - * without a root mount. In this case we return 1 if the - * path is a mount point and the super magic of the covering - * mount if there is one or 0 if it isn't a mountpoint. - * - * If we aren't supplied with a file descriptor then we - * lookup the path and check if it is the root of a mount. - * If a type is given we are looking for a particular autofs - * mount and if we don't find a match we return fail. If the - * located path is the root of a mount we return 1 along with - * the super magic of the mount or 0 otherwise. - * - * In both cases the the device number (as returned by - * new_encode_dev()) is also returned. - */ -static int autofs_dev_ioctl_ismountpoint(struct file *fp, - struct autofs_sb_info *sbi, - struct autofs_dev_ioctl *param) -{ - struct path path; - const char *name; - unsigned int type; - unsigned int devid, magic; - int err = -ENOENT; - - if (param->size <= AUTOFS_DEV_IOCTL_SIZE) { - err = -EINVAL; - goto out; - } - - name = param->path; - type = param->ismountpoint.in.type; - - param->ismountpoint.out.devid = devid = 0; - param->ismountpoint.out.magic = magic = 0; - - if (!fp || param->ioctlfd == -1) { - if (autofs_type_any(type)) - err = kern_path_mountpoint(AT_FDCWD, - name, &path, LOOKUP_FOLLOW); - else - err = find_autofs_mount(name, &path, - test_by_type, &type); - if (err) - goto out; - devid = new_encode_dev(path.dentry->d_sb->s_dev); - err = 0; - if (path.mnt->mnt_root == path.dentry) { - err = 1; - magic = path.dentry->d_sb->s_magic; - } - } else { - dev_t dev = sbi->sb->s_dev; - - err = find_autofs_mount(name, &path, test_by_dev, &dev); - if (err) - goto out; - - devid = new_encode_dev(dev); - - err = path_has_submounts(&path); - - if (follow_down_one(&path)) - magic = path.dentry->d_sb->s_magic; - } - - param->ismountpoint.out.devid = devid; - param->ismountpoint.out.magic = magic; - path_put(&path); -out: - return err; -} - -/* - * Our range of ioctl numbers isn't 0 based so we need to shift - * the array index by _IOC_NR(AUTOFS_CTL_IOC_FIRST) for the table - * lookup. - */ -#define cmd_idx(cmd) (cmd - _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST)) - -static ioctl_fn lookup_dev_ioctl(unsigned int cmd) -{ - static ioctl_fn _ioctls[] = { - autofs_dev_ioctl_version, - autofs_dev_ioctl_protover, - autofs_dev_ioctl_protosubver, - autofs_dev_ioctl_openmount, - autofs_dev_ioctl_closemount, - autofs_dev_ioctl_ready, - autofs_dev_ioctl_fail, - autofs_dev_ioctl_setpipefd, - autofs_dev_ioctl_catatonic, - autofs_dev_ioctl_timeout, - autofs_dev_ioctl_requester, - autofs_dev_ioctl_expire, - autofs_dev_ioctl_askumount, - autofs_dev_ioctl_ismountpoint, - }; - unsigned int idx = cmd_idx(cmd); - - return (idx >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[idx]; -} - -/* ioctl dispatcher */ -static int _autofs_dev_ioctl(unsigned int command, - struct autofs_dev_ioctl __user *user) -{ - struct autofs_dev_ioctl *param; - struct file *fp; - struct autofs_sb_info *sbi; - unsigned int cmd_first, cmd; - ioctl_fn fn = NULL; - int err = 0; - - cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST); - cmd = _IOC_NR(command); - - if (_IOC_TYPE(command) != _IOC_TYPE(AUTOFS_DEV_IOCTL_IOC_FIRST) || - cmd - cmd_first > AUTOFS_DEV_IOCTL_IOC_COUNT) { - return -ENOTTY; - } - - /* Only root can use ioctls other than AUTOFS_DEV_IOCTL_VERSION_CMD - * and AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD - */ - if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD && - cmd != AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD && - !capable(CAP_SYS_ADMIN)) - return -EPERM; - - /* Copy the parameters into kernel space. */ - param = copy_dev_ioctl(user); - if (IS_ERR(param)) - return PTR_ERR(param); - - err = validate_dev_ioctl(command, param); - if (err) - goto out; - - fn = lookup_dev_ioctl(cmd); - if (!fn) { - pr_warn("unknown command 0x%08x\n", command); - err = -ENOTTY; - goto out; - } - - fp = NULL; - sbi = NULL; - - /* - * For obvious reasons the openmount can't have a file - * descriptor yet. We don't take a reference to the - * file during close to allow for immediate release, - * and the same for retrieving ioctl version. - */ - if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD && - cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD && - cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) { - fp = fget(param->ioctlfd); - if (!fp) { - if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD) - goto cont; - err = -EBADF; - goto out; - } - - sbi = autofs_dev_ioctl_sbi(fp); - if (!sbi || sbi->magic != AUTOFS_SBI_MAGIC) { - err = -EINVAL; - fput(fp); - goto out; - } - - /* - * Admin needs to be able to set the mount catatonic in - * order to be able to perform the re-open. - */ - if (!autofs_oz_mode(sbi) && - cmd != AUTOFS_DEV_IOCTL_CATATONIC_CMD) { - err = -EACCES; - fput(fp); - goto out; - } - } -cont: - err = fn(fp, sbi, param); - - if (fp) - fput(fp); - if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE)) - err = -EFAULT; -out: - free_dev_ioctl(param); - return err; -} - -static long autofs_dev_ioctl(struct file *file, unsigned int command, - unsigned long u) -{ - int err; - - err = _autofs_dev_ioctl(command, (struct autofs_dev_ioctl __user *) u); - return (long) err; -} - -#ifdef CONFIG_COMPAT -static long autofs_dev_ioctl_compat(struct file *file, unsigned int command, - unsigned long u) -{ - return autofs_dev_ioctl(file, command, (unsigned long) compat_ptr(u)); -} -#else -#define autofs_dev_ioctl_compat NULL -#endif - -static const struct file_operations _dev_ioctl_fops = { - .unlocked_ioctl = autofs_dev_ioctl, - .compat_ioctl = autofs_dev_ioctl_compat, - .owner = THIS_MODULE, - .llseek = noop_llseek, -}; - -static struct miscdevice _autofs_dev_ioctl_misc = { - .minor = AUTOFS_MINOR, - .name = AUTOFS_DEVICE_NAME, - .fops = &_dev_ioctl_fops, - .mode = 0644, -}; - -MODULE_ALIAS_MISCDEV(AUTOFS_MINOR); -MODULE_ALIAS("devname:autofs"); - -/* Register/deregister misc character device */ -int __init autofs_dev_ioctl_init(void) -{ - int r; - - r = misc_register(&_autofs_dev_ioctl_misc); - if (r) { - pr_err("misc_register failed for control device\n"); - return r; - } - - return 0; -} - -void autofs_dev_ioctl_exit(void) -{ - misc_deregister(&_autofs_dev_ioctl_misc); -} 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 */ |