xref: /f-stack/freebsd/sys/mount.h (revision 22ce4aff)
1a9643ea8Slogwang /*-
2*22ce4affSfengbojiang  * SPDX-License-Identifier: BSD-3-Clause
3*22ce4affSfengbojiang  *
4a9643ea8Slogwang  * Copyright (c) 1989, 1991, 1993
5a9643ea8Slogwang  *	The Regents of the University of California.  All rights reserved.
6a9643ea8Slogwang  *
7a9643ea8Slogwang  * Redistribution and use in source and binary forms, with or without
8a9643ea8Slogwang  * modification, are permitted provided that the following conditions
9a9643ea8Slogwang  * are met:
10a9643ea8Slogwang  * 1. Redistributions of source code must retain the above copyright
11a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer.
12a9643ea8Slogwang  * 2. Redistributions in binary form must reproduce the above copyright
13a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer in the
14a9643ea8Slogwang  *    documentation and/or other materials provided with the distribution.
15*22ce4affSfengbojiang  * 3. Neither the name of the University nor the names of its contributors
16a9643ea8Slogwang  *    may be used to endorse or promote products derived from this software
17a9643ea8Slogwang  *    without specific prior written permission.
18a9643ea8Slogwang  *
19a9643ea8Slogwang  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20a9643ea8Slogwang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21a9643ea8Slogwang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22a9643ea8Slogwang  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23a9643ea8Slogwang  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24a9643ea8Slogwang  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25a9643ea8Slogwang  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26a9643ea8Slogwang  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27a9643ea8Slogwang  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28a9643ea8Slogwang  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29a9643ea8Slogwang  * SUCH DAMAGE.
30a9643ea8Slogwang  *
31a9643ea8Slogwang  *	@(#)mount.h	8.21 (Berkeley) 5/20/95
32a9643ea8Slogwang  * $FreeBSD$
33a9643ea8Slogwang  */
34a9643ea8Slogwang 
35a9643ea8Slogwang #ifndef _SYS_MOUNT_H_
36a9643ea8Slogwang #define _SYS_MOUNT_H_
37a9643ea8Slogwang 
38a9643ea8Slogwang #include <sys/ucred.h>
39a9643ea8Slogwang #include <sys/queue.h>
40a9643ea8Slogwang #ifdef _KERNEL
41a9643ea8Slogwang #include <sys/lock.h>
42a9643ea8Slogwang #include <sys/lockmgr.h>
43*22ce4affSfengbojiang #include <sys/tslog.h>
44a9643ea8Slogwang #include <sys/_mutex.h>
45a9643ea8Slogwang #include <sys/_sx.h>
46a9643ea8Slogwang #endif
47a9643ea8Slogwang 
48a9643ea8Slogwang /*
49a9643ea8Slogwang  * NOTE: When changing statfs structure, mount structure, MNT_* flags or
50a9643ea8Slogwang  * MNTK_* flags also update DDB show mount command in vfs_subr.c.
51a9643ea8Slogwang  */
52a9643ea8Slogwang 
53a9643ea8Slogwang typedef struct fsid { int32_t val[2]; } fsid_t;	/* filesystem id type */
54a9643ea8Slogwang 
55*22ce4affSfengbojiang #define fsidcmp(a, b) memcmp((a), (b), sizeof(fsid_t))
56*22ce4affSfengbojiang 
57a9643ea8Slogwang /*
58a9643ea8Slogwang  * File identifier.
59a9643ea8Slogwang  * These are unique per filesystem on a single machine.
60*22ce4affSfengbojiang  *
61*22ce4affSfengbojiang  * Note that the offset of fid_data is 4 bytes, so care must be taken to avoid
62*22ce4affSfengbojiang  * undefined behavior accessing unaligned fields within an embedded struct.
63a9643ea8Slogwang  */
64a9643ea8Slogwang #define	MAXFIDSZ	16
65a9643ea8Slogwang 
66a9643ea8Slogwang struct fid {
67a9643ea8Slogwang 	u_short		fid_len;		/* length of data in bytes */
68a9643ea8Slogwang 	u_short		fid_data0;		/* force longword alignment */
69a9643ea8Slogwang 	char		fid_data[MAXFIDSZ];	/* data (variable length) */
70a9643ea8Slogwang };
71a9643ea8Slogwang 
72a9643ea8Slogwang /*
73a9643ea8Slogwang  * filesystem statistics
74a9643ea8Slogwang  */
75a9643ea8Slogwang #define	MFSNAMELEN	16		/* length of type name including null */
76*22ce4affSfengbojiang #define	MNAMELEN	1024		/* size of on/from name bufs */
77*22ce4affSfengbojiang #define	STATFS_VERSION	0x20140518	/* current version number */
78a9643ea8Slogwang struct statfs {
79a9643ea8Slogwang 	uint32_t f_version;		/* structure version number */
80a9643ea8Slogwang 	uint32_t f_type;		/* type of filesystem */
81a9643ea8Slogwang 	uint64_t f_flags;		/* copy of mount exported flags */
82a9643ea8Slogwang 	uint64_t f_bsize;		/* filesystem fragment size */
83a9643ea8Slogwang 	uint64_t f_iosize;		/* optimal transfer block size */
84a9643ea8Slogwang 	uint64_t f_blocks;		/* total data blocks in filesystem */
85a9643ea8Slogwang 	uint64_t f_bfree;		/* free blocks in filesystem */
86a9643ea8Slogwang 	int64_t	 f_bavail;		/* free blocks avail to non-superuser */
87a9643ea8Slogwang 	uint64_t f_files;		/* total file nodes in filesystem */
88a9643ea8Slogwang 	int64_t	 f_ffree;		/* free nodes avail to non-superuser */
89a9643ea8Slogwang 	uint64_t f_syncwrites;		/* count of sync writes since mount */
90a9643ea8Slogwang 	uint64_t f_asyncwrites;		/* count of async writes since mount */
91a9643ea8Slogwang 	uint64_t f_syncreads;		/* count of sync reads since mount */
92a9643ea8Slogwang 	uint64_t f_asyncreads;		/* count of async reads since mount */
93a9643ea8Slogwang 	uint64_t f_spare[10];		/* unused spare */
94a9643ea8Slogwang 	uint32_t f_namemax;		/* maximum filename length */
95a9643ea8Slogwang 	uid_t	  f_owner;		/* user that mounted the filesystem */
96a9643ea8Slogwang 	fsid_t	  f_fsid;		/* filesystem id */
97a9643ea8Slogwang 	char	  f_charspare[80];	    /* spare string space */
98a9643ea8Slogwang 	char	  f_fstypename[MFSNAMELEN]; /* filesystem type name */
99a9643ea8Slogwang 	char	  f_mntfromname[MNAMELEN];  /* mounted filesystem */
100a9643ea8Slogwang 	char	  f_mntonname[MNAMELEN];    /* directory on which mounted */
101a9643ea8Slogwang };
102a9643ea8Slogwang 
103*22ce4affSfengbojiang #if defined(_WANT_FREEBSD11_STATFS) || defined(_KERNEL)
104*22ce4affSfengbojiang #define	FREEBSD11_STATFS_VERSION	0x20030518 /* current version number */
105*22ce4affSfengbojiang struct freebsd11_statfs {
106*22ce4affSfengbojiang 	uint32_t f_version;		/* structure version number */
107*22ce4affSfengbojiang 	uint32_t f_type;		/* type of filesystem */
108*22ce4affSfengbojiang 	uint64_t f_flags;		/* copy of mount exported flags */
109*22ce4affSfengbojiang 	uint64_t f_bsize;		/* filesystem fragment size */
110*22ce4affSfengbojiang 	uint64_t f_iosize;		/* optimal transfer block size */
111*22ce4affSfengbojiang 	uint64_t f_blocks;		/* total data blocks in filesystem */
112*22ce4affSfengbojiang 	uint64_t f_bfree;		/* free blocks in filesystem */
113*22ce4affSfengbojiang 	int64_t	 f_bavail;		/* free blocks avail to non-superuser */
114*22ce4affSfengbojiang 	uint64_t f_files;		/* total file nodes in filesystem */
115*22ce4affSfengbojiang 	int64_t	 f_ffree;		/* free nodes avail to non-superuser */
116*22ce4affSfengbojiang 	uint64_t f_syncwrites;		/* count of sync writes since mount */
117*22ce4affSfengbojiang 	uint64_t f_asyncwrites;		/* count of async writes since mount */
118*22ce4affSfengbojiang 	uint64_t f_syncreads;		/* count of sync reads since mount */
119*22ce4affSfengbojiang 	uint64_t f_asyncreads;		/* count of async reads since mount */
120*22ce4affSfengbojiang 	uint64_t f_spare[10];		/* unused spare */
121*22ce4affSfengbojiang 	uint32_t f_namemax;		/* maximum filename length */
122*22ce4affSfengbojiang 	uid_t	  f_owner;		/* user that mounted the filesystem */
123*22ce4affSfengbojiang 	fsid_t	  f_fsid;		/* filesystem id */
124*22ce4affSfengbojiang 	char	  f_charspare[80];	/* spare string space */
125*22ce4affSfengbojiang 	char	  f_fstypename[16];	/* filesystem type name */
126*22ce4affSfengbojiang 	char	  f_mntfromname[88];	/* mounted filesystem */
127*22ce4affSfengbojiang 	char	  f_mntonname[88];	/* directory on which mounted */
128*22ce4affSfengbojiang };
129*22ce4affSfengbojiang #endif /* _WANT_FREEBSD11_STATFS || _KERNEL */
130*22ce4affSfengbojiang 
131a9643ea8Slogwang #ifdef _KERNEL
132a9643ea8Slogwang #define	OMFSNAMELEN	16	/* length of fs type name, including null */
133a9643ea8Slogwang #define	OMNAMELEN	(88 - 2 * sizeof(long))	/* size of on/from name bufs */
134a9643ea8Slogwang 
135a9643ea8Slogwang /* XXX getfsstat.2 is out of date with write and read counter changes here. */
136a9643ea8Slogwang /* XXX statfs.2 is out of date with read counter changes here. */
137a9643ea8Slogwang struct ostatfs {
138a9643ea8Slogwang 	long	f_spare2;		/* placeholder */
139a9643ea8Slogwang 	long	f_bsize;		/* fundamental filesystem block size */
140a9643ea8Slogwang 	long	f_iosize;		/* optimal transfer block size */
141a9643ea8Slogwang 	long	f_blocks;		/* total data blocks in filesystem */
142a9643ea8Slogwang 	long	f_bfree;		/* free blocks in fs */
143a9643ea8Slogwang 	long	f_bavail;		/* free blocks avail to non-superuser */
144a9643ea8Slogwang 	long	f_files;		/* total file nodes in filesystem */
145a9643ea8Slogwang 	long	f_ffree;		/* free file nodes in fs */
146a9643ea8Slogwang 	fsid_t	f_fsid;			/* filesystem id */
147a9643ea8Slogwang 	uid_t	f_owner;		/* user that mounted the filesystem */
148a9643ea8Slogwang 	int	f_type;			/* type of filesystem */
149a9643ea8Slogwang 	int	f_flags;		/* copy of mount exported flags */
150a9643ea8Slogwang 	long	f_syncwrites;		/* count of sync writes since mount */
151a9643ea8Slogwang 	long	f_asyncwrites;		/* count of async writes since mount */
152a9643ea8Slogwang 	char	f_fstypename[OMFSNAMELEN]; /* fs type name */
153a9643ea8Slogwang 	char	f_mntonname[OMNAMELEN];	/* directory on which mounted */
154a9643ea8Slogwang 	long	f_syncreads;		/* count of sync reads since mount */
155a9643ea8Slogwang 	long	f_asyncreads;		/* count of async reads since mount */
156a9643ea8Slogwang 	short	f_spares1;		/* unused spare */
157a9643ea8Slogwang 	char	f_mntfromname[OMNAMELEN];/* mounted filesystem */
158a9643ea8Slogwang 	short	f_spares2;		/* unused spare */
159a9643ea8Slogwang 	/*
160a9643ea8Slogwang 	 * XXX on machines where longs are aligned to 8-byte boundaries, there
161a9643ea8Slogwang 	 * is an unnamed int32_t here.  This spare was after the apparent end
162a9643ea8Slogwang 	 * of the struct until we bit off the read counters from f_mntonname.
163a9643ea8Slogwang 	 */
164a9643ea8Slogwang 	long	f_spare[2];		/* unused spare */
165a9643ea8Slogwang };
166a9643ea8Slogwang 
167a9643ea8Slogwang TAILQ_HEAD(vnodelst, vnode);
168a9643ea8Slogwang 
169a9643ea8Slogwang /* Mount options list */
170a9643ea8Slogwang TAILQ_HEAD(vfsoptlist, vfsopt);
171a9643ea8Slogwang struct vfsopt {
172a9643ea8Slogwang 	TAILQ_ENTRY(vfsopt) link;
173a9643ea8Slogwang 	char	*name;
174a9643ea8Slogwang 	void	*value;
175a9643ea8Slogwang 	int	len;
176a9643ea8Slogwang 	int	pos;
177a9643ea8Slogwang 	int	seen;
178a9643ea8Slogwang };
179a9643ea8Slogwang 
180*22ce4affSfengbojiang struct mount_pcpu {
181*22ce4affSfengbojiang 	int		mntp_thread_in_ops;
182*22ce4affSfengbojiang 	int		mntp_ref;
183*22ce4affSfengbojiang 	int		mntp_lockref;
184*22ce4affSfengbojiang 	int		mntp_writeopcount;
185*22ce4affSfengbojiang };
186*22ce4affSfengbojiang 
187*22ce4affSfengbojiang _Static_assert(sizeof(struct mount_pcpu) == 16,
188*22ce4affSfengbojiang     "the struct is allocated from pcpu 16 zone");
189*22ce4affSfengbojiang 
190a9643ea8Slogwang /*
191a9643ea8Slogwang  * Structure per mounted filesystem.  Each mounted filesystem has an
192a9643ea8Slogwang  * array of operations and an instance record.  The filesystems are
193a9643ea8Slogwang  * put on a doubly linked list.
194a9643ea8Slogwang  *
195a9643ea8Slogwang  * Lock reference:
196*22ce4affSfengbojiang  * 	l - mnt_listmtx
197a9643ea8Slogwang  *	m - mountlist_mtx
198a9643ea8Slogwang  *	i - interlock
199a9643ea8Slogwang  *	v - vnode freelist mutex
200a9643ea8Slogwang  *
201a9643ea8Slogwang  * Unmarked fields are considered stable as long as a ref is held.
202a9643ea8Slogwang  *
203a9643ea8Slogwang  */
204a9643ea8Slogwang struct mount {
205*22ce4affSfengbojiang 	int 		mnt_vfs_ops;		/* (i) pending vfs ops */
206*22ce4affSfengbojiang 	int		mnt_kern_flag;		/* (i) kernel only flags */
207*22ce4affSfengbojiang 	uint64_t	mnt_flag;		/* (i) flags shared with user */
208*22ce4affSfengbojiang 	struct mount_pcpu *mnt_pcpu;		/* per-CPU data */
209*22ce4affSfengbojiang 	struct vnode	*mnt_rootvnode;
210*22ce4affSfengbojiang 	struct vnode	*mnt_vnodecovered;	/* vnode we mounted on */
211*22ce4affSfengbojiang 	struct vfsops	*mnt_op;		/* operations on fs */
212*22ce4affSfengbojiang 	struct vfsconf	*mnt_vfc;		/* configuration info */
213*22ce4affSfengbojiang 	struct mtx __aligned(CACHE_LINE_SIZE)	mnt_mtx; /* mount structure interlock */
214a9643ea8Slogwang 	int		mnt_gen;		/* struct mount generation */
215a9643ea8Slogwang #define	mnt_startzero	mnt_list
216a9643ea8Slogwang 	TAILQ_ENTRY(mount) mnt_list;		/* (m) mount list */
217a9643ea8Slogwang 	struct vnode	*mnt_syncer;		/* syncer vnode */
218a9643ea8Slogwang 	int		mnt_ref;		/* (i) Reference count */
219a9643ea8Slogwang 	struct vnodelst	mnt_nvnodelist;		/* (i) list of vnodes */
220a9643ea8Slogwang 	int		mnt_nvnodelistsize;	/* (i) # of vnodes */
221a9643ea8Slogwang 	int		mnt_writeopcount;	/* (i) write syscalls pending */
222a9643ea8Slogwang 	struct vfsoptlist *mnt_opt;		/* current mount options */
223a9643ea8Slogwang 	struct vfsoptlist *mnt_optnew;		/* new options passed to fs */
224a9643ea8Slogwang 	int		mnt_maxsymlinklen;	/* max size of short symlink */
225a9643ea8Slogwang 	struct statfs	mnt_stat;		/* cache of filesystem stats */
226a9643ea8Slogwang 	struct ucred	*mnt_cred;		/* credentials of mounter */
227a9643ea8Slogwang 	void *		mnt_data;		/* private data */
228a9643ea8Slogwang 	time_t		mnt_time;		/* last time written*/
229a9643ea8Slogwang 	int		mnt_iosize_max;		/* max size for clusters, etc */
230a9643ea8Slogwang 	struct netexport *mnt_export;		/* export list */
231a9643ea8Slogwang 	struct label	*mnt_label;		/* MAC label for the fs */
232a9643ea8Slogwang 	u_int		mnt_hashseed;		/* Random seed for vfs_hash */
233a9643ea8Slogwang 	int		mnt_lockref;		/* (i) Lock reference count */
234a9643ea8Slogwang 	int		mnt_secondary_writes;   /* (i) # of secondary writes */
235a9643ea8Slogwang 	int		mnt_secondary_accwrites;/* (i) secondary wr. starts */
236a9643ea8Slogwang 	struct thread	*mnt_susp_owner;	/* (i) thread owning suspension */
237a9643ea8Slogwang #define	mnt_endzero	mnt_gjprovider
238a9643ea8Slogwang 	char		*mnt_gjprovider;	/* gjournal provider name */
239*22ce4affSfengbojiang 	struct mtx	mnt_listmtx;
240*22ce4affSfengbojiang 	struct vnodelst	mnt_lazyvnodelist;	/* (l) list of lazy vnodes */
241*22ce4affSfengbojiang 	int		mnt_lazyvnodelistsize;	/* (l) # of lazy vnodes */
242a9643ea8Slogwang 	struct lock	mnt_explock;		/* vfs_export walkers lock */
243a9643ea8Slogwang 	TAILQ_ENTRY(mount) mnt_upper_link;	/* (m) we in the all uppers */
244a9643ea8Slogwang 	TAILQ_HEAD(, mount) mnt_uppers;		/* (m) upper mounts over us*/
245a9643ea8Slogwang };
246a9643ea8Slogwang 
247a9643ea8Slogwang /*
248a9643ea8Slogwang  * Definitions for MNT_VNODE_FOREACH_ALL.
249a9643ea8Slogwang  */
250a9643ea8Slogwang struct vnode *__mnt_vnode_next_all(struct vnode **mvp, struct mount *mp);
251a9643ea8Slogwang struct vnode *__mnt_vnode_first_all(struct vnode **mvp, struct mount *mp);
252a9643ea8Slogwang void          __mnt_vnode_markerfree_all(struct vnode **mvp, struct mount *mp);
253a9643ea8Slogwang 
254a9643ea8Slogwang #define MNT_VNODE_FOREACH_ALL(vp, mp, mvp)				\
255a9643ea8Slogwang 	for (vp = __mnt_vnode_first_all(&(mvp), (mp));			\
256a9643ea8Slogwang 		(vp) != NULL; vp = __mnt_vnode_next_all(&(mvp), (mp)))
257a9643ea8Slogwang 
258a9643ea8Slogwang #define MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp)				\
259a9643ea8Slogwang 	do {								\
260a9643ea8Slogwang 		MNT_ILOCK(mp);						\
261a9643ea8Slogwang 		__mnt_vnode_markerfree_all(&(mvp), (mp));		\
262a9643ea8Slogwang 		/* MNT_IUNLOCK(mp); -- done in above function */	\
263a9643ea8Slogwang 		mtx_assert(MNT_MTX(mp), MA_NOTOWNED);			\
264a9643ea8Slogwang 	} while (0)
265a9643ea8Slogwang 
266a9643ea8Slogwang /*
267*22ce4affSfengbojiang  * Definitions for MNT_VNODE_FOREACH_LAZY.
268a9643ea8Slogwang  */
269*22ce4affSfengbojiang typedef int mnt_lazy_cb_t(struct vnode *, void *);
270*22ce4affSfengbojiang struct vnode *__mnt_vnode_next_lazy(struct vnode **mvp, struct mount *mp,
271*22ce4affSfengbojiang     mnt_lazy_cb_t *cb, void *cbarg);
272*22ce4affSfengbojiang struct vnode *__mnt_vnode_first_lazy(struct vnode **mvp, struct mount *mp,
273*22ce4affSfengbojiang     mnt_lazy_cb_t *cb, void *cbarg);
274*22ce4affSfengbojiang void          __mnt_vnode_markerfree_lazy(struct vnode **mvp, struct mount *mp);
275a9643ea8Slogwang 
276*22ce4affSfengbojiang #define MNT_VNODE_FOREACH_LAZY(vp, mp, mvp, cb, cbarg)			\
277*22ce4affSfengbojiang 	for (vp = __mnt_vnode_first_lazy(&(mvp), (mp), (cb), (cbarg));	\
278*22ce4affSfengbojiang 		(vp) != NULL; 						\
279*22ce4affSfengbojiang 		vp = __mnt_vnode_next_lazy(&(mvp), (mp), (cb), (cbarg)))
280a9643ea8Slogwang 
281*22ce4affSfengbojiang #define MNT_VNODE_FOREACH_LAZY_ABORT(mp, mvp)				\
282*22ce4affSfengbojiang 	__mnt_vnode_markerfree_lazy(&(mvp), (mp))
283a9643ea8Slogwang 
284a9643ea8Slogwang #define	MNT_ILOCK(mp)	mtx_lock(&(mp)->mnt_mtx)
285a9643ea8Slogwang #define	MNT_ITRYLOCK(mp) mtx_trylock(&(mp)->mnt_mtx)
286a9643ea8Slogwang #define	MNT_IUNLOCK(mp)	mtx_unlock(&(mp)->mnt_mtx)
287a9643ea8Slogwang #define	MNT_MTX(mp)	(&(mp)->mnt_mtx)
288*22ce4affSfengbojiang 
289*22ce4affSfengbojiang #define	MNT_REF(mp)	do {						\
290*22ce4affSfengbojiang 	mtx_assert(MNT_MTX(mp), MA_OWNED);				\
291*22ce4affSfengbojiang 	mp->mnt_ref++;							\
292*22ce4affSfengbojiang } while (0)
293a9643ea8Slogwang #define	MNT_REL(mp)	do {						\
294*22ce4affSfengbojiang 	mtx_assert(MNT_MTX(mp), MA_OWNED);				\
295a9643ea8Slogwang 	(mp)->mnt_ref--;						\
296*22ce4affSfengbojiang 	if ((mp)->mnt_vfs_ops && (mp)->mnt_ref < 0)		\
297*22ce4affSfengbojiang 		vfs_dump_mount_counters(mp);				\
298*22ce4affSfengbojiang 	if ((mp)->mnt_ref == 0 && (mp)->mnt_vfs_ops)		\
299a9643ea8Slogwang 		wakeup((mp));						\
300a9643ea8Slogwang } while (0)
301a9643ea8Slogwang 
302a9643ea8Slogwang #endif /* _KERNEL */
303a9643ea8Slogwang 
304*22ce4affSfengbojiang #if defined(_WANT_MNTOPTNAMES) || defined(_KERNEL)
305*22ce4affSfengbojiang struct mntoptnames {
306*22ce4affSfengbojiang 	uint64_t o_opt;
307*22ce4affSfengbojiang 	const char *o_name;
308*22ce4affSfengbojiang };
309*22ce4affSfengbojiang #define MNTOPT_NAMES							\
310*22ce4affSfengbojiang 	{ MNT_ASYNC,		"asynchronous" },			\
311*22ce4affSfengbojiang 	{ MNT_EXPORTED,		"NFS exported" },			\
312*22ce4affSfengbojiang 	{ MNT_LOCAL,		"local" },				\
313*22ce4affSfengbojiang 	{ MNT_NOATIME,		"noatime" },				\
314*22ce4affSfengbojiang 	{ MNT_NOEXEC,		"noexec" },				\
315*22ce4affSfengbojiang 	{ MNT_NOSUID,		"nosuid" },				\
316*22ce4affSfengbojiang 	{ MNT_NOSYMFOLLOW,	"nosymfollow" },			\
317*22ce4affSfengbojiang 	{ MNT_QUOTA,		"with quotas" },			\
318*22ce4affSfengbojiang 	{ MNT_RDONLY,		"read-only" },				\
319*22ce4affSfengbojiang 	{ MNT_SYNCHRONOUS,	"synchronous" },			\
320*22ce4affSfengbojiang 	{ MNT_UNION,		"union" },				\
321*22ce4affSfengbojiang 	{ MNT_NOCLUSTERR,	"noclusterr" },				\
322*22ce4affSfengbojiang 	{ MNT_NOCLUSTERW,	"noclusterw" },				\
323*22ce4affSfengbojiang 	{ MNT_SUIDDIR,		"suiddir" },				\
324*22ce4affSfengbojiang 	{ MNT_SOFTDEP,		"soft-updates" },			\
325*22ce4affSfengbojiang 	{ MNT_SUJ,		"journaled soft-updates" },		\
326*22ce4affSfengbojiang 	{ MNT_MULTILABEL,	"multilabel" },				\
327*22ce4affSfengbojiang 	{ MNT_ACLS,		"acls" },				\
328*22ce4affSfengbojiang 	{ MNT_NFS4ACLS,		"nfsv4acls" },				\
329*22ce4affSfengbojiang 	{ MNT_GJOURNAL,		"gjournal" },				\
330*22ce4affSfengbojiang 	{ MNT_AUTOMOUNTED,	"automounted" },			\
331*22ce4affSfengbojiang 	{ MNT_VERIFIED,		"verified" },				\
332*22ce4affSfengbojiang 	{ MNT_UNTRUSTED,	"untrusted" },				\
333*22ce4affSfengbojiang 	{ MNT_NOCOVER,		"nocover" },				\
334*22ce4affSfengbojiang 	{ MNT_EMPTYDIR,		"emptydir" },				\
335*22ce4affSfengbojiang 	{ MNT_UPDATE,		"update" },				\
336*22ce4affSfengbojiang 	{ MNT_DELEXPORT,	"delexport" },				\
337*22ce4affSfengbojiang 	{ MNT_RELOAD,		"reload" },				\
338*22ce4affSfengbojiang 	{ MNT_FORCE,		"force" },				\
339*22ce4affSfengbojiang 	{ MNT_SNAPSHOT,		"snapshot" },				\
340*22ce4affSfengbojiang 	{ 0, NULL }
341*22ce4affSfengbojiang #endif
342*22ce4affSfengbojiang 
343a9643ea8Slogwang /*
344a9643ea8Slogwang  * User specifiable flags, stored in mnt_flag.
345a9643ea8Slogwang  */
346a9643ea8Slogwang #define	MNT_RDONLY	0x0000000000000001ULL /* read only filesystem */
347a9643ea8Slogwang #define	MNT_SYNCHRONOUS	0x0000000000000002ULL /* fs written synchronously */
348a9643ea8Slogwang #define	MNT_NOEXEC	0x0000000000000004ULL /* can't exec from filesystem */
349a9643ea8Slogwang #define	MNT_NOSUID	0x0000000000000008ULL /* don't honor setuid fs bits */
350a9643ea8Slogwang #define	MNT_NFS4ACLS	0x0000000000000010ULL /* enable NFS version 4 ACLs */
351a9643ea8Slogwang #define	MNT_UNION	0x0000000000000020ULL /* union with underlying fs */
352a9643ea8Slogwang #define	MNT_ASYNC	0x0000000000000040ULL /* fs written asynchronously */
353a9643ea8Slogwang #define	MNT_SUIDDIR	0x0000000000100000ULL /* special SUID dir handling */
354a9643ea8Slogwang #define	MNT_SOFTDEP	0x0000000000200000ULL /* using soft updates */
355a9643ea8Slogwang #define	MNT_NOSYMFOLLOW	0x0000000000400000ULL /* do not follow symlinks */
356a9643ea8Slogwang #define	MNT_GJOURNAL	0x0000000002000000ULL /* GEOM journal support enabled */
357a9643ea8Slogwang #define	MNT_MULTILABEL	0x0000000004000000ULL /* MAC support for objects */
358a9643ea8Slogwang #define	MNT_ACLS	0x0000000008000000ULL /* ACL support enabled */
359a9643ea8Slogwang #define	MNT_NOATIME	0x0000000010000000ULL /* dont update file access time */
360a9643ea8Slogwang #define	MNT_NOCLUSTERR	0x0000000040000000ULL /* disable cluster read */
361a9643ea8Slogwang #define	MNT_NOCLUSTERW	0x0000000080000000ULL /* disable cluster write */
362a9643ea8Slogwang #define	MNT_SUJ		0x0000000100000000ULL /* using journaled soft updates */
363a9643ea8Slogwang #define	MNT_AUTOMOUNTED	0x0000000200000000ULL /* mounted by automountd(8) */
364*22ce4affSfengbojiang #define	MNT_UNTRUSTED	0x0000000800000000ULL /* filesys metadata untrusted */
365a9643ea8Slogwang 
366a9643ea8Slogwang /*
367a9643ea8Slogwang  * NFS export related mount flags.
368a9643ea8Slogwang  */
369a9643ea8Slogwang #define	MNT_EXRDONLY	0x0000000000000080ULL	/* exported read only */
370a9643ea8Slogwang #define	MNT_EXPORTED	0x0000000000000100ULL	/* filesystem is exported */
371a9643ea8Slogwang #define	MNT_DEFEXPORTED	0x0000000000000200ULL	/* exported to the world */
372a9643ea8Slogwang #define	MNT_EXPORTANON	0x0000000000000400ULL	/* anon uid mapping for all */
373a9643ea8Slogwang #define	MNT_EXKERB	0x0000000000000800ULL	/* exported with Kerberos */
374a9643ea8Slogwang #define	MNT_EXPUBLIC	0x0000000020000000ULL	/* public export (WebNFS) */
375*22ce4affSfengbojiang #define	MNT_EXTLS	0x0000004000000000ULL /* require TLS */
376*22ce4affSfengbojiang #define	MNT_EXTLSCERT	0x0000008000000000ULL /* require TLS with client cert */
377*22ce4affSfengbojiang #define	MNT_EXTLSCERTUSER 0x0000010000000000ULL /* require TLS with user cert */
378a9643ea8Slogwang 
379a9643ea8Slogwang /*
380a9643ea8Slogwang  * Flags set by internal operations,
381a9643ea8Slogwang  * but visible to the user.
382a9643ea8Slogwang  * XXX some of these are not quite right.. (I've never seen the root flag set)
383a9643ea8Slogwang  */
384a9643ea8Slogwang #define	MNT_LOCAL	0x0000000000001000ULL /* filesystem is stored locally */
385a9643ea8Slogwang #define	MNT_QUOTA	0x0000000000002000ULL /* quotas are enabled on fs */
386a9643ea8Slogwang #define	MNT_ROOTFS	0x0000000000004000ULL /* identifies the root fs */
387a9643ea8Slogwang #define	MNT_USER	0x0000000000008000ULL /* mounted by a user */
388a9643ea8Slogwang #define	MNT_IGNORE	0x0000000000800000ULL /* do not show entry in df */
389*22ce4affSfengbojiang #define	MNT_VERIFIED	0x0000000400000000ULL /* filesystem is verified */
390a9643ea8Slogwang 
391a9643ea8Slogwang /*
392a9643ea8Slogwang  * Mask of flags that are visible to statfs().
393a9643ea8Slogwang  * XXX I think that this could now become (~(MNT_CMDFLAGS))
394a9643ea8Slogwang  * but the 'mount' program may need changing to handle this.
395a9643ea8Slogwang  */
396a9643ea8Slogwang #define	MNT_VISFLAGMASK	(MNT_RDONLY	| MNT_SYNCHRONOUS | MNT_NOEXEC	| \
397a9643ea8Slogwang 			MNT_NOSUID	| MNT_UNION	| MNT_SUJ	| \
398a9643ea8Slogwang 			MNT_ASYNC	| MNT_EXRDONLY	| MNT_EXPORTED	| \
399a9643ea8Slogwang 			MNT_DEFEXPORTED	| MNT_EXPORTANON| MNT_EXKERB	| \
400a9643ea8Slogwang 			MNT_LOCAL	| MNT_USER	| MNT_QUOTA	| \
401a9643ea8Slogwang 			MNT_ROOTFS	| MNT_NOATIME	| MNT_NOCLUSTERR| \
402a9643ea8Slogwang 			MNT_NOCLUSTERW	| MNT_SUIDDIR	| MNT_SOFTDEP	| \
403a9643ea8Slogwang 			MNT_IGNORE	| MNT_EXPUBLIC	| MNT_NOSYMFOLLOW | \
404a9643ea8Slogwang 			MNT_GJOURNAL	| MNT_MULTILABEL | MNT_ACLS	| \
405*22ce4affSfengbojiang 			MNT_NFS4ACLS	| MNT_AUTOMOUNTED | MNT_VERIFIED | \
406*22ce4affSfengbojiang 			MNT_UNTRUSTED)
407a9643ea8Slogwang 
408a9643ea8Slogwang /* Mask of flags that can be updated. */
409a9643ea8Slogwang #define	MNT_UPDATEMASK (MNT_NOSUID	| MNT_NOEXEC	| \
410a9643ea8Slogwang 			MNT_SYNCHRONOUS	| MNT_UNION	| MNT_ASYNC	| \
411a9643ea8Slogwang 			MNT_NOATIME | \
412a9643ea8Slogwang 			MNT_NOSYMFOLLOW	| MNT_IGNORE	| \
413a9643ea8Slogwang 			MNT_NOCLUSTERR	| MNT_NOCLUSTERW | MNT_SUIDDIR	| \
414a9643ea8Slogwang 			MNT_ACLS	| MNT_USER	| MNT_NFS4ACLS	| \
415*22ce4affSfengbojiang 			MNT_AUTOMOUNTED | MNT_UNTRUSTED)
416a9643ea8Slogwang 
417a9643ea8Slogwang /*
418a9643ea8Slogwang  * External filesystem command modifier flags.
419a9643ea8Slogwang  * Unmount can use the MNT_FORCE flag.
420a9643ea8Slogwang  * XXX: These are not STATES and really should be somewhere else.
421a9643ea8Slogwang  * XXX: MNT_BYFSID and MNT_NONBUSY collide with MNT_ACLS and MNT_MULTILABEL,
422a9643ea8Slogwang  *      but because MNT_ACLS and MNT_MULTILABEL are only used for mount(2),
423a9643ea8Slogwang  *      and MNT_BYFSID and MNT_NONBUSY are only used for unmount(2),
424a9643ea8Slogwang  *      it's harmless.
425a9643ea8Slogwang  */
426a9643ea8Slogwang #define	MNT_UPDATE	0x0000000000010000ULL /* not real mount, just update */
427a9643ea8Slogwang #define	MNT_DELEXPORT	0x0000000000020000ULL /* delete export host lists */
428a9643ea8Slogwang #define	MNT_RELOAD	0x0000000000040000ULL /* reload filesystem data */
429a9643ea8Slogwang #define	MNT_FORCE	0x0000000000080000ULL /* force unmount or readonly */
430a9643ea8Slogwang #define	MNT_SNAPSHOT	0x0000000001000000ULL /* snapshot the filesystem */
431a9643ea8Slogwang #define	MNT_NONBUSY	0x0000000004000000ULL /* check vnode use counts. */
432a9643ea8Slogwang #define	MNT_BYFSID	0x0000000008000000ULL /* specify filesystem by ID. */
433*22ce4affSfengbojiang #define	MNT_NOCOVER	0x0000001000000000ULL /* Do not cover a mount point */
434*22ce4affSfengbojiang #define	MNT_EMPTYDIR	0x0000002000000000ULL /* Only mount on empty dir */
435a9643ea8Slogwang #define MNT_CMDFLAGS   (MNT_UPDATE	| MNT_DELEXPORT	| MNT_RELOAD	| \
436a9643ea8Slogwang 			MNT_FORCE	| MNT_SNAPSHOT	| MNT_NONBUSY	| \
437*22ce4affSfengbojiang 			MNT_BYFSID	| MNT_NOCOVER	| MNT_EMPTYDIR)
438a9643ea8Slogwang /*
439a9643ea8Slogwang  * Internal filesystem control flags stored in mnt_kern_flag.
440a9643ea8Slogwang  *
441*22ce4affSfengbojiang  * MNTK_UNMOUNT locks the mount entry so that name lookup cannot
442*22ce4affSfengbojiang  * proceed past the mount point.  This keeps the subtree stable during
443*22ce4affSfengbojiang  * mounts and unmounts.  When non-forced unmount flushes all vnodes
444*22ce4affSfengbojiang  * from the mp queue, the MNTK_UNMOUNT flag prevents insmntque() from
445*22ce4affSfengbojiang  * queueing new vnodes.
446a9643ea8Slogwang  *
447a9643ea8Slogwang  * MNTK_UNMOUNTF permits filesystems to detect a forced unmount while
448a9643ea8Slogwang  * dounmount() is still waiting to lock the mountpoint. This allows
449a9643ea8Slogwang  * the filesystem to cancel operations that might otherwise deadlock
450a9643ea8Slogwang  * with the unmount attempt (used by NFS).
451a9643ea8Slogwang  */
452a9643ea8Slogwang #define MNTK_UNMOUNTF	0x00000001	/* forced unmount in progress */
453a9643ea8Slogwang #define MNTK_ASYNC	0x00000002	/* filtered async flag */
454a9643ea8Slogwang #define MNTK_SOFTDEP	0x00000004	/* async disabled by softdep */
455*22ce4affSfengbojiang #define MNTK_NOMSYNC	0x00000008	/* don't do msync */
456a9643ea8Slogwang #define	MNTK_DRAINING	0x00000010	/* lock draining is happening */
457a9643ea8Slogwang #define	MNTK_REFEXPIRE	0x00000020	/* refcount expiring is happening */
458a9643ea8Slogwang #define MNTK_EXTENDED_SHARED	0x00000040 /* Allow shared locking for more ops */
459a9643ea8Slogwang #define	MNTK_SHARED_WRITES	0x00000080 /* Allow shared locking for writes */
460a9643ea8Slogwang #define	MNTK_NO_IOPF	0x00000100	/* Disallow page faults during reads
461a9643ea8Slogwang 					   and writes. Filesystem shall properly
462a9643ea8Slogwang 					   handle i/o state on EFAULT. */
463a9643ea8Slogwang #define	MNTK_VGONE_UPPER	0x00000200
464a9643ea8Slogwang #define	MNTK_VGONE_WAITER	0x00000400
465a9643ea8Slogwang #define	MNTK_LOOKUP_EXCL_DOTDOT	0x00000800
466a9643ea8Slogwang #define	MNTK_MARKER		0x00001000
467a9643ea8Slogwang #define	MNTK_UNMAPPED_BUFS	0x00002000
468a9643ea8Slogwang #define	MNTK_USES_BCACHE	0x00004000 /* FS uses the buffer cache. */
469*22ce4affSfengbojiang #define	MNTK_TEXT_REFS		0x00008000 /* Keep use ref for text */
470*22ce4affSfengbojiang #define	MNTK_VMSETSIZE_BUG	0x00010000
471*22ce4affSfengbojiang #define	MNTK_UNIONFS	0x00020000	/* A hack for F_ISUNIONSTACK */
472*22ce4affSfengbojiang #define	MNTK_FPLOOKUP	0x00040000	/* fast path lookup is supported */
473*22ce4affSfengbojiang #define	MNTK_SUSPEND_ALL	0x00080000 /* Suspended by all-fs suspension */
474a9643ea8Slogwang #define MNTK_NOASYNC	0x00800000	/* disable async */
475a9643ea8Slogwang #define MNTK_UNMOUNT	0x01000000	/* unmount in progress */
476a9643ea8Slogwang #define	MNTK_MWAIT	0x02000000	/* waiting for unmount to finish */
477a9643ea8Slogwang #define	MNTK_SUSPEND	0x08000000	/* request write suspension */
478a9643ea8Slogwang #define	MNTK_SUSPEND2	0x04000000	/* block secondary writes */
479a9643ea8Slogwang #define	MNTK_SUSPENDED	0x10000000	/* write operations are suspended */
480*22ce4affSfengbojiang #define	MNTK_NULL_NOCACHE	0x20000000 /* auto disable cache for nullfs
481*22ce4affSfengbojiang 					      mounts over this fs */
482a9643ea8Slogwang #define MNTK_LOOKUP_SHARED	0x40000000 /* FS supports shared lock lookups */
483a9643ea8Slogwang #define	MNTK_NOKNOTE	0x80000000	/* Don't send KNOTEs from VOP hooks */
484a9643ea8Slogwang 
485a9643ea8Slogwang #ifdef _KERNEL
486a9643ea8Slogwang static inline int
MNT_SHARED_WRITES(struct mount * mp)487a9643ea8Slogwang MNT_SHARED_WRITES(struct mount *mp)
488a9643ea8Slogwang {
489a9643ea8Slogwang 
490a9643ea8Slogwang 	return (mp != NULL && (mp->mnt_kern_flag & MNTK_SHARED_WRITES) != 0);
491a9643ea8Slogwang }
492a9643ea8Slogwang 
493a9643ea8Slogwang static inline int
MNT_EXTENDED_SHARED(struct mount * mp)494a9643ea8Slogwang MNT_EXTENDED_SHARED(struct mount *mp)
495a9643ea8Slogwang {
496a9643ea8Slogwang 
497a9643ea8Slogwang 	return (mp != NULL && (mp->mnt_kern_flag & MNTK_EXTENDED_SHARED) != 0);
498a9643ea8Slogwang }
499a9643ea8Slogwang #endif
500a9643ea8Slogwang 
501a9643ea8Slogwang /*
502a9643ea8Slogwang  * Sysctl CTL_VFS definitions.
503a9643ea8Slogwang  *
504a9643ea8Slogwang  * Second level identifier specifies which filesystem. Second level
505a9643ea8Slogwang  * identifier VFS_VFSCONF returns information about all filesystems.
506a9643ea8Slogwang  * Second level identifier VFS_GENERIC is non-terminal.
507a9643ea8Slogwang  */
508a9643ea8Slogwang #define	VFS_VFSCONF		0	/* get configured filesystems */
509a9643ea8Slogwang #define	VFS_GENERIC		0	/* generic filesystem information */
510a9643ea8Slogwang /*
511a9643ea8Slogwang  * Third level identifiers for VFS_GENERIC are given below; third
512a9643ea8Slogwang  * level identifiers for specific filesystems are given in their
513a9643ea8Slogwang  * mount specific header files.
514a9643ea8Slogwang  */
515a9643ea8Slogwang #define VFS_MAXTYPENUM	1	/* int: highest defined filesystem type */
516a9643ea8Slogwang #define VFS_CONF	2	/* struct: vfsconf for filesystem given
517a9643ea8Slogwang 				   as next argument */
518a9643ea8Slogwang 
519a9643ea8Slogwang /*
520a9643ea8Slogwang  * Flags for various system call interfaces.
521a9643ea8Slogwang  *
522a9643ea8Slogwang  * waitfor flags to vfs_sync() and getfsstat()
523a9643ea8Slogwang  */
524a9643ea8Slogwang #define MNT_WAIT	1	/* synchronously wait for I/O to complete */
525a9643ea8Slogwang #define MNT_NOWAIT	2	/* start all I/O, but do not wait for it */
526a9643ea8Slogwang #define MNT_LAZY	3	/* push data not written by filesystem syncer */
527a9643ea8Slogwang #define MNT_SUSPEND	4	/* Suspend file system after sync */
528a9643ea8Slogwang 
529a9643ea8Slogwang /*
530a9643ea8Slogwang  * Generic file handle
531a9643ea8Slogwang  */
532a9643ea8Slogwang struct fhandle {
533a9643ea8Slogwang 	fsid_t	fh_fsid;	/* Filesystem id of mount point */
534a9643ea8Slogwang 	struct	fid fh_fid;	/* Filesys specific id */
535a9643ea8Slogwang };
536a9643ea8Slogwang typedef struct fhandle	fhandle_t;
537a9643ea8Slogwang 
538a9643ea8Slogwang /*
539a9643ea8Slogwang  * Old export arguments without security flavor list
540a9643ea8Slogwang  */
541a9643ea8Slogwang struct oexport_args {
542a9643ea8Slogwang 	int	ex_flags;		/* export related flags */
543a9643ea8Slogwang 	uid_t	ex_root;		/* mapping for root uid */
544a9643ea8Slogwang 	struct	xucred ex_anon;		/* mapping for anonymous user */
545a9643ea8Slogwang 	struct	sockaddr *ex_addr;	/* net address to which exported */
546a9643ea8Slogwang 	u_char	ex_addrlen;		/* and the net address length */
547a9643ea8Slogwang 	struct	sockaddr *ex_mask;	/* mask of valid bits in saddr */
548a9643ea8Slogwang 	u_char	ex_masklen;		/* and the smask length */
549a9643ea8Slogwang 	char	*ex_indexfile;		/* index file for WebNFS URLs */
550a9643ea8Slogwang };
551a9643ea8Slogwang 
552a9643ea8Slogwang /*
553*22ce4affSfengbojiang  * Not quite so old export arguments with 32bit ex_flags and xucred ex_anon.
554a9643ea8Slogwang  */
555a9643ea8Slogwang #define	MAXSECFLAVORS	5
556*22ce4affSfengbojiang struct o2export_args {
557a9643ea8Slogwang 	int	ex_flags;		/* export related flags */
558a9643ea8Slogwang 	uid_t	ex_root;		/* mapping for root uid */
559a9643ea8Slogwang 	struct	xucred ex_anon;		/* mapping for anonymous user */
560a9643ea8Slogwang 	struct	sockaddr *ex_addr;	/* net address to which exported */
561a9643ea8Slogwang 	u_char	ex_addrlen;		/* and the net address length */
562a9643ea8Slogwang 	struct	sockaddr *ex_mask;	/* mask of valid bits in saddr */
563a9643ea8Slogwang 	u_char	ex_masklen;		/* and the smask length */
564a9643ea8Slogwang 	char	*ex_indexfile;		/* index file for WebNFS URLs */
565a9643ea8Slogwang 	int	ex_numsecflavors;	/* security flavor count */
566a9643ea8Slogwang 	int	ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
567a9643ea8Slogwang };
568a9643ea8Slogwang 
569a9643ea8Slogwang /*
570*22ce4affSfengbojiang  * Export arguments for local filesystem mount calls.
571*22ce4affSfengbojiang  */
572*22ce4affSfengbojiang struct export_args {
573*22ce4affSfengbojiang 	uint64_t ex_flags;		/* export related flags */
574*22ce4affSfengbojiang 	uid_t	ex_root;		/* mapping for root uid */
575*22ce4affSfengbojiang 	uid_t	ex_uid;			/* mapping for anonymous user */
576*22ce4affSfengbojiang 	int	ex_ngroups;
577*22ce4affSfengbojiang 	gid_t	*ex_groups;
578*22ce4affSfengbojiang 	struct	sockaddr *ex_addr;	/* net address to which exported */
579*22ce4affSfengbojiang 	u_char	ex_addrlen;		/* and the net address length */
580*22ce4affSfengbojiang 	struct	sockaddr *ex_mask;	/* mask of valid bits in saddr */
581*22ce4affSfengbojiang 	u_char	ex_masklen;		/* and the smask length */
582*22ce4affSfengbojiang 	char	*ex_indexfile;		/* index file for WebNFS URLs */
583*22ce4affSfengbojiang 	int	ex_numsecflavors;	/* security flavor count */
584*22ce4affSfengbojiang 	int	ex_secflavors[MAXSECFLAVORS]; /* list of security flavors */
585*22ce4affSfengbojiang };
586*22ce4affSfengbojiang 
587*22ce4affSfengbojiang /*
588a9643ea8Slogwang  * Structure holding information for a publicly exported filesystem
589a9643ea8Slogwang  * (WebNFS). Currently the specs allow just for one such filesystem.
590a9643ea8Slogwang  */
591a9643ea8Slogwang struct nfs_public {
592a9643ea8Slogwang 	int		np_valid;	/* Do we hold valid information */
593a9643ea8Slogwang 	fhandle_t	np_handle;	/* Filehandle for pub fs (internal) */
594a9643ea8Slogwang 	struct mount	*np_mount;	/* Mountpoint of exported fs */
595a9643ea8Slogwang 	char		*np_index;	/* Index file */
596a9643ea8Slogwang };
597a9643ea8Slogwang 
598a9643ea8Slogwang /*
599a9643ea8Slogwang  * Filesystem configuration information. One of these exists for each
600a9643ea8Slogwang  * type of filesystem supported by the kernel. These are searched at
601a9643ea8Slogwang  * mount time to identify the requested filesystem.
602a9643ea8Slogwang  *
603a9643ea8Slogwang  * XXX: Never change the first two arguments!
604a9643ea8Slogwang  */
605a9643ea8Slogwang struct vfsconf {
606a9643ea8Slogwang 	u_int	vfc_version;		/* ABI version number */
607a9643ea8Slogwang 	char	vfc_name[MFSNAMELEN];	/* filesystem type name */
608a9643ea8Slogwang 	struct	vfsops *vfc_vfsops;	/* filesystem operations vector */
609*22ce4affSfengbojiang 	struct	vfsops *vfc_vfsops_sd;	/* ... signal-deferred */
610a9643ea8Slogwang 	int	vfc_typenum;		/* historic filesystem type number */
611a9643ea8Slogwang 	int	vfc_refcount;		/* number mounted of this type */
612a9643ea8Slogwang 	int	vfc_flags;		/* permanent flags */
613*22ce4affSfengbojiang 	int	vfc_prison_flag;	/* prison allow.mount.* flag */
614a9643ea8Slogwang 	struct	vfsoptdecl *vfc_opts;	/* mount options */
615a9643ea8Slogwang 	TAILQ_ENTRY(vfsconf) vfc_list;	/* list of vfscons */
616a9643ea8Slogwang };
617a9643ea8Slogwang 
618a9643ea8Slogwang /* Userland version of the struct vfsconf. */
619a9643ea8Slogwang struct xvfsconf {
620a9643ea8Slogwang 	struct	vfsops *vfc_vfsops;	/* filesystem operations vector */
621a9643ea8Slogwang 	char	vfc_name[MFSNAMELEN];	/* filesystem type name */
622a9643ea8Slogwang 	int	vfc_typenum;		/* historic filesystem type number */
623a9643ea8Slogwang 	int	vfc_refcount;		/* number mounted of this type */
624a9643ea8Slogwang 	int	vfc_flags;		/* permanent flags */
625a9643ea8Slogwang 	struct	vfsconf *vfc_next;	/* next in list */
626a9643ea8Slogwang };
627a9643ea8Slogwang 
628a9643ea8Slogwang #ifndef BURN_BRIDGES
629a9643ea8Slogwang struct ovfsconf {
630a9643ea8Slogwang 	void	*vfc_vfsops;
631a9643ea8Slogwang 	char	vfc_name[32];
632a9643ea8Slogwang 	int	vfc_index;
633a9643ea8Slogwang 	int	vfc_refcount;
634a9643ea8Slogwang 	int	vfc_flags;
635a9643ea8Slogwang };
636a9643ea8Slogwang #endif
637a9643ea8Slogwang 
638a9643ea8Slogwang /*
639a9643ea8Slogwang  * NB: these flags refer to IMPLEMENTATION properties, not properties of
640a9643ea8Slogwang  * any actual mounts; i.e., it does not make sense to change the flags.
641a9643ea8Slogwang  */
642a9643ea8Slogwang #define	VFCF_STATIC	0x00010000	/* statically compiled into kernel */
643a9643ea8Slogwang #define	VFCF_NETWORK	0x00020000	/* may get data over the network */
644a9643ea8Slogwang #define	VFCF_READONLY	0x00040000	/* writes are not implemented */
645a9643ea8Slogwang #define	VFCF_SYNTHETIC	0x00080000	/* data does not represent real files */
646a9643ea8Slogwang #define	VFCF_LOOPBACK	0x00100000	/* aliases some other mounted FS */
647a9643ea8Slogwang #define	VFCF_UNICODE	0x00200000	/* stores file names as Unicode */
648a9643ea8Slogwang #define	VFCF_JAIL	0x00400000	/* can be mounted from within a jail */
649a9643ea8Slogwang #define	VFCF_DELEGADMIN	0x00800000	/* supports delegated administration */
650*22ce4affSfengbojiang #define	VFCF_SBDRY	0x01000000	/* Stop at Boundary: defer stop requests
651*22ce4affSfengbojiang 					   to kernel->user (AST) transition */
652a9643ea8Slogwang 
653a9643ea8Slogwang typedef uint32_t fsctlop_t;
654a9643ea8Slogwang 
655a9643ea8Slogwang struct vfsidctl {
656a9643ea8Slogwang 	int		vc_vers;	/* should be VFSIDCTL_VERS1 (below) */
657a9643ea8Slogwang 	fsid_t		vc_fsid;	/* fsid to operate on */
658a9643ea8Slogwang 	char		vc_fstypename[MFSNAMELEN];
659a9643ea8Slogwang 					/* type of fs 'nfs' or '*' */
660a9643ea8Slogwang 	fsctlop_t	vc_op;		/* operation VFS_CTL_* (below) */
661a9643ea8Slogwang 	void		*vc_ptr;	/* pointer to data structure */
662a9643ea8Slogwang 	size_t		vc_len;		/* sizeof said structure */
663a9643ea8Slogwang 	u_int32_t	vc_spare[12];	/* spare (must be zero) */
664a9643ea8Slogwang };
665a9643ea8Slogwang 
666a9643ea8Slogwang /* vfsidctl API version. */
667a9643ea8Slogwang #define VFS_CTL_VERS1	0x01
668a9643ea8Slogwang 
669a9643ea8Slogwang /*
670a9643ea8Slogwang  * New style VFS sysctls, do not reuse/conflict with the namespace for
671a9643ea8Slogwang  * private sysctls.
672a9643ea8Slogwang  * All "global" sysctl ops have the 33rd bit set:
673a9643ea8Slogwang  * 0x...1....
674a9643ea8Slogwang  * Private sysctl ops should have the 33rd bit unset.
675a9643ea8Slogwang  */
676a9643ea8Slogwang #define VFS_CTL_QUERY	0x00010001	/* anything wrong? (vfsquery) */
677a9643ea8Slogwang #define VFS_CTL_TIMEO	0x00010002	/* set timeout for vfs notification */
678a9643ea8Slogwang #define VFS_CTL_NOLOCKS	0x00010003	/* disable file locking */
679a9643ea8Slogwang 
680a9643ea8Slogwang struct vfsquery {
681a9643ea8Slogwang 	u_int32_t	vq_flags;
682a9643ea8Slogwang 	u_int32_t	vq_spare[31];
683a9643ea8Slogwang };
684a9643ea8Slogwang 
685a9643ea8Slogwang /* vfsquery flags */
686a9643ea8Slogwang #define VQ_NOTRESP	0x0001	/* server down */
687a9643ea8Slogwang #define VQ_NEEDAUTH	0x0002	/* server bad auth */
688a9643ea8Slogwang #define VQ_LOWDISK	0x0004	/* we're low on space */
689a9643ea8Slogwang #define VQ_MOUNT	0x0008	/* new filesystem arrived */
690a9643ea8Slogwang #define VQ_UNMOUNT	0x0010	/* filesystem has left */
691a9643ea8Slogwang #define VQ_DEAD		0x0020	/* filesystem is dead, needs force unmount */
692a9643ea8Slogwang #define VQ_ASSIST	0x0040	/* filesystem needs assistance from external
693a9643ea8Slogwang 				   program */
694a9643ea8Slogwang #define VQ_NOTRESPLOCK	0x0080	/* server lockd down */
695a9643ea8Slogwang #define VQ_FLAG0100	0x0100	/* placeholder */
696a9643ea8Slogwang #define VQ_FLAG0200	0x0200	/* placeholder */
697a9643ea8Slogwang #define VQ_FLAG0400	0x0400	/* placeholder */
698a9643ea8Slogwang #define VQ_FLAG0800	0x0800	/* placeholder */
699a9643ea8Slogwang #define VQ_FLAG1000	0x1000	/* placeholder */
700a9643ea8Slogwang #define VQ_FLAG2000	0x2000	/* placeholder */
701a9643ea8Slogwang #define VQ_FLAG4000	0x4000	/* placeholder */
702a9643ea8Slogwang #define VQ_FLAG8000	0x8000	/* placeholder */
703a9643ea8Slogwang 
704a9643ea8Slogwang #ifdef _KERNEL
705a9643ea8Slogwang /* Point a sysctl request at a vfsidctl's data. */
706a9643ea8Slogwang #define VCTLTOREQ(vc, req)						\
707a9643ea8Slogwang 	do {								\
708a9643ea8Slogwang 		(req)->newptr = (vc)->vc_ptr;				\
709a9643ea8Slogwang 		(req)->newlen = (vc)->vc_len;				\
710a9643ea8Slogwang 		(req)->newidx = 0;					\
711a9643ea8Slogwang 	} while (0)
712a9643ea8Slogwang #endif
713a9643ea8Slogwang 
714a9643ea8Slogwang struct iovec;
715a9643ea8Slogwang struct uio;
716a9643ea8Slogwang 
717a9643ea8Slogwang #ifdef _KERNEL
718a9643ea8Slogwang 
719a9643ea8Slogwang /*
720a9643ea8Slogwang  * vfs_busy specific flags and mask.
721a9643ea8Slogwang  */
722a9643ea8Slogwang #define	MBF_NOWAIT	0x01
723a9643ea8Slogwang #define	MBF_MNTLSTLOCK	0x02
724a9643ea8Slogwang #define	MBF_MASK	(MBF_NOWAIT | MBF_MNTLSTLOCK)
725a9643ea8Slogwang 
726a9643ea8Slogwang #ifdef MALLOC_DECLARE
727a9643ea8Slogwang MALLOC_DECLARE(M_MOUNT);
728*22ce4affSfengbojiang MALLOC_DECLARE(M_STATFS);
729a9643ea8Slogwang #endif
730a9643ea8Slogwang extern int maxvfsconf;		/* highest defined filesystem type */
731a9643ea8Slogwang 
732a9643ea8Slogwang TAILQ_HEAD(vfsconfhead, vfsconf);
733a9643ea8Slogwang extern struct vfsconfhead vfsconf;
734a9643ea8Slogwang 
735a9643ea8Slogwang /*
736a9643ea8Slogwang  * Operations supported on mounted filesystem.
737a9643ea8Slogwang  */
738a9643ea8Slogwang struct mount_args;
739a9643ea8Slogwang struct nameidata;
740a9643ea8Slogwang struct sysctl_req;
741a9643ea8Slogwang struct mntarg;
742a9643ea8Slogwang 
743*22ce4affSfengbojiang /*
744*22ce4affSfengbojiang  * N.B., vfs_cmount is the ancient vfsop invoked by the old mount(2) syscall.
745*22ce4affSfengbojiang  * The new way is vfs_mount.
746*22ce4affSfengbojiang  *
747*22ce4affSfengbojiang  * vfs_cmount implementations typically translate arguments from their
748*22ce4affSfengbojiang  * respective old per-FS structures into the key-value list supported by
749*22ce4affSfengbojiang  * nmount(2), then use kernel_mount(9) to mimic nmount(2) from kernelspace.
750*22ce4affSfengbojiang  *
751*22ce4affSfengbojiang  * Filesystems with mounters that use nmount(2) do not need to and should not
752*22ce4affSfengbojiang  * implement vfs_cmount.  Hopefully a future cleanup can remove vfs_cmount and
753*22ce4affSfengbojiang  * mount(2) entirely.
754*22ce4affSfengbojiang  */
755a9643ea8Slogwang typedef int vfs_cmount_t(struct mntarg *ma, void *data, uint64_t flags);
756a9643ea8Slogwang typedef int vfs_unmount_t(struct mount *mp, int mntflags);
757a9643ea8Slogwang typedef int vfs_root_t(struct mount *mp, int flags, struct vnode **vpp);
758a9643ea8Slogwang typedef	int vfs_quotactl_t(struct mount *mp, int cmds, uid_t uid, void *arg);
759a9643ea8Slogwang typedef	int vfs_statfs_t(struct mount *mp, struct statfs *sbp);
760a9643ea8Slogwang typedef	int vfs_sync_t(struct mount *mp, int waitfor);
761a9643ea8Slogwang typedef	int vfs_vget_t(struct mount *mp, ino_t ino, int flags,
762a9643ea8Slogwang 		    struct vnode **vpp);
763a9643ea8Slogwang typedef	int vfs_fhtovp_t(struct mount *mp, struct fid *fhp,
764a9643ea8Slogwang 		    int flags, struct vnode **vpp);
765a9643ea8Slogwang typedef	int vfs_checkexp_t(struct mount *mp, struct sockaddr *nam,
766*22ce4affSfengbojiang 		    uint64_t *extflagsp, struct ucred **credanonp,
767*22ce4affSfengbojiang 		    int *numsecflavors, int *secflavors);
768a9643ea8Slogwang typedef	int vfs_init_t(struct vfsconf *);
769a9643ea8Slogwang typedef	int vfs_uninit_t(struct vfsconf *);
770a9643ea8Slogwang typedef	int vfs_extattrctl_t(struct mount *mp, int cmd,
771a9643ea8Slogwang 		    struct vnode *filename_vp, int attrnamespace,
772a9643ea8Slogwang 		    const char *attrname);
773a9643ea8Slogwang typedef	int vfs_mount_t(struct mount *mp);
774a9643ea8Slogwang typedef int vfs_sysctl_t(struct mount *mp, fsctlop_t op,
775a9643ea8Slogwang 		    struct sysctl_req *req);
776a9643ea8Slogwang typedef void vfs_susp_clean_t(struct mount *mp);
777a9643ea8Slogwang typedef void vfs_notify_lowervp_t(struct mount *mp, struct vnode *lowervp);
778a9643ea8Slogwang typedef void vfs_purge_t(struct mount *mp);
779a9643ea8Slogwang 
780a9643ea8Slogwang struct vfsops {
781a9643ea8Slogwang 	vfs_mount_t		*vfs_mount;
782a9643ea8Slogwang 	vfs_cmount_t		*vfs_cmount;
783a9643ea8Slogwang 	vfs_unmount_t		*vfs_unmount;
784a9643ea8Slogwang 	vfs_root_t		*vfs_root;
785*22ce4affSfengbojiang 	vfs_root_t		*vfs_cachedroot;
786a9643ea8Slogwang 	vfs_quotactl_t		*vfs_quotactl;
787a9643ea8Slogwang 	vfs_statfs_t		*vfs_statfs;
788a9643ea8Slogwang 	vfs_sync_t		*vfs_sync;
789a9643ea8Slogwang 	vfs_vget_t		*vfs_vget;
790a9643ea8Slogwang 	vfs_fhtovp_t		*vfs_fhtovp;
791a9643ea8Slogwang 	vfs_checkexp_t		*vfs_checkexp;
792a9643ea8Slogwang 	vfs_init_t		*vfs_init;
793a9643ea8Slogwang 	vfs_uninit_t		*vfs_uninit;
794a9643ea8Slogwang 	vfs_extattrctl_t	*vfs_extattrctl;
795a9643ea8Slogwang 	vfs_sysctl_t		*vfs_sysctl;
796a9643ea8Slogwang 	vfs_susp_clean_t	*vfs_susp_clean;
797a9643ea8Slogwang 	vfs_notify_lowervp_t	*vfs_reclaim_lowervp;
798a9643ea8Slogwang 	vfs_notify_lowervp_t	*vfs_unlink_lowervp;
799a9643ea8Slogwang 	vfs_purge_t		*vfs_purge;
800a9643ea8Slogwang 	vfs_mount_t		*vfs_spare[6];	/* spares for ABI compat */
801a9643ea8Slogwang };
802a9643ea8Slogwang 
803a9643ea8Slogwang vfs_statfs_t	__vfs_statfs;
804a9643ea8Slogwang 
805a9643ea8Slogwang #define	VFS_MOUNT(MP) ({						\
806a9643ea8Slogwang 	int _rc;							\
807a9643ea8Slogwang 									\
808*22ce4affSfengbojiang 	TSRAW(curthread, TS_ENTER, "VFS_MOUNT", (MP)->mnt_vfc->vfc_name);\
809a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_mount)(MP);				\
810*22ce4affSfengbojiang 	TSRAW(curthread, TS_EXIT, "VFS_MOUNT", (MP)->mnt_vfc->vfc_name);\
811a9643ea8Slogwang 	_rc; })
812a9643ea8Slogwang 
813a9643ea8Slogwang #define	VFS_UNMOUNT(MP, FORCE) ({					\
814a9643ea8Slogwang 	int _rc;							\
815a9643ea8Slogwang 									\
816a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_unmount)(MP, FORCE);			\
817a9643ea8Slogwang 	_rc; })
818a9643ea8Slogwang 
819a9643ea8Slogwang #define	VFS_ROOT(MP, FLAGS, VPP) ({					\
820a9643ea8Slogwang 	int _rc;							\
821a9643ea8Slogwang 									\
822a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_root)(MP, FLAGS, VPP);		\
823*22ce4affSfengbojiang 	_rc; })
824*22ce4affSfengbojiang 
825*22ce4affSfengbojiang #define	VFS_CACHEDROOT(MP, FLAGS, VPP) ({				\
826*22ce4affSfengbojiang 	int _rc;							\
827*22ce4affSfengbojiang 									\
828*22ce4affSfengbojiang 	_rc = (*(MP)->mnt_op->vfs_cachedroot)(MP, FLAGS, VPP);		\
829a9643ea8Slogwang 	_rc; })
830a9643ea8Slogwang 
831a9643ea8Slogwang #define	VFS_QUOTACTL(MP, C, U, A) ({					\
832a9643ea8Slogwang 	int _rc;							\
833a9643ea8Slogwang 									\
834a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_quotactl)(MP, C, U, A);		\
835a9643ea8Slogwang 	_rc; })
836a9643ea8Slogwang 
837a9643ea8Slogwang #define	VFS_STATFS(MP, SBP) ({						\
838a9643ea8Slogwang 	int _rc;							\
839a9643ea8Slogwang 									\
840a9643ea8Slogwang 	_rc = __vfs_statfs((MP), (SBP));				\
841a9643ea8Slogwang 	_rc; })
842a9643ea8Slogwang 
843a9643ea8Slogwang #define	VFS_SYNC(MP, WAIT) ({						\
844a9643ea8Slogwang 	int _rc;							\
845a9643ea8Slogwang 									\
846a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_sync)(MP, WAIT);			\
847a9643ea8Slogwang 	_rc; })
848a9643ea8Slogwang 
849a9643ea8Slogwang #define	VFS_VGET(MP, INO, FLAGS, VPP) ({				\
850a9643ea8Slogwang 	int _rc;							\
851a9643ea8Slogwang 									\
852a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_vget)(MP, INO, FLAGS, VPP);		\
853a9643ea8Slogwang 	_rc; })
854a9643ea8Slogwang 
855a9643ea8Slogwang #define	VFS_FHTOVP(MP, FIDP, FLAGS, VPP) ({				\
856a9643ea8Slogwang 	int _rc;							\
857a9643ea8Slogwang 									\
858a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, FLAGS, VPP);	\
859a9643ea8Slogwang 	_rc; })
860a9643ea8Slogwang 
861a9643ea8Slogwang #define	VFS_CHECKEXP(MP, NAM, EXFLG, CRED, NUMSEC, SEC) ({		\
862a9643ea8Slogwang 	int _rc;							\
863a9643ea8Slogwang 									\
864a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED, NUMSEC,\
865a9643ea8Slogwang 	    SEC);							\
866a9643ea8Slogwang 	_rc; })
867a9643ea8Slogwang 
868a9643ea8Slogwang #define	VFS_EXTATTRCTL(MP, C, FN, NS, N) ({				\
869a9643ea8Slogwang 	int _rc;							\
870a9643ea8Slogwang 									\
871a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_extattrctl)(MP, C, FN, NS, N);	\
872a9643ea8Slogwang 	_rc; })
873a9643ea8Slogwang 
874a9643ea8Slogwang #define	VFS_SYSCTL(MP, OP, REQ) ({					\
875a9643ea8Slogwang 	int _rc;							\
876a9643ea8Slogwang 									\
877a9643ea8Slogwang 	_rc = (*(MP)->mnt_op->vfs_sysctl)(MP, OP, REQ);			\
878a9643ea8Slogwang 	_rc; })
879a9643ea8Slogwang 
880a9643ea8Slogwang #define	VFS_SUSP_CLEAN(MP) do {						\
881a9643ea8Slogwang 	if (*(MP)->mnt_op->vfs_susp_clean != NULL) {			\
882a9643ea8Slogwang 		(*(MP)->mnt_op->vfs_susp_clean)(MP);			\
883a9643ea8Slogwang 	}								\
884a9643ea8Slogwang } while (0)
885a9643ea8Slogwang 
886a9643ea8Slogwang #define	VFS_RECLAIM_LOWERVP(MP, VP) do {				\
887a9643ea8Slogwang 	if (*(MP)->mnt_op->vfs_reclaim_lowervp != NULL) {		\
888a9643ea8Slogwang 		(*(MP)->mnt_op->vfs_reclaim_lowervp)((MP), (VP));	\
889a9643ea8Slogwang 	}								\
890a9643ea8Slogwang } while (0)
891a9643ea8Slogwang 
892a9643ea8Slogwang #define	VFS_UNLINK_LOWERVP(MP, VP) do {					\
893a9643ea8Slogwang 	if (*(MP)->mnt_op->vfs_unlink_lowervp != NULL) {		\
894a9643ea8Slogwang 		(*(MP)->mnt_op->vfs_unlink_lowervp)((MP), (VP));	\
895a9643ea8Slogwang 	}								\
896a9643ea8Slogwang } while (0)
897a9643ea8Slogwang 
898a9643ea8Slogwang #define	VFS_PURGE(MP) do {						\
899a9643ea8Slogwang 	if (*(MP)->mnt_op->vfs_purge != NULL) {				\
900a9643ea8Slogwang 		(*(MP)->mnt_op->vfs_purge)(MP);				\
901a9643ea8Slogwang 	}								\
902a9643ea8Slogwang } while (0)
903a9643ea8Slogwang 
904a9643ea8Slogwang #define VFS_KNOTE_LOCKED(vp, hint) do					\
905a9643ea8Slogwang {									\
906a9643ea8Slogwang 	if (((vp)->v_vflag & VV_NOKNOTE) == 0)				\
907a9643ea8Slogwang 		VN_KNOTE((vp), (hint), KNF_LISTLOCKED);			\
908a9643ea8Slogwang } while (0)
909a9643ea8Slogwang 
910a9643ea8Slogwang #define VFS_KNOTE_UNLOCKED(vp, hint) do					\
911a9643ea8Slogwang {									\
912a9643ea8Slogwang 	if (((vp)->v_vflag & VV_NOKNOTE) == 0)				\
913a9643ea8Slogwang 		VN_KNOTE((vp), (hint), 0);				\
914a9643ea8Slogwang } while (0)
915a9643ea8Slogwang 
916a9643ea8Slogwang #define	VFS_NOTIFY_UPPER_RECLAIM	1
917a9643ea8Slogwang #define	VFS_NOTIFY_UPPER_UNLINK		2
918a9643ea8Slogwang 
919a9643ea8Slogwang #include <sys/module.h>
920a9643ea8Slogwang 
921a9643ea8Slogwang /*
922a9643ea8Slogwang  * Version numbers.
923a9643ea8Slogwang  */
924a9643ea8Slogwang #define VFS_VERSION_00	0x19660120
925a9643ea8Slogwang #define VFS_VERSION_01	0x20121030
926*22ce4affSfengbojiang #define VFS_VERSION_02	0x20180504
927*22ce4affSfengbojiang #define VFS_VERSION	VFS_VERSION_02
928a9643ea8Slogwang 
929a9643ea8Slogwang #define VFS_SET(vfsops, fsname, flags) \
930a9643ea8Slogwang 	static struct vfsconf fsname ## _vfsconf = {		\
931a9643ea8Slogwang 		.vfc_version = VFS_VERSION,			\
932a9643ea8Slogwang 		.vfc_name = #fsname,				\
933a9643ea8Slogwang 		.vfc_vfsops = &vfsops,				\
934a9643ea8Slogwang 		.vfc_typenum = -1,				\
935a9643ea8Slogwang 		.vfc_flags = flags,				\
936a9643ea8Slogwang 	};							\
937a9643ea8Slogwang 	static moduledata_t fsname ## _mod = {			\
938a9643ea8Slogwang 		#fsname,					\
939a9643ea8Slogwang 		vfs_modevent,					\
940a9643ea8Slogwang 		& fsname ## _vfsconf				\
941a9643ea8Slogwang 	};							\
942a9643ea8Slogwang 	DECLARE_MODULE(fsname, fsname ## _mod, SI_SUB_VFS, SI_ORDER_MIDDLE)
943a9643ea8Slogwang 
944a9643ea8Slogwang /*
945a9643ea8Slogwang  * exported vnode operations
946a9643ea8Slogwang  */
947a9643ea8Slogwang 
948a9643ea8Slogwang int	dounmount(struct mount *, int, struct thread *);
949a9643ea8Slogwang 
950a9643ea8Slogwang int	kernel_mount(struct mntarg *ma, uint64_t flags);
951a9643ea8Slogwang int	kernel_vmount(int flags, ...);
952a9643ea8Slogwang struct mntarg *mount_arg(struct mntarg *ma, const char *name, const void *val, int len);
953a9643ea8Slogwang struct mntarg *mount_argb(struct mntarg *ma, int flag, const char *name);
954a9643ea8Slogwang struct mntarg *mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...);
955a9643ea8Slogwang struct mntarg *mount_argsu(struct mntarg *ma, const char *name, const void *val, int len);
956a9643ea8Slogwang void	statfs_scale_blocks(struct statfs *sf, long max_size);
957a9643ea8Slogwang struct vfsconf *vfs_byname(const char *);
958a9643ea8Slogwang struct vfsconf *vfs_byname_kld(const char *, struct thread *td, int *);
959a9643ea8Slogwang void	vfs_mount_destroy(struct mount *);
960a9643ea8Slogwang void	vfs_event_signal(fsid_t *, u_int32_t, intptr_t);
961a9643ea8Slogwang void	vfs_freeopts(struct vfsoptlist *opts);
962a9643ea8Slogwang void	vfs_deleteopt(struct vfsoptlist *opts, const char *name);
963a9643ea8Slogwang int	vfs_buildopts(struct uio *auio, struct vfsoptlist **options);
964a9643ea8Slogwang int	vfs_flagopt(struct vfsoptlist *opts, const char *name, uint64_t *w,
965a9643ea8Slogwang 	    uint64_t val);
966a9643ea8Slogwang int	vfs_getopt(struct vfsoptlist *, const char *, void **, int *);
967a9643ea8Slogwang int	vfs_getopt_pos(struct vfsoptlist *opts, const char *name);
968a9643ea8Slogwang int	vfs_getopt_size(struct vfsoptlist *opts, const char *name,
969a9643ea8Slogwang 	    off_t *value);
970a9643ea8Slogwang char	*vfs_getopts(struct vfsoptlist *, const char *, int *error);
971a9643ea8Slogwang int	vfs_copyopt(struct vfsoptlist *, const char *, void *, int);
972a9643ea8Slogwang int	vfs_filteropt(struct vfsoptlist *, const char **legal);
973a9643ea8Slogwang void	vfs_opterror(struct vfsoptlist *opts, const char *fmt, ...);
974a9643ea8Slogwang int	vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...);
975a9643ea8Slogwang int	vfs_setopt(struct vfsoptlist *opts, const char *name, void *value,
976a9643ea8Slogwang 	    int len);
977a9643ea8Slogwang int	vfs_setopt_part(struct vfsoptlist *opts, const char *name, void *value,
978a9643ea8Slogwang 	    int len);
979a9643ea8Slogwang int	vfs_setopts(struct vfsoptlist *opts, const char *name,
980a9643ea8Slogwang 	    const char *value);
981a9643ea8Slogwang int	vfs_setpublicfs			    /* set publicly exported fs */
982a9643ea8Slogwang 	    (struct mount *, struct netexport *, struct export_args *);
983*22ce4affSfengbojiang void	vfs_periodic(struct mount *, int);
984a9643ea8Slogwang int	vfs_busy(struct mount *, int);
985a9643ea8Slogwang int	vfs_export			 /* process mount export info */
986a9643ea8Slogwang 	    (struct mount *, struct export_args *);
987a9643ea8Slogwang void	vfs_allocate_syncvnode(struct mount *);
988a9643ea8Slogwang void	vfs_deallocate_syncvnode(struct mount *);
989a9643ea8Slogwang int	vfs_donmount(struct thread *td, uint64_t fsflags,
990a9643ea8Slogwang 	    struct uio *fsoptions);
991a9643ea8Slogwang void	vfs_getnewfsid(struct mount *);
992a9643ea8Slogwang struct cdev *vfs_getrootfsid(struct mount *);
993a9643ea8Slogwang struct	mount *vfs_getvfs(fsid_t *);      /* return vfs given fsid */
994a9643ea8Slogwang struct	mount *vfs_busyfs(fsid_t *);
995a9643ea8Slogwang int	vfs_modevent(module_t, int, void *);
996a9643ea8Slogwang void	vfs_mount_error(struct mount *, const char *, ...);
997a9643ea8Slogwang void	vfs_mountroot(void);			/* mount our root filesystem */
998a9643ea8Slogwang void	vfs_mountedfrom(struct mount *, const char *from);
999a9643ea8Slogwang void	vfs_notify_upper(struct vnode *, int);
1000a9643ea8Slogwang void	vfs_ref(struct mount *);
1001a9643ea8Slogwang void	vfs_rel(struct mount *);
1002a9643ea8Slogwang struct mount *vfs_mount_alloc(struct vnode *, struct vfsconf *, const char *,
1003a9643ea8Slogwang 	    struct ucred *);
1004a9643ea8Slogwang int	vfs_suser(struct mount *, struct thread *);
1005a9643ea8Slogwang void	vfs_unbusy(struct mount *);
1006a9643ea8Slogwang void	vfs_unmountall(void);
1007a9643ea8Slogwang extern	TAILQ_HEAD(mntlist, mount) mountlist;	/* mounted filesystem list */
1008*22ce4affSfengbojiang extern	struct mtx_padalign mountlist_mtx;
1009a9643ea8Slogwang extern	struct nfs_public nfs_pub;
1010a9643ea8Slogwang extern	struct sx vfsconf_sx;
1011a9643ea8Slogwang #define	vfsconf_lock()		sx_xlock(&vfsconf_sx)
1012a9643ea8Slogwang #define	vfsconf_unlock()	sx_xunlock(&vfsconf_sx)
1013a9643ea8Slogwang #define	vfsconf_slock()		sx_slock(&vfsconf_sx)
1014a9643ea8Slogwang #define	vfsconf_sunlock()	sx_sunlock(&vfsconf_sx)
1015*22ce4affSfengbojiang struct vnode *mntfs_allocvp(struct mount *, struct vnode *);
1016*22ce4affSfengbojiang void   mntfs_freevp(struct vnode *);
1017a9643ea8Slogwang 
1018a9643ea8Slogwang /*
1019a9643ea8Slogwang  * Declarations for these vfs default operations are located in
1020a9643ea8Slogwang  * kern/vfs_default.c.  They will be automatically used to replace
1021a9643ea8Slogwang  * null entries in VFS ops tables when registering a new filesystem
1022a9643ea8Slogwang  * type in the global table.
1023a9643ea8Slogwang  */
1024a9643ea8Slogwang vfs_root_t		vfs_stdroot;
1025a9643ea8Slogwang vfs_quotactl_t		vfs_stdquotactl;
1026a9643ea8Slogwang vfs_statfs_t		vfs_stdstatfs;
1027a9643ea8Slogwang vfs_sync_t		vfs_stdsync;
1028a9643ea8Slogwang vfs_sync_t		vfs_stdnosync;
1029a9643ea8Slogwang vfs_vget_t		vfs_stdvget;
1030a9643ea8Slogwang vfs_fhtovp_t		vfs_stdfhtovp;
1031a9643ea8Slogwang vfs_checkexp_t		vfs_stdcheckexp;
1032a9643ea8Slogwang vfs_init_t		vfs_stdinit;
1033a9643ea8Slogwang vfs_uninit_t		vfs_stduninit;
1034a9643ea8Slogwang vfs_extattrctl_t	vfs_stdextattrctl;
1035a9643ea8Slogwang vfs_sysctl_t		vfs_stdsysctl;
1036a9643ea8Slogwang 
1037a9643ea8Slogwang void	syncer_suspend(void);
1038a9643ea8Slogwang void	syncer_resume(void);
1039a9643ea8Slogwang 
1040*22ce4affSfengbojiang struct vnode *vfs_cache_root_clear(struct mount *);
1041*22ce4affSfengbojiang void	vfs_cache_root_set(struct mount *, struct vnode *);
1042*22ce4affSfengbojiang 
1043*22ce4affSfengbojiang void	vfs_op_barrier_wait(struct mount *);
1044*22ce4affSfengbojiang void	vfs_op_enter(struct mount *);
1045*22ce4affSfengbojiang void	vfs_op_exit_locked(struct mount *);
1046*22ce4affSfengbojiang void	vfs_op_exit(struct mount *);
1047*22ce4affSfengbojiang 
1048*22ce4affSfengbojiang #ifdef DIAGNOSTIC
1049*22ce4affSfengbojiang void	vfs_assert_mount_counters(struct mount *);
1050*22ce4affSfengbojiang void	vfs_dump_mount_counters(struct mount *);
1051*22ce4affSfengbojiang #else
1052*22ce4affSfengbojiang #define vfs_assert_mount_counters(mp) do { } while (0)
1053*22ce4affSfengbojiang #define vfs_dump_mount_counters(mp) do { } while (0)
1054*22ce4affSfengbojiang #endif
1055*22ce4affSfengbojiang 
1056*22ce4affSfengbojiang enum mount_counter { MNT_COUNT_REF, MNT_COUNT_LOCKREF, MNT_COUNT_WRITEOPCOUNT };
1057*22ce4affSfengbojiang int	vfs_mount_fetch_counter(struct mount *, enum mount_counter);
1058*22ce4affSfengbojiang 
1059*22ce4affSfengbojiang void suspend_all_fs(void);
1060*22ce4affSfengbojiang void resume_all_fs(void);
1061*22ce4affSfengbojiang 
1062*22ce4affSfengbojiang /*
1063*22ce4affSfengbojiang  * Code transitioning mnt_vfs_ops to > 0 issues IPIs until it observes
1064*22ce4affSfengbojiang  * all CPUs not executing code enclosed by thread_in_ops_pcpu variable.
1065*22ce4affSfengbojiang  *
1066*22ce4affSfengbojiang  * This provides an invariant that by the time the last CPU is observed not
1067*22ce4affSfengbojiang  * executing, everyone else entering will see the counter > 0 and exit.
1068*22ce4affSfengbojiang  *
1069*22ce4affSfengbojiang  * Note there is no barrier between vfs_ops and the rest of the code in the
1070*22ce4affSfengbojiang  * section. It is not necessary as the writer has to wait for everyone to drain
1071*22ce4affSfengbojiang  * before making any changes or only make changes safe while the section is
1072*22ce4affSfengbojiang  * executed.
1073*22ce4affSfengbojiang  */
1074*22ce4affSfengbojiang #define	vfs_mount_pcpu(mp)		zpcpu_get(mp->mnt_pcpu)
1075*22ce4affSfengbojiang #define	vfs_mount_pcpu_remote(mp, cpu)	zpcpu_get_cpu(mp->mnt_pcpu, cpu)
1076*22ce4affSfengbojiang 
1077*22ce4affSfengbojiang #define vfs_op_thread_entered(mp) ({				\
1078*22ce4affSfengbojiang 	MPASS(curthread->td_critnest > 0);			\
1079*22ce4affSfengbojiang 	struct mount_pcpu *_mpcpu = vfs_mount_pcpu(mp);		\
1080*22ce4affSfengbojiang 	_mpcpu->mntp_thread_in_ops == 1;			\
1081*22ce4affSfengbojiang })
1082*22ce4affSfengbojiang 
1083*22ce4affSfengbojiang #define vfs_op_thread_enter_crit(mp, _mpcpu) ({			\
1084*22ce4affSfengbojiang 	bool _retval_crit = true;				\
1085*22ce4affSfengbojiang 	MPASS(curthread->td_critnest > 0);			\
1086*22ce4affSfengbojiang 	_mpcpu = vfs_mount_pcpu(mp);				\
1087*22ce4affSfengbojiang 	MPASS(mpcpu->mntp_thread_in_ops == 0);			\
1088*22ce4affSfengbojiang 	_mpcpu->mntp_thread_in_ops = 1;				\
1089*22ce4affSfengbojiang 	atomic_interrupt_fence();					\
1090*22ce4affSfengbojiang 	if (__predict_false(mp->mnt_vfs_ops > 0)) {		\
1091*22ce4affSfengbojiang 		vfs_op_thread_exit_crit(mp, _mpcpu);		\
1092*22ce4affSfengbojiang 		_retval_crit = false;				\
1093*22ce4affSfengbojiang 	}							\
1094*22ce4affSfengbojiang 	_retval_crit;						\
1095*22ce4affSfengbojiang })
1096*22ce4affSfengbojiang 
1097*22ce4affSfengbojiang #define vfs_op_thread_enter(mp, _mpcpu) ({			\
1098*22ce4affSfengbojiang 	bool _retval;						\
1099*22ce4affSfengbojiang 	critical_enter();					\
1100*22ce4affSfengbojiang 	_retval = vfs_op_thread_enter_crit(mp, _mpcpu);		\
1101*22ce4affSfengbojiang 	if (__predict_false(!_retval))				\
1102*22ce4affSfengbojiang 		critical_exit();				\
1103*22ce4affSfengbojiang 	_retval;						\
1104*22ce4affSfengbojiang })
1105*22ce4affSfengbojiang 
1106*22ce4affSfengbojiang #define vfs_op_thread_exit_crit(mp, _mpcpu) do {		\
1107*22ce4affSfengbojiang 	MPASS(_mpcpu == vfs_mount_pcpu(mp));			\
1108*22ce4affSfengbojiang 	MPASS(_mpcpu->mntp_thread_in_ops == 1);			\
1109*22ce4affSfengbojiang 	atomic_interrupt_fence();					\
1110*22ce4affSfengbojiang 	_mpcpu->mntp_thread_in_ops = 0;				\
1111*22ce4affSfengbojiang } while (0)
1112*22ce4affSfengbojiang 
1113*22ce4affSfengbojiang #define vfs_op_thread_exit(mp, _mpcpu) do {			\
1114*22ce4affSfengbojiang 	vfs_op_thread_exit_crit(mp, _mpcpu);			\
1115*22ce4affSfengbojiang 	critical_exit();					\
1116*22ce4affSfengbojiang } while (0)
1117*22ce4affSfengbojiang 
1118*22ce4affSfengbojiang #define vfs_mp_count_add_pcpu(_mpcpu, count, val) do {		\
1119*22ce4affSfengbojiang 	MPASS(_mpcpu->mntp_thread_in_ops == 1);			\
1120*22ce4affSfengbojiang 	_mpcpu->mntp_##count += val;				\
1121*22ce4affSfengbojiang } while (0)
1122*22ce4affSfengbojiang 
1123*22ce4affSfengbojiang #define vfs_mp_count_sub_pcpu(_mpcpu, count, val) do {		\
1124*22ce4affSfengbojiang 	MPASS(_mpcpu->mntp_thread_in_ops == 1);			\
1125*22ce4affSfengbojiang 	_mpcpu->mntp_##count -= val;				\
1126*22ce4affSfengbojiang } while (0)
1127*22ce4affSfengbojiang 
1128a9643ea8Slogwang #else /* !_KERNEL */
1129a9643ea8Slogwang 
1130a9643ea8Slogwang #include <sys/cdefs.h>
1131a9643ea8Slogwang 
1132a9643ea8Slogwang struct stat;
1133a9643ea8Slogwang 
1134a9643ea8Slogwang __BEGIN_DECLS
1135*22ce4affSfengbojiang int	fhlink(struct fhandle *, const char *);
1136*22ce4affSfengbojiang int	fhlinkat(struct fhandle *, int, const char *);
1137a9643ea8Slogwang int	fhopen(const struct fhandle *, int);
1138*22ce4affSfengbojiang int	fhreadlink(struct fhandle *, char *, size_t);
1139a9643ea8Slogwang int	fhstat(const struct fhandle *, struct stat *);
1140a9643ea8Slogwang int	fhstatfs(const struct fhandle *, struct statfs *);
1141a9643ea8Slogwang int	fstatfs(int, struct statfs *);
1142a9643ea8Slogwang int	getfh(const char *, fhandle_t *);
1143*22ce4affSfengbojiang int	getfhat(int, char *, struct fhandle *, int);
1144a9643ea8Slogwang int	getfsstat(struct statfs *, long, int);
1145a9643ea8Slogwang int	getmntinfo(struct statfs **, int);
1146a9643ea8Slogwang int	lgetfh(const char *, fhandle_t *);
1147a9643ea8Slogwang int	mount(const char *, const char *, int, void *);
1148a9643ea8Slogwang int	nmount(struct iovec *, unsigned int, int);
1149a9643ea8Slogwang int	statfs(const char *, struct statfs *);
1150a9643ea8Slogwang int	unmount(const char *, int);
1151a9643ea8Slogwang 
1152a9643ea8Slogwang /* C library stuff */
1153a9643ea8Slogwang int	getvfsbyname(const char *, struct xvfsconf *);
1154a9643ea8Slogwang __END_DECLS
1155a9643ea8Slogwang 
1156a9643ea8Slogwang #endif /* _KERNEL */
1157a9643ea8Slogwang 
1158a9643ea8Slogwang #endif /* !_SYS_MOUNT_H_ */
1159