1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*
28 * Portions Copyright 2007-2013 Apple Inc.
29 */
30
31#ifndef __AUTOFS_KERN_H__
32#define __AUTOFS_KERN_H__
33
34#ifdef __APPLE_API_PRIVATE
35#include <sys/param.h>
36#include <sys/lock.h>
37#include <sys/queue.h>
38#include <sys/attr.h>
39#include <kern/locks.h>
40
41/*
42 * Global lock information, defined in auto_vfsops.c.
43 */
44extern lck_grp_t *autofs_lck_grp;
45extern lck_mtx_t *autofs_nodeid_lock;
46
47/* XXX Get rid of this as soon as sys/malloc.h can be updated to define a real M_AUTOFS */
48#define M_AUTOFS M_TEMP
49
50/* XXX Get rid of this as soon as sys/vnode.h can be updated to define a real VT_AUTOFS */
51#define VT_AUTOFS (VT_OTHER+1)
52
53/*
54 * Tracing macro; expands to nothing for non-debug kernels.
55 * Also, define MACH_ASSERT in debug kernels, so assert() does something.
56 */
57#ifndef DEBUG
58#define AUTOFS_DPRINT(x)
59#else /* DEBUG */
60#define AUTOFS_DPRINT(x)	auto_dprint x
61#ifndef MACH_ASSERT
62#define MACH_ASSERT
63#endif /* MACH_ASSERT */
64#endif /* DEBUG */
65
66extern int (**autofs_vnodeop_p)(void *);
67
68struct action_list;
69
70/*
71 * Per AUTOFS mountpoint information.
72 */
73typedef struct fninfo {
74	lck_rw_t	*fi_rwlock;
75	vnode_t		fi_rootvp;		/* root vnode */
76	char		*fi_path;		/* autofs mountpoint */
77	char 		*fi_map;		/* context/map-name */
78	char		*fi_subdir;		/* subdir within map */
79	char		*fi_key;		/* key to use on direct maps */
80	char		*fi_opts;		/* default mount options */
81	uint32_t	fi_mntflags;		/* Boolean mount options */
82	int		fi_pathlen;		/* autofs mountpoint len */
83	int		fi_maplen;		/* size of context */
84	int		fi_subdirlen;
85	int		fi_keylen;
86	int		fi_optslen;		/* default mount options len */
87	int		fi_flags;
88} fninfo_t;
89
90/*
91 * fi_flags bits:
92 *
93 *	MF_DIRECT:
94 *		- Direct mountpoint if set, indirect otherwise.
95 *
96 *	MF_UNMOUNTING
97 *		- We're in the process of unmounting this, so we should
98 *		  return ENOENT for lookups in the root directory (see
99 *		  auto_control_ioctl() for a reason why this is done)
100 *
101 *	MF_SUBTRIGGER
102 *		- This is a subtrigger mount.
103 */
104#define	MF_DIRECT	0x001
105#define	MF_UNMOUNTING	0x002
106#define	MF_SUBTRIGGER	0x004
107
108/*
109 * We handle both directories and symlinks in autofs.
110 * This is the vnode-type-specific information.
111 */
112
113/*
114 * Directory-specific information - list of entries and number of entries.
115 */
116struct autofs_dir_node {
117	struct fnnode *d_dirents;
118	int	d_direntcnt;		/* count of entries in d_dirents list */
119};
120#define fn_dirents	fn_u.d.d_dirents
121#define fn_direntcnt	fn_u.d.d_direntcnt
122
123/*
124 * Symlink-specific information - contents of symlink.
125 */
126struct autofs_symlink_node {
127	int s_length;
128	char *s_symlinktarget;		/* Dynamically allocated */
129};
130
131#define fn_symlink	fn_u.s.s_symlinktarget
132#define fn_symlinklen	fn_u.s.s_length
133
134/*
135 * The AUTOFS locking scheme:
136 *
137 * The locks:
138 * 	fn_lock: protects the fn_node. It must be grabbed to change any
139 *		 field on the fn_node, except for those protected by
140 *		 fn_rwlock.
141 *
142 * 	fn_rwlock: readers/writers lock to protect the subdirectory and
143 *		   top level list traversal.
144 *		   Protects: fn_dirents
145 *			     fn_direntcnt
146 *			     fn_next
147 *		             fn_linkcnt
148 *                 - Grab readers when checking if certain fn_node exists
149 *                   under fn_dirents.
150 *		   - Grab readers when attempting to reference a node
151 *                   pointed to by fn_dirents, fn_next, and fn_parent.
152 *                 - Grab writers to add a new fnnode under fn_dirents and
153 *		     to remove a node pointed to by fn_dirents or fn_next.
154 *
155 *
156 * The flags:
157 * 	MF_HOMEDIRMOUNT:
158 * 		- A home directory mount is in progress on this node.
159 */
160
161/*
162 * The inode of AUTOFS
163 */
164typedef struct fnnode {
165	char		*fn_name;
166	int		fn_namelen;
167	nlink_t		fn_linkcnt;		/* link count */
168	mode_t		fn_mode;		/* file mode bits */
169	uid_t		fn_uid;			/* owner's uid */
170	int		fn_error;		/* mount/lookup error */
171	ino_t		fn_nodeid;
172	off_t		fn_offset;		/* offset into directory */
173	int		fn_flags;
174	trigger_info_t	*fn_trigger_info;	/* if this is a trigger, here's the trigger info */
175	union {
176		struct autofs_dir_node d;
177		struct autofs_symlink_node s;
178	}		fn_u;
179	vnode_t		fn_vnode;
180	uint32_t	fn_vid;			/* vid of the vnode */
181	vnode_t		fn_parentvp;
182	uint32_t	fn_parentvid;		/* vid of parent's vnode */
183	struct fnnode	*fn_parent;
184	struct fnnode	*fn_next;		/* sibling */
185	lck_rw_t	*fn_rwlock;		/* protects list traversal */
186	lck_mtx_t	*fn_lock;		/* protects the fnnode */
187	struct timeval	fn_crtime;
188	struct timeval	fn_atime;
189	struct timeval	fn_mtime;
190	struct timeval	fn_ctime;
191	struct autofs_globals *fn_globals;	/* global variables */
192	lck_mtx_t	*fn_mnt_lock;		/* protects race between autofs and homedirmounter */
193	uint32_t        fn_restart_cnt;        	/* count of auto_lookup() ERESTART(s)- 17454528*/
194} fnnode_t;
195
196#define vntofn(vp)	((struct fnnode *)(vnode_fsnode(vp)))
197#define	fntovn(fnp)	(((fnp)->fn_vnode))
198#define	vfstofni(mp)	((fninfo_t *)(vfs_fsprivate(mp)))
199
200#define	MF_HOMEDIRMOUNT         0x001	/* Home directory mount in progress */
201#define	MF_HOMEDIRMOUNT_LOCKED	0x002	/* Home directory mount lock taken */
202
203#define	AUTOFS_MODE		0555
204#define	AUTOFS_BLOCKSIZE	1024
205
206struct autofs_globals {
207	fnnode_t		*fng_rootfnnodep;
208	int			fng_fnnode_count;
209	int			fng_printed_not_running_msg;
210	int			fng_verbose;
211	lck_mtx_t		*fng_flush_notification_lock;
212	int			fng_flush_notification_pending;
213};
214
215extern struct vnodeops *auto_vnodeops;
216
217/*
218 * We can't call VFS_ROOT(), so, instead, we directly call our VFS_ROOT()
219 * routine.
220 */
221extern int auto_root(mount_t, vnode_t *, vfs_context_t);
222
223/*
224 * Utility routines
225 */
226extern fnnode_t *auto_search(fnnode_t *, char *, int);
227extern int auto_enter(fnnode_t *, struct componentname *, fnnode_t **);
228extern int auto_wait4unmount_tree(fnnode_t *, vfs_context_t);
229extern int auto_makefnnode(fnnode_t **, int, mount_t,
230	struct componentname *, const char *, vnode_t, int,
231	struct autofs_globals *);
232extern void auto_freefnnode(fnnode_t *, int);
233extern void auto_disconnect(fnnode_t *, fnnode_t *);
234/*PRINTFLIKE2*/
235extern void auto_dprint(int level, const char *fmt, ...)
236	__printflike(2, 3);
237extern void auto_debug_set(int level);
238extern int auto_lookup_aux(struct fninfo *, fnnode_t *, char *, int,
239    vfs_context_t, int *);
240extern int auto_readdir_aux(struct fninfo *, fnnode_t *, off_t, u_int,
241    int64_t *, boolean_t *, byte_buffer *, mach_msg_type_number_t *);
242extern int auto_is_automounter(int);
243extern int auto_is_nowait_process(int);
244extern int auto_is_notrigger_process(int);
245extern int auto_is_homedirmounter_process(vnode_t, int);
246extern int auto_mark_vnode_homedirmount(vnode_t, int, int);
247extern int auto_is_autofs(mount_t);
248extern int auto_nobrowse(vnode_t);
249extern void auto_get_attributes(vnode_t, struct vnode_attr *);
250extern int auto_lookup_request(fninfo_t *, char *, int, char *,
251    vfs_context_t, int *, boolean_t *);
252
253extern void autofs_free_globals(struct autofs_globals *);
254
255extern boolean_t auto_fninfo_lock_shared(fninfo_t *fnip, int pid);
256extern void auto_fninfo_unlock_shared(fninfo_t *fnip, boolean_t have_lock);
257
258#endif /* __APPLE_API_PRIVATE */
259
260#endif	/* __AUTOFS_KERN_H__ */
261