xref: /xnu-8020.121.3/bsd/vfs/vfs_conf.c (revision fdd8201d7b966f0c3ea610489d29bd841d358941) !
1 /*
2  * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
29 /*
30  * Copyright (c) 1989, 1993, 1995
31  *	The Regents of the University of California.  All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  * 1. Redistributions of source code must retain the above copyright
37  *    notice, this list of conditions and the following disclaimer.
38  * 2. Redistributions in binary form must reproduce the above copyright
39  *    notice, this list of conditions and the following disclaimer in the
40  *    documentation and/or other materials provided with the distribution.
41  * 3. All advertising materials mentioning features or use of this software
42  *    must display the following acknowledgement:
43  *	This product includes software developed by the University of
44  *	California, Berkeley and its contributors.
45  * 4. Neither the name of the University nor the names of its contributors
46  *    may be used to endorse or promote products derived from this software
47  *    without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  *
61  *	@(#)vfs_conf.c	8.11 (Berkeley) 5/10/95
62  */
63 /*
64  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
65  * support for mandatory and extensible security protections.  This notice
66  * is included in support of clause 2.2 (b) of the Apple Public License,
67  * Version 2.0.
68  */
69 
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/mount_internal.h>
73 #include <sys/vnode_internal.h>
74 
75 #include <nfs/nfs_conf.h>
76 
77 /*
78  * These define the root filesystem, device, and root filesystem type.
79  */
80 struct mount *rootfs;
81 struct vnode *rootvnode;
82 
83 #ifdef CONFIG_IMGSRC_ACCESS
84 struct vnode *imgsrc_rootvnodes[MAX_IMAGEBOOT_NESTING]; /* [0] -> source volume, [1] -> first disk image */
85 #endif /* CONFIG_IMGSRC_ACCESS */
86 
87 int (*mountroot)(void) = NULL;
88 
89 /*
90  * Set up the initial array of known filesystem types.
91  */
92 extern  struct vfsops mfs_vfsops;
93 extern  int mfs_mountroot(mount_t, vnode_t, vfs_context_t);     /* dead */
94 extern  struct vfsops nfs_vfsops;
95 extern  int nfs_mountroot(void);
96 extern  struct vfsops afs_vfsops;
97 extern  struct vfsops null_vfsops;
98 extern  struct vfsops devfs_vfsops;
99 extern  const struct vfsops routefs_vfsops;
100 extern  struct vfsops nullfs_vfsops;
101 extern struct vfsops bindfs_vfsops;
102 
103 #if MOCKFS
104 extern  struct vfsops mockfs_vfsops;
105 extern  int mockfs_mountroot(mount_t, vnode_t, vfs_context_t);
106 #endif /* MOCKFS */
107 
108 /*
109  * For nfs_mountroot(void) cast.  nfs_mountroot ignores its parameters, if
110  * invoked through this table.
111  */
112 typedef int (*mountroot_t)(mount_t, vnode_t, vfs_context_t);
113 
114 enum fs_type_num {
115 	FT_NFS = 2,
116 	FT_DEVFS = 19,
117 	FT_SYNTHFS = 20,
118 	FT_ROUTEFS = 21,
119 	FT_NULLFS = 22,
120 	FT_BINDFS = 23,
121 	FT_MOCKFS  = 0x6D6F636B
122 };
123 
124 int fstypenumstart = FT_BINDFS + 1;
125 /*
126  * Set up the filesystem operations for vnodes.
127  */
128 static struct vfstable vfstbllist[] = {
129 	/* Sun-compatible Network Filesystem */
130 #if CONFIG_NFS_CLIENT
131 	{
132 		.vfc_vfsops = &nfs_vfsops,
133 		.vfc_name = "nfs",
134 		.vfc_typenum = FT_NFS,
135 		.vfc_refcount = 0,
136 		.vfc_flags = 0,
137 		.vfc_mountroot = NULL,
138 		.vfc_next = NULL,
139 		.vfc_reserved1 = 0,
140 		.vfc_reserved2 = 0,
141 		.vfc_vfsflags = VFC_VFSGENERICARGS | VFC_VFSPREFLIGHT | VFC_VFS64BITREADY | VFC_VFSREADDIR_EXTENDED,
142 		.vfc_descptr = NULL,
143 		.vfc_descsize = 0,
144 		.vfc_sysctl = NULL
145 	},
146 #endif /* CONFIG_NFS_CLIENT */
147 
148 	/* Device Filesystem */
149 #if DEVFS
150 #if CONFIG_MACF
151 	{
152 		.vfc_vfsops = &devfs_vfsops,
153 		.vfc_name = "devfs",
154 		.vfc_typenum = FT_DEVFS,
155 		.vfc_refcount = 0,
156 		.vfc_flags = MNT_MULTILABEL,
157 		.vfc_mountroot = NULL,
158 		.vfc_next = NULL,
159 		.vfc_reserved1 = 0,
160 		.vfc_reserved2 = 0,
161 		.vfc_vfsflags = VFC_VFSGENERICARGS | VFC_VFS64BITREADY,
162 		.vfc_descptr = NULL,
163 		.vfc_descsize = 0,
164 		.vfc_sysctl = NULL
165 	},
166 #else /* !CONFIG_MAC */
167 	{
168 		.vfc_vfsops = &devfs_vfsops,
169 		.vfc_name = "devfs",
170 		.vfc_typenum = FT_DEVFS,
171 		.vfc_refcount = 0,
172 		.vfc_flags = 0,
173 		.vfc_mountroot = NULL,
174 		.vfc_next = NULL,
175 		.vfc_reserved1 = 0,
176 		.vfc_reserved2 = 0,
177 		.vfc_vfsflags = VFC_VFSGENERICARGS | VFC_VFS64BITREADY,
178 		.vfc_descptr = NULL,
179 		.vfc_descsize = 0,
180 		.vfc_sysctl = NULL
181 	},
182 #endif /* CONFIG_MAC */
183 #endif /* DEVFS */
184 
185 #ifndef __LP64__
186 #endif /* __LP64__ */
187 
188 #if NULLFS
189 	{
190 		.vfc_vfsops = &nullfs_vfsops,
191 		.vfc_name = "nullfs",
192 		.vfc_typenum = FT_NULLFS,
193 		.vfc_refcount = 0,
194 		.vfc_flags = MNT_DONTBROWSE | MNT_RDONLY,
195 		.vfc_mountroot = NULL,
196 		.vfc_next = NULL,
197 		.vfc_reserved1 = 0,
198 		.vfc_reserved2 = 0,
199 		.vfc_vfsflags = VFC_VFS64BITREADY,
200 		.vfc_descptr = NULL,
201 		.vfc_descsize = 0,
202 		.vfc_sysctl = NULL
203 	},
204 #endif /* NULLFS */
205 
206 #if BINDFS
207 	{
208 		.vfc_vfsops = &bindfs_vfsops,
209 		.vfc_name = "bindfs",
210 		.vfc_typenum = FT_BINDFS,
211 		.vfc_refcount = 0,
212 		.vfc_flags = MNT_DONTBROWSE | MNT_RDONLY,
213 		.vfc_mountroot = NULL,
214 		.vfc_next = NULL,
215 		.vfc_reserved1 = 0,
216 		.vfc_reserved2 = 0,
217 		.vfc_vfsflags = VFC_VFS64BITREADY,
218 		.vfc_descptr = NULL,
219 		.vfc_descsize = 0,
220 		.vfc_sysctl = NULL
221 	},
222 #endif /* BINDFS */
223 
224 #if MOCKFS
225 	/* If we are configured for it, mockfs should always be the last standard entry (and thus the last FS we attempt mountroot with) */
226 	{
227 		.vfc_vfsops = &mockfs_vfsops,
228 		.vfc_name = "mockfs",
229 		.vfc_typenum = FT_MOCKFS,
230 		.vfc_refcount = 0,
231 		.vfc_flags = MNT_LOCAL,
232 		.vfc_mountroot = mockfs_mountroot,
233 		.vfc_next = NULL,
234 		.vfc_reserved1 = 0,
235 		.vfc_reserved2 = 0,
236 		.vfc_vfsflags = VFC_VFSGENERICARGS,
237 		.vfc_descptr = NULL,
238 		.vfc_descsize = 0,
239 		.vfc_sysctl = NULL
240 	},
241 #endif /* MOCKFS */
242 
243 #if ROUTEFS
244 	/* If we are configured for it, mockfs should always be the last standard entry (and thus the last FS we attempt mountroot with) */
245 	{
246 		.vfc_vfsops = &routefs_vfsops,
247 		.vfc_name = "routefs",
248 		.vfc_typenum = FT_ROUTEFS,
249 		.vfc_refcount = 0,
250 		.vfc_flags = MNT_LOCAL,
251 		.vfc_mountroot = NULL,
252 		.vfc_next = NULL,
253 		.vfc_reserved1 = 0,
254 		.vfc_reserved2 = 0,
255 		.vfc_vfsflags = VFC_VFSGENERICARGS | VFC_VFS64BITREADY,
256 		.vfc_descptr = NULL,
257 		.vfc_descsize = 0,
258 		.vfc_sysctl = NULL
259 	},
260 #endif /* ROUTEFS */
261 
262 	{
263 		.vfc_vfsops = NULL,
264 		.vfc_name = "<unassigned>",
265 		.vfc_typenum = 0,
266 		.vfc_refcount = 0,
267 		.vfc_flags = 0,
268 		.vfc_mountroot = NULL,
269 		.vfc_next = NULL,
270 		.vfc_reserved1 = 0,
271 		.vfc_reserved2 = 0,
272 		.vfc_vfsflags = 0,
273 		.vfc_descptr = NULL,
274 		.vfc_descsize = 0,
275 		.vfc_sysctl = NULL
276 	},
277 	{
278 		.vfc_vfsops = NULL,
279 		.vfc_name = "<unassigned>",
280 		.vfc_typenum = 0,
281 		.vfc_refcount = 0,
282 		.vfc_flags = 0,
283 		.vfc_mountroot = NULL,
284 		.vfc_next = NULL,
285 		.vfc_reserved1 = 0,
286 		.vfc_reserved2 = 0,
287 		.vfc_vfsflags = 0,
288 		.vfc_descptr = NULL,
289 		.vfc_descsize = 0,
290 		.vfc_sysctl = NULL
291 	},
292 };
293 
294 /*
295  * vfs_init will set maxvfstypenum to the highest defined type number.
296  */
297 const int maxvfsslots = sizeof(vfstbllist) / sizeof(struct vfstable);
298 int numused_vfsslots = 0;
299 int numregistered_fses = 0;
300 int maxvfstypenum = VT_NON + 1;
301 struct vfstable *vfsconf = vfstbllist;
302 
303 /*
304  *
305  * vfs_opv_descs enumerates the list of vnode classes, each with it's own
306  * vnode operation vector.  It is consulted at system boot to build operation
307  * vectors.  It is NULL terminated.
308  *
309  */
310 extern struct vnodeopv_desc mfs_vnodeop_opv_desc;
311 extern const struct vnodeopv_desc dead_vnodeop_opv_desc;
312 #if FIFO && SOCKETS
313 extern const struct vnodeopv_desc fifo_vnodeop_opv_desc;
314 #endif /* SOCKETS */
315 extern const struct vnodeopv_desc spec_vnodeop_opv_desc;
316 extern const struct vnodeopv_desc nfsv2_vnodeop_opv_desc;
317 extern const struct vnodeopv_desc spec_nfsv2nodeop_opv_desc;
318 extern const struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc;
319 #if CONFIG_NFS4
320 extern const struct vnodeopv_desc nfsv4_vnodeop_opv_desc;
321 extern const struct vnodeopv_desc spec_nfsv4nodeop_opv_desc;
322 extern const struct vnodeopv_desc fifo_nfsv4nodeop_opv_desc;
323 #endif
324 extern struct vnodeopv_desc null_vnodeop_opv_desc;
325 extern struct vnodeopv_desc devfs_vnodeop_opv_desc;
326 extern struct vnodeopv_desc devfs_spec_vnodeop_opv_desc;
327 #if FDESC
328 extern struct vnodeopv_desc devfs_devfd_vnodeop_opv_desc;
329 extern const struct vnodeopv_desc devfs_fdesc_vnodeop_opv_desc;
330 #endif /* FDESC */
331 
332 #if MOCKFS
333 extern const struct vnodeopv_desc mockfs_vnodeop_opv_desc;
334 #endif /* MOCKFS */
335 
336 extern const struct vnodeopv_desc nullfs_vnodeop_opv_desc;
337 extern const struct vnodeopv_desc bindfs_vnodeop_opv_desc;
338 
339 const struct vnodeopv_desc *vfs_opv_descs[] = {
340 	&dead_vnodeop_opv_desc,
341 #if FIFO && SOCKETS
342 	&fifo_vnodeop_opv_desc,
343 #endif
344 	&spec_vnodeop_opv_desc,
345 #if MFS
346 	&mfs_vnodeop_opv_desc,
347 #endif
348 #if CONFIG_NFS_CLIENT
349 	&nfsv2_vnodeop_opv_desc,
350 	&spec_nfsv2nodeop_opv_desc,
351 #if CONFIG_NFS4
352 	&nfsv4_vnodeop_opv_desc,
353 	&spec_nfsv4nodeop_opv_desc,
354 #endif
355 #if FIFO
356 	&fifo_nfsv2nodeop_opv_desc,
357 #if CONFIG_NFS4
358 	&fifo_nfsv4nodeop_opv_desc,
359 #endif /* CONFIG_NFS4 */
360 #endif /* FIFO */
361 #endif /* CONFIG_NFS_CLIENT */
362 #if DEVFS
363 	&devfs_vnodeop_opv_desc,
364 	&devfs_spec_vnodeop_opv_desc,
365 #if FDESC
366 	&devfs_devfd_vnodeop_opv_desc,
367 	&devfs_fdesc_vnodeop_opv_desc,
368 #endif /* FDESC */
369 #endif /* DEVFS */
370 #if NULLFS
371 	&nullfs_vnodeop_opv_desc,
372 #endif /* NULLFS */
373 #if BINDFS
374 	&bindfs_vnodeop_opv_desc,
375 #endif /* BINDFS */
376 #if MOCKFS
377 	&mockfs_vnodeop_opv_desc,
378 #endif /* MOCKFS */
379 	NULL
380 };
381