18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Copyright 1997-1998 Transmeta Corporation - All Rights Reserved
48c2ecf20Sopenharmony_ci *  Copyright 2005-2006 Ian Kent <raven@themaw.net>
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci/* Internal header file for autofs */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/auto_fs.h>
108c2ecf20Sopenharmony_ci#include <linux/auto_dev-ioctl.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/kernel.h>
138c2ecf20Sopenharmony_ci#include <linux/slab.h>
148c2ecf20Sopenharmony_ci#include <linux/time.h>
158c2ecf20Sopenharmony_ci#include <linux/string.h>
168c2ecf20Sopenharmony_ci#include <linux/wait.h>
178c2ecf20Sopenharmony_ci#include <linux/sched.h>
188c2ecf20Sopenharmony_ci#include <linux/sched/signal.h>
198c2ecf20Sopenharmony_ci#include <linux/mount.h>
208c2ecf20Sopenharmony_ci#include <linux/namei.h>
218c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
228c2ecf20Sopenharmony_ci#include <linux/mutex.h>
238c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
248c2ecf20Sopenharmony_ci#include <linux/list.h>
258c2ecf20Sopenharmony_ci#include <linux/completion.h>
268c2ecf20Sopenharmony_ci#include <linux/file.h>
278c2ecf20Sopenharmony_ci#include <linux/magic.h>
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/* This is the range of ioctl() numbers we claim as ours */
308c2ecf20Sopenharmony_ci#define AUTOFS_IOC_FIRST     AUTOFS_IOC_READY
318c2ecf20Sopenharmony_ci#define AUTOFS_IOC_COUNT     32
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#define AUTOFS_DEV_IOCTL_IOC_FIRST	(AUTOFS_DEV_IOCTL_VERSION)
348c2ecf20Sopenharmony_ci#define AUTOFS_DEV_IOCTL_IOC_COUNT \
358c2ecf20Sopenharmony_ci	(AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD - AUTOFS_DEV_IOCTL_VERSION_CMD)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#ifdef pr_fmt
388c2ecf20Sopenharmony_ci#undef pr_fmt
398c2ecf20Sopenharmony_ci#endif
408c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ":pid:%d:%s: " fmt, current->pid, __func__
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ciextern struct file_system_type autofs_fs_type;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci/*
458c2ecf20Sopenharmony_ci * Unified info structure.  This is pointed to by both the dentry and
468c2ecf20Sopenharmony_ci * inode structures.  Each file in the filesystem has an instance of this
478c2ecf20Sopenharmony_ci * structure.  It holds a reference to the dentry, so dentries are never
488c2ecf20Sopenharmony_ci * flushed while the file exists.  All name lookups are dealt with at the
498c2ecf20Sopenharmony_ci * dentry level, although the filesystem can interfere in the validation
508c2ecf20Sopenharmony_ci * process.  Readdir is implemented by traversing the dentry lists.
518c2ecf20Sopenharmony_ci */
528c2ecf20Sopenharmony_cistruct autofs_info {
538c2ecf20Sopenharmony_ci	struct dentry	*dentry;
548c2ecf20Sopenharmony_ci	struct inode	*inode;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	int		flags;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	struct completion expire_complete;
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	struct list_head active;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	struct list_head expiring;
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	struct autofs_sb_info *sbi;
658c2ecf20Sopenharmony_ci	unsigned long last_used;
668c2ecf20Sopenharmony_ci	int count;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	kuid_t uid;
698c2ecf20Sopenharmony_ci	kgid_t gid;
708c2ecf20Sopenharmony_ci	struct rcu_head rcu;
718c2ecf20Sopenharmony_ci};
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci#define AUTOFS_INF_EXPIRING	(1<<0) /* dentry in the process of expiring */
748c2ecf20Sopenharmony_ci#define AUTOFS_INF_WANT_EXPIRE	(1<<1) /* the dentry is being considered
758c2ecf20Sopenharmony_ci					* for expiry, so RCU_walk is
768c2ecf20Sopenharmony_ci					* not permitted.  If it progresses to
778c2ecf20Sopenharmony_ci					* actual expiry attempt, the flag is
788c2ecf20Sopenharmony_ci					* not cleared when EXPIRING is set -
798c2ecf20Sopenharmony_ci					* in that case it gets cleared only
808c2ecf20Sopenharmony_ci					* when it comes to clearing EXPIRING.
818c2ecf20Sopenharmony_ci					*/
828c2ecf20Sopenharmony_ci#define AUTOFS_INF_PENDING	(1<<2) /* dentry pending mount */
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistruct autofs_wait_queue {
858c2ecf20Sopenharmony_ci	wait_queue_head_t queue;
868c2ecf20Sopenharmony_ci	struct autofs_wait_queue *next;
878c2ecf20Sopenharmony_ci	autofs_wqt_t wait_queue_token;
888c2ecf20Sopenharmony_ci	/* We use the following to see what we are waiting for */
898c2ecf20Sopenharmony_ci	struct qstr name;
908c2ecf20Sopenharmony_ci	u32 dev;
918c2ecf20Sopenharmony_ci	u64 ino;
928c2ecf20Sopenharmony_ci	kuid_t uid;
938c2ecf20Sopenharmony_ci	kgid_t gid;
948c2ecf20Sopenharmony_ci	pid_t pid;
958c2ecf20Sopenharmony_ci	pid_t tgid;
968c2ecf20Sopenharmony_ci	/* This is for status reporting upon return */
978c2ecf20Sopenharmony_ci	int status;
988c2ecf20Sopenharmony_ci	unsigned int wait_ctr;
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci#define AUTOFS_SBI_MAGIC 0x6d4a556d
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci#define AUTOFS_SBI_CATATONIC	0x0001
1048c2ecf20Sopenharmony_ci#define AUTOFS_SBI_STRICTEXPIRE 0x0002
1058c2ecf20Sopenharmony_ci#define AUTOFS_SBI_IGNORE	0x0004
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cistruct autofs_sb_info {
1088c2ecf20Sopenharmony_ci	u32 magic;
1098c2ecf20Sopenharmony_ci	int pipefd;
1108c2ecf20Sopenharmony_ci	struct file *pipe;
1118c2ecf20Sopenharmony_ci	struct pid *oz_pgrp;
1128c2ecf20Sopenharmony_ci	int version;
1138c2ecf20Sopenharmony_ci	int sub_version;
1148c2ecf20Sopenharmony_ci	int min_proto;
1158c2ecf20Sopenharmony_ci	int max_proto;
1168c2ecf20Sopenharmony_ci	unsigned int flags;
1178c2ecf20Sopenharmony_ci	unsigned long exp_timeout;
1188c2ecf20Sopenharmony_ci	unsigned int type;
1198c2ecf20Sopenharmony_ci	struct super_block *sb;
1208c2ecf20Sopenharmony_ci	struct mutex wq_mutex;
1218c2ecf20Sopenharmony_ci	struct mutex pipe_mutex;
1228c2ecf20Sopenharmony_ci	spinlock_t fs_lock;
1238c2ecf20Sopenharmony_ci	struct autofs_wait_queue *queues; /* Wait queue pointer */
1248c2ecf20Sopenharmony_ci	spinlock_t lookup_lock;
1258c2ecf20Sopenharmony_ci	struct list_head active_list;
1268c2ecf20Sopenharmony_ci	struct list_head expiring_list;
1278c2ecf20Sopenharmony_ci	struct rcu_head rcu;
1288c2ecf20Sopenharmony_ci};
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic inline struct autofs_sb_info *autofs_sbi(struct super_block *sb)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	return (struct autofs_sb_info *)(sb->s_fs_info);
1338c2ecf20Sopenharmony_ci}
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_cistatic inline struct autofs_info *autofs_dentry_ino(struct dentry *dentry)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	return (struct autofs_info *)(dentry->d_fsdata);
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci/* autofs_oz_mode(): do we see the man behind the curtain?  (The
1418c2ecf20Sopenharmony_ci * processes which do manipulations for us in user space sees the raw
1428c2ecf20Sopenharmony_ci * filesystem without "magic".)
1438c2ecf20Sopenharmony_ci */
1448c2ecf20Sopenharmony_cistatic inline int autofs_oz_mode(struct autofs_sb_info *sbi)
1458c2ecf20Sopenharmony_ci{
1468c2ecf20Sopenharmony_ci	return ((sbi->flags & AUTOFS_SBI_CATATONIC) ||
1478c2ecf20Sopenharmony_ci		 task_pgrp(current) == sbi->oz_pgrp);
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistruct inode *autofs_get_inode(struct super_block *, umode_t);
1518c2ecf20Sopenharmony_civoid autofs_free_ino(struct autofs_info *);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci/* Expiration */
1548c2ecf20Sopenharmony_ciint is_autofs_dentry(struct dentry *);
1558c2ecf20Sopenharmony_ciint autofs_expire_wait(const struct path *path, int rcu_walk);
1568c2ecf20Sopenharmony_ciint autofs_expire_run(struct super_block *, struct vfsmount *,
1578c2ecf20Sopenharmony_ci		      struct autofs_sb_info *,
1588c2ecf20Sopenharmony_ci		      struct autofs_packet_expire __user *);
1598c2ecf20Sopenharmony_ciint autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
1608c2ecf20Sopenharmony_ci			   struct autofs_sb_info *sbi, unsigned int how);
1618c2ecf20Sopenharmony_ciint autofs_expire_multi(struct super_block *, struct vfsmount *,
1628c2ecf20Sopenharmony_ci			struct autofs_sb_info *, int __user *);
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci/* Device node initialization */
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ciint autofs_dev_ioctl_init(void);
1678c2ecf20Sopenharmony_civoid autofs_dev_ioctl_exit(void);
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci/* Operations structures */
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ciextern const struct inode_operations autofs_symlink_inode_operations;
1728c2ecf20Sopenharmony_ciextern const struct inode_operations autofs_dir_inode_operations;
1738c2ecf20Sopenharmony_ciextern const struct file_operations autofs_dir_operations;
1748c2ecf20Sopenharmony_ciextern const struct file_operations autofs_root_operations;
1758c2ecf20Sopenharmony_ciextern const struct dentry_operations autofs_dentry_operations;
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci/* VFS automount flags management functions */
1788c2ecf20Sopenharmony_cistatic inline void __managed_dentry_set_managed(struct dentry *dentry)
1798c2ecf20Sopenharmony_ci{
1808c2ecf20Sopenharmony_ci	dentry->d_flags |= (DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT);
1818c2ecf20Sopenharmony_ci}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_cistatic inline void managed_dentry_set_managed(struct dentry *dentry)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	spin_lock(&dentry->d_lock);
1868c2ecf20Sopenharmony_ci	__managed_dentry_set_managed(dentry);
1878c2ecf20Sopenharmony_ci	spin_unlock(&dentry->d_lock);
1888c2ecf20Sopenharmony_ci}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_cistatic inline void __managed_dentry_clear_managed(struct dentry *dentry)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	dentry->d_flags &= ~(DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT);
1938c2ecf20Sopenharmony_ci}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic inline void managed_dentry_clear_managed(struct dentry *dentry)
1968c2ecf20Sopenharmony_ci{
1978c2ecf20Sopenharmony_ci	spin_lock(&dentry->d_lock);
1988c2ecf20Sopenharmony_ci	__managed_dentry_clear_managed(dentry);
1998c2ecf20Sopenharmony_ci	spin_unlock(&dentry->d_lock);
2008c2ecf20Sopenharmony_ci}
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci/* Initializing function */
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ciint autofs_fill_super(struct super_block *, void *, int);
2058c2ecf20Sopenharmony_cistruct autofs_info *autofs_new_ino(struct autofs_sb_info *);
2068c2ecf20Sopenharmony_civoid autofs_clean_ino(struct autofs_info *);
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_cistatic inline int autofs_prepare_pipe(struct file *pipe)
2098c2ecf20Sopenharmony_ci{
2108c2ecf20Sopenharmony_ci	if (!(pipe->f_mode & FMODE_CAN_WRITE))
2118c2ecf20Sopenharmony_ci		return -EINVAL;
2128c2ecf20Sopenharmony_ci	if (!S_ISFIFO(file_inode(pipe)->i_mode))
2138c2ecf20Sopenharmony_ci		return -EINVAL;
2148c2ecf20Sopenharmony_ci	/* We want a packet pipe */
2158c2ecf20Sopenharmony_ci	pipe->f_flags |= O_DIRECT;
2168c2ecf20Sopenharmony_ci	/* We don't expect -EAGAIN */
2178c2ecf20Sopenharmony_ci	pipe->f_flags &= ~O_NONBLOCK;
2188c2ecf20Sopenharmony_ci	return 0;
2198c2ecf20Sopenharmony_ci}
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci/* Queue management functions */
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ciint autofs_wait(struct autofs_sb_info *,
2248c2ecf20Sopenharmony_ci		 const struct path *, enum autofs_notify);
2258c2ecf20Sopenharmony_ciint autofs_wait_release(struct autofs_sb_info *, autofs_wqt_t, int);
2268c2ecf20Sopenharmony_civoid autofs_catatonic_mode(struct autofs_sb_info *);
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_cistatic inline u32 autofs_get_dev(struct autofs_sb_info *sbi)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	return new_encode_dev(sbi->sb->s_dev);
2318c2ecf20Sopenharmony_ci}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_cistatic inline u64 autofs_get_ino(struct autofs_sb_info *sbi)
2348c2ecf20Sopenharmony_ci{
2358c2ecf20Sopenharmony_ci	return d_inode(sbi->sb->s_root)->i_ino;
2368c2ecf20Sopenharmony_ci}
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_cistatic inline void __autofs_add_expiring(struct dentry *dentry)
2398c2ecf20Sopenharmony_ci{
2408c2ecf20Sopenharmony_ci	struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb);
2418c2ecf20Sopenharmony_ci	struct autofs_info *ino = autofs_dentry_ino(dentry);
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci	if (ino) {
2448c2ecf20Sopenharmony_ci		if (list_empty(&ino->expiring))
2458c2ecf20Sopenharmony_ci			list_add(&ino->expiring, &sbi->expiring_list);
2468c2ecf20Sopenharmony_ci	}
2478c2ecf20Sopenharmony_ci}
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_cistatic inline void autofs_add_expiring(struct dentry *dentry)
2508c2ecf20Sopenharmony_ci{
2518c2ecf20Sopenharmony_ci	struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb);
2528c2ecf20Sopenharmony_ci	struct autofs_info *ino = autofs_dentry_ino(dentry);
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci	if (ino) {
2558c2ecf20Sopenharmony_ci		spin_lock(&sbi->lookup_lock);
2568c2ecf20Sopenharmony_ci		if (list_empty(&ino->expiring))
2578c2ecf20Sopenharmony_ci			list_add(&ino->expiring, &sbi->expiring_list);
2588c2ecf20Sopenharmony_ci		spin_unlock(&sbi->lookup_lock);
2598c2ecf20Sopenharmony_ci	}
2608c2ecf20Sopenharmony_ci}
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_cistatic inline void autofs_del_expiring(struct dentry *dentry)
2638c2ecf20Sopenharmony_ci{
2648c2ecf20Sopenharmony_ci	struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb);
2658c2ecf20Sopenharmony_ci	struct autofs_info *ino = autofs_dentry_ino(dentry);
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci	if (ino) {
2688c2ecf20Sopenharmony_ci		spin_lock(&sbi->lookup_lock);
2698c2ecf20Sopenharmony_ci		if (!list_empty(&ino->expiring))
2708c2ecf20Sopenharmony_ci			list_del_init(&ino->expiring);
2718c2ecf20Sopenharmony_ci		spin_unlock(&sbi->lookup_lock);
2728c2ecf20Sopenharmony_ci	}
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_civoid autofs_kill_sb(struct super_block *);
276