xref: /xnu-11215.41.3/bsd/vfs/vfs_subr.c (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 /*
2  *
3  * Copyright (c) 2000-2024 Apple Inc. All rights reserved.
4  *
5  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6  *
7  * This file contains Original Code and/or Modifications of Original Code
8  * as defined in and that are subject to the Apple Public Source License
9  * Version 2.0 (the 'License'). You may not use this file except in
10  * compliance with the License. The rights granted to you under the License
11  * may not be used to create, or enable the creation or redistribution of,
12  * unlawful or unlicensed copies of an Apple operating system, or to
13  * circumvent, violate, or enable the circumvention or violation of, any
14  * terms of an Apple operating system software license agreement.
15  *
16  * Please obtain a copy of the License at
17  * http://www.opensource.apple.com/apsl/ and read it before using this file.
18  *
19  * The Original Code and all software distributed under the License are
20  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
21  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
22  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
24  * Please see the License for the specific language governing rights and
25  * limitations under the License.
26  *
27  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28  */
29 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
30 /*
31  * Copyright (c) 1989, 1993
32  *	The Regents of the University of California.  All rights reserved.
33  * (c) UNIX System Laboratories, Inc.
34  * All or some portions of this file are derived from material licensed
35  * to the University of California by American Telephone and Telegraph
36  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
37  * the permission of UNIX System Laboratories, Inc.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  * 3. All advertising materials mentioning features or use of this software
48  *    must display the following acknowledgement:
49  *	This product includes software developed by the University of
50  *	California, Berkeley and its contributors.
51  * 4. Neither the name of the University nor the names of its contributors
52  *    may be used to endorse or promote products derived from this software
53  *    without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65  * SUCH DAMAGE.
66  *
67  *	@(#)vfs_subr.c	8.31 (Berkeley) 5/26/95
68  */
69 /*
70  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
71  * support for mandatory and extensible security protections.  This notice
72  * is included in support of clause 2.2 (b) of the Apple Public License,
73  * Version 2.0.
74  */
75 
76 /*
77  * External virtual filesystem routines
78  */
79 
80 #include <sys/param.h>
81 #include <sys/systm.h>
82 #include <sys/proc_internal.h>
83 #include <sys/kauth.h>
84 #include <sys/mount_internal.h>
85 #include <sys/time.h>
86 #include <sys/lock.h>
87 #include <sys/vnode.h>
88 #include <sys/vnode_internal.h>
89 #include <sys/stat.h>
90 #include <sys/namei.h>
91 #include <sys/ucred.h>
92 #include <sys/buf_internal.h>
93 #include <sys/errno.h>
94 #include <kern/kalloc.h>
95 #include <sys/uio_internal.h>
96 #include <sys/uio.h>
97 #include <sys/domain.h>
98 #include <sys/mbuf.h>
99 #include <sys/syslog.h>
100 #include <sys/ubc_internal.h>
101 #include <sys/vm.h>
102 #include <sys/sysctl.h>
103 #include <sys/filedesc.h>
104 #include <sys/fcntl.h>
105 #include <sys/event.h>
106 #include <sys/kdebug.h>
107 #include <sys/kauth.h>
108 #include <sys/user.h>
109 #include <sys/systm.h>
110 #include <sys/kern_memorystatus.h>
111 #include <sys/lockf.h>
112 #include <sys/reboot.h>
113 #include <miscfs/fifofs/fifo.h>
114 
115 #include <nfs/nfs.h>
116 
117 #include <string.h>
118 #include <machine/machine_routines.h>
119 
120 #include <kern/assert.h>
121 #include <mach/kern_return.h>
122 #include <kern/thread.h>
123 #include <kern/sched_prim.h>
124 #include <kern/smr.h>
125 
126 #include <miscfs/specfs/specdev.h>
127 
128 #include <mach/mach_types.h>
129 #include <mach/memory_object_types.h>
130 #include <mach/memory_object_control.h>
131 
132 #include <kern/kalloc.h>        /* kalloc()/kfree() */
133 #include <kern/clock.h>         /* delay_for_interval() */
134 #include <libkern/coreanalytics/coreanalytics.h>
135 #include <libkern/OSAtomic.h>   /* OSAddAtomic() */
136 #include <os/atomic_private.h>
137 #if defined(XNU_TARGET_OS_OSX)
138 #include <console/video_console.h>
139 #endif
140 
141 #ifdef CONFIG_IOCOUNT_TRACE
142 #include <libkern/OSDebug.h>
143 #endif
144 
145 #include <vm/vm_protos.h>       /* vnode_pager_vrele() */
146 #include <vm/vm_ubc.h>
147 #include <vm/memory_object_xnu.h>
148 
149 #if CONFIG_MACF
150 #include <security/mac_framework.h>
151 #endif
152 
153 #include <vfs/vfs_disk_conditioner.h>
154 #include <libkern/section_keywords.h>
155 
156 static LCK_GRP_DECLARE(vnode_lck_grp, "vnode");
157 static LCK_ATTR_DECLARE(vnode_lck_attr, 0, 0);
158 
159 #if CONFIG_TRIGGERS
160 static LCK_GRP_DECLARE(trigger_vnode_lck_grp, "trigger_vnode");
161 static LCK_ATTR_DECLARE(trigger_vnode_lck_attr, 0, 0);
162 #endif
163 
164 extern lck_mtx_t mnt_list_mtx_lock;
165 
166 static KALLOC_TYPE_DEFINE(specinfo_zone, struct specinfo, KT_DEFAULT);
167 
168 ZONE_DEFINE(vnode_zone, "vnodes",
169     sizeof(struct vnode), ZC_NOGC | ZC_ZFREE_CLEARMEM);
170 
171 enum vtype iftovt_tab[16] = {
172 	VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
173 	VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
174 };
175 int     vttoif_tab[9] = {
176 	0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK,
177 	S_IFSOCK, S_IFIFO, S_IFMT,
178 };
179 
180 extern int paniclog_append_noflush(const char *format, ...);
181 
182 /* XXX next prototytype should be from libsa/stdlib.h> but conflicts libkern */
183 __private_extern__ void qsort(
184 	void * array,
185 	size_t nmembers,
186 	size_t member_size,
187 	int (*)(const void *, const void *));
188 
189 __private_extern__ void vntblinit(void);
190 __private_extern__ int unlink1(vfs_context_t, vnode_t, user_addr_t,
191     enum uio_seg, int);
192 
193 static void vnode_list_add(vnode_t);
194 static void vnode_async_list_add(vnode_t);
195 static void vnode_list_remove(vnode_t);
196 static void vnode_list_remove_locked(vnode_t);
197 
198 static void vnode_abort_advlocks(vnode_t);
199 static errno_t vnode_drain(vnode_t);
200 static void vgone(vnode_t, int flags);
201 static void vclean(vnode_t vp, int flag);
202 static void vnode_reclaim_internal(vnode_t, int, int, int);
203 
204 static void vnode_dropiocount(vnode_t);
205 
206 static vnode_t checkalias(vnode_t vp, dev_t nvp_rdev);
207 static int  vnode_reload(vnode_t);
208 
209 static int unmount_callback(mount_t, __unused void *);
210 
211 static void insmntque(vnode_t vp, mount_t mp);
212 static int mount_getvfscnt(void);
213 static int mount_fillfsids(fsid_t *, int );
214 static void vnode_iterate_setup(mount_t);
215 int vnode_umount_preflight(mount_t, vnode_t, int);
216 static int vnode_iterate_prepare(mount_t);
217 static int vnode_iterate_reloadq(mount_t);
218 static void vnode_iterate_clear(mount_t);
219 static mount_t vfs_getvfs_locked(fsid_t *);
220 static int vn_create_reg(vnode_t dvp, vnode_t *vpp, struct nameidata *ndp,
221     struct vnode_attr *vap, uint32_t flags, int fmode, uint32_t *statusp, vfs_context_t ctx);
222 static int vnode_authattr_new_internal(vnode_t dvp, struct vnode_attr *vap, int noauth, uint32_t *defaulted_fieldsp, vfs_context_t ctx);
223 
224 errno_t rmdir_remove_orphaned_appleDouble(vnode_t, vfs_context_t, int *);
225 
226 #ifdef CONFIG_IOCOUNT_TRACE
227 static void record_vp(vnode_t vp, int count);
228 static TUNABLE(int, bootarg_vnode_iocount_trace, "vnode_iocount_trace", 0);
229 static TUNABLE(int, bootarg_uthread_iocount_trace, "uthread_iocount_trace", 0);
230 #endif /* CONFIG_IOCOUNT_TRACE */
231 
232 #if CONFIG_JETSAM && (DEVELOPMENT || DEBUG)
233 static TUNABLE(bool, bootarg_no_vnode_jetsam, "-no_vnode_jetsam", false);
234 #endif /* CONFIG_JETSAM && (DEVELOPMENT || DEBUG) */
235 
236 static TUNABLE(bool, bootarg_no_vnode_drain, "-no_vnode_drain", false);
237 
238 __options_decl(freeable_vnode_level_t, uint32_t, {
239 	DEALLOC_VNODE_NONE = 0,
240 	DEALLOC_VNODE_ONLY_OVERFLOW = 1,
241 	DEALLOC_VNODE_ALL = 2
242 });
243 
244 #if XNU_TARGET_OS_OSX
245 static TUNABLE(freeable_vnode_level_t, bootarg_vn_dealloc_level, "vn_dealloc_level", DEALLOC_VNODE_NONE);
246 #else
247 static TUNABLE(freeable_vnode_level_t, bootarg_vn_dealloc_level, "vn_dealloc_level", DEALLOC_VNODE_ONLY_OVERFLOW);
248 #endif /* CONFIG_VNDEALLOC */
249 
250 static freeable_vnode_level_t vn_dealloc_level = DEALLOC_VNODE_NONE;
251 
252 boolean_t root_is_CF_drive = FALSE;
253 
254 #if CONFIG_TRIGGERS
255 static int vnode_resolver_create(mount_t, vnode_t, struct vnode_trigger_param *, boolean_t external);
256 static void vnode_resolver_detach(vnode_t);
257 #endif
258 
259 TAILQ_HEAD(freelst, vnode) vnode_free_list;     /* vnode free list */
260 TAILQ_HEAD(deadlst, vnode) vnode_dead_list;     /* vnode dead list */
261 TAILQ_HEAD(async_work_lst, vnode) vnode_async_work_list;
262 
263 
264 TAILQ_HEAD(ragelst, vnode) vnode_rage_list;     /* vnode rapid age list */
265 struct timeval rage_tv;
266 int     rage_limit = 0;
267 int     ragevnodes = 0;
268 
269 long  reusablevnodes_max = LONG_MAX;
270 long  reusablevnodes = 0;
271 int   deadvnodes_low = 0;
272 int   deadvnodes_high = 0;
273 int   numvnodes_min = 0;
274 int   numvnodes_max = 0;
275 
276 uint64_t newvnode = 0;
277 unsigned long newvnode_nodead = 0;
278 
279 static  int vfs_unmountall_started = 0;
280 static  int vfs_unmountall_finished = 0;
281 static  uint64_t vfs_shutdown_last_completion_time;
282 
283 #define RAGE_LIMIT_MIN  100
284 #define RAGE_TIME_LIMIT 5
285 
286 VFS_SMR_DECLARE;
287 extern uint32_t nc_smr_enabled;
288 
289 /*
290  * ROSV definitions
291  * NOTE: These are shadowed from PlatformSupport definitions, but XNU
292  * builds standalone.
293  */
294 #define PLATFORM_DATA_VOLUME_MOUNT_POINT "/System/Volumes/Data"
295 
296 /*
297  * These could be in PlatformSupport but aren't yet
298  */
299 #define PLATFORM_PREBOOT_VOLUME_MOUNT_POINT "/System/Volumes/Preboot"
300 #define PLATFORM_RECOVERY_VOLUME_MOUNT_POINT "/System/Volumes/Recovery"
301 
302 #if CONFIG_MOUNT_VM
303 #define PLATFORM_VM_VOLUME_MOUNT_POINT "/System/Volumes/VM"
304 #endif
305 
306 struct mntlist mountlist;                       /* mounted filesystem list */
307 static int nummounts = 0;
308 
309 static int print_busy_vnodes = 0;                               /* print out busy vnodes */
310 
311 #if DIAGNOSTIC
312 #define VLISTCHECK(fun, vp, list)       \
313 	if ((vp)->v_freelist.tqe_prev == (struct vnode **)0xdeadb) \
314 	        panic("%s: %s vnode not on %slist", (fun), (list), (list));
315 #else
316 #define VLISTCHECK(fun, vp, list)
317 #endif /* DIAGNOSTIC */
318 
319 #define VLISTNONE(vp)   \
320 	do {    \
321 	        (vp)->v_freelist.tqe_next = (struct vnode *)0;  \
322 	        (vp)->v_freelist.tqe_prev = (struct vnode **)0xdeadb;   \
323 	} while(0)
324 
325 #define VONLIST(vp)     \
326 	((vp)->v_freelist.tqe_prev != (struct vnode **)0xdeadb)
327 
328 /* remove a vnode from free vnode list */
329 #define VREMFREE(fun, vp)       \
330 	do {    \
331 	        VLISTCHECK((fun), (vp), "free");        \
332 	        TAILQ_REMOVE(&vnode_free_list, (vp), v_freelist);       \
333 	        VLISTNONE((vp));        \
334 	        freevnodes--;   \
335 	        reusablevnodes--;    \
336 	} while(0)
337 
338 
339 /* remove a vnode from dead vnode list */
340 #define VREMDEAD(fun, vp)       \
341 	do {    \
342 	        VLISTCHECK((fun), (vp), "dead");        \
343 	        TAILQ_REMOVE(&vnode_dead_list, (vp), v_freelist);       \
344 	        VLISTNONE((vp));        \
345 	        vp->v_listflag &= ~VLIST_DEAD;  \
346 	        deadvnodes--;   \
347 	        if (vp->v_listflag & VLIST_NO_REUSE) {        \
348 	                deadvnodes_noreuse--;        \
349 	        }        \
350 	} while(0)
351 
352 
353 /* remove a vnode from async work vnode list */
354 #define VREMASYNC_WORK(fun, vp) \
355 	do {    \
356 	        VLISTCHECK((fun), (vp), "async_work");  \
357 	        TAILQ_REMOVE(&vnode_async_work_list, (vp), v_freelist); \
358 	        VLISTNONE((vp));        \
359 	        vp->v_listflag &= ~VLIST_ASYNC_WORK;    \
360 	        async_work_vnodes--;    \
361 	        if (!(vp->v_listflag & VLIST_NO_REUSE)) {        \
362 	                reusablevnodes--;    \
363 	        }        \
364 	} while(0)
365 
366 
367 /* remove a vnode from rage vnode list */
368 #define VREMRAGE(fun, vp)       \
369 	do {    \
370 	        if ( !(vp->v_listflag & VLIST_RAGE))                    \
371 	                panic("VREMRAGE: vp not on rage list");         \
372 	        VLISTCHECK((fun), (vp), "rage");                        \
373 	        TAILQ_REMOVE(&vnode_rage_list, (vp), v_freelist);       \
374 	        VLISTNONE((vp));                \
375 	        vp->v_listflag &= ~VLIST_RAGE;  \
376 	        ragevnodes--;                   \
377 	        reusablevnodes--;    \
378 	} while(0)
379 
380 static void async_work_continue(void);
381 static void vn_laundry_continue(void);
382 static void wakeup_laundry_thread(void);
383 static void vnode_smr_free(void *, size_t);
384 
385 CA_EVENT(freeable_vnodes,
386     CA_INT, numvnodes_min,
387     CA_INT, numvnodes_max,
388     CA_INT, desiredvnodes,
389     CA_INT, numvnodes,
390     CA_INT, freevnodes,
391     CA_INT, deadvnodes,
392     CA_INT, freeablevnodes,
393     CA_INT, busyvnodes,
394     CA_BOOL, threshold_crossed);
395 static CA_EVENT_TYPE(freeable_vnodes) freeable_vnodes_telemetry;
396 
397 static bool freeablevnodes_threshold_crossed = false;
398 
399 /*
400  * Initialize the vnode management data structures.
401  */
402 __private_extern__ void
vntblinit(void)403 vntblinit(void)
404 {
405 	thread_t        thread = THREAD_NULL;
406 	int desiredvnodes_one_percent = desiredvnodes / 100;
407 
408 	TAILQ_INIT(&vnode_free_list);
409 	TAILQ_INIT(&vnode_rage_list);
410 	TAILQ_INIT(&vnode_dead_list);
411 	TAILQ_INIT(&vnode_async_work_list);
412 	TAILQ_INIT(&mountlist);
413 
414 	microuptime(&rage_tv);
415 	rage_limit = desiredvnodes_one_percent;
416 	if (rage_limit < RAGE_LIMIT_MIN) {
417 		rage_limit = RAGE_LIMIT_MIN;
418 	}
419 
420 	deadvnodes_low = desiredvnodes_one_percent;
421 	if (deadvnodes_low > 300) {
422 		deadvnodes_low = 300;
423 	}
424 	deadvnodes_high = deadvnodes_low * 2;
425 
426 	numvnodes_min = numvnodes_max = desiredvnodes;
427 	if (bootarg_vn_dealloc_level == DEALLOC_VNODE_ONLY_OVERFLOW) {
428 		numvnodes_max = desiredvnodes * 2;
429 		vn_dealloc_level = bootarg_vn_dealloc_level;
430 	} else if (bootarg_vn_dealloc_level == DEALLOC_VNODE_ALL) {
431 		numvnodes_min = desiredvnodes_one_percent * 40;
432 		numvnodes_max = desiredvnodes * 2;
433 		reusablevnodes_max = (desiredvnodes_one_percent * 20) - deadvnodes_low;
434 		vn_dealloc_level = bootarg_vn_dealloc_level;
435 	}
436 
437 	bzero(&freeable_vnodes_telemetry, sizeof(CA_EVENT_TYPE(freeable_vnodes)));
438 	freeable_vnodes_telemetry.numvnodes_min = numvnodes_min;
439 	freeable_vnodes_telemetry.numvnodes_max = numvnodes_max;
440 	freeable_vnodes_telemetry.desiredvnodes = desiredvnodes;
441 
442 	if (nc_smr_enabled) {
443 		zone_enable_smr(vnode_zone, VFS_SMR(), &vnode_smr_free);
444 	}
445 
446 	/*
447 	 * create worker threads
448 	 */
449 	kernel_thread_start((thread_continue_t)async_work_continue, NULL, &thread);
450 	thread_deallocate(thread);
451 	kernel_thread_start((thread_continue_t)vn_laundry_continue, NULL, &thread);
452 	thread_deallocate(thread);
453 }
454 
455 /* the timeout is in 10 msecs */
456 int
vnode_waitforwrites(vnode_t vp,int output_target,int slpflag,int slptimeout,const char * msg)457 vnode_waitforwrites(vnode_t vp, int output_target, int slpflag, int slptimeout, const char *msg)
458 {
459 	int error = 0;
460 	struct timespec ts;
461 
462 	if (output_target < 0) {
463 		return EINVAL;
464 	}
465 
466 	KERNEL_DEBUG(0x3010280 | DBG_FUNC_START, (int)vp, output_target, vp->v_numoutput, 0, 0);
467 
468 	if (vp->v_numoutput > output_target) {
469 		slpflag |= PDROP;
470 
471 		vnode_lock_spin(vp);
472 
473 		while ((vp->v_numoutput > output_target) && error == 0) {
474 			if (output_target) {
475 				vp->v_flag |= VTHROTTLED;
476 			} else {
477 				vp->v_flag |= VBWAIT;
478 			}
479 
480 			ts.tv_sec = (slptimeout / 100);
481 			ts.tv_nsec = (slptimeout % 1000)  * 10 * NSEC_PER_USEC * 1000;
482 			error = msleep((caddr_t)&vp->v_numoutput, &vp->v_lock, (slpflag | (PRIBIO + 1)), msg, &ts);
483 
484 			vnode_lock_spin(vp);
485 		}
486 		vnode_unlock(vp);
487 	}
488 	KERNEL_DEBUG(0x3010280 | DBG_FUNC_END, (int)vp, output_target, vp->v_numoutput, error, 0);
489 
490 	return error;
491 }
492 
493 
494 void
vnode_startwrite(vnode_t vp)495 vnode_startwrite(vnode_t vp)
496 {
497 	OSAddAtomic(1, &vp->v_numoutput);
498 }
499 
500 
501 void
vnode_writedone(vnode_t vp)502 vnode_writedone(vnode_t vp)
503 {
504 	if (vp) {
505 		int need_wakeup = 0;
506 
507 		OSAddAtomic(-1, &vp->v_numoutput);
508 
509 		vnode_lock_spin(vp);
510 
511 		if (vp->v_numoutput < 0) {
512 			panic("vnode_writedone: numoutput < 0");
513 		}
514 
515 		if ((vp->v_flag & VTHROTTLED)) {
516 			vp->v_flag &= ~VTHROTTLED;
517 			need_wakeup = 1;
518 		}
519 		if ((vp->v_flag & VBWAIT) && (vp->v_numoutput == 0)) {
520 			vp->v_flag &= ~VBWAIT;
521 			need_wakeup = 1;
522 		}
523 		vnode_unlock(vp);
524 
525 		if (need_wakeup) {
526 			wakeup((caddr_t)&vp->v_numoutput);
527 		}
528 	}
529 }
530 
531 
532 
533 int
vnode_hasdirtyblks(vnode_t vp)534 vnode_hasdirtyblks(vnode_t vp)
535 {
536 	struct cl_writebehind *wbp;
537 
538 	/*
539 	 * Not taking the buf_mtx as there is little
540 	 * point doing it. Even if the lock is taken the
541 	 * state can change right after that. If their
542 	 * needs to be a synchronization, it must be driven
543 	 * by the caller
544 	 */
545 	if (vp->v_dirtyblkhd.lh_first) {
546 		return 1;
547 	}
548 
549 	if (!UBCINFOEXISTS(vp)) {
550 		return 0;
551 	}
552 
553 	wbp = vp->v_ubcinfo->cl_wbehind;
554 
555 	if (wbp && (wbp->cl_number || wbp->cl_scmap)) {
556 		return 1;
557 	}
558 
559 	return 0;
560 }
561 
562 int
vnode_hascleanblks(vnode_t vp)563 vnode_hascleanblks(vnode_t vp)
564 {
565 	/*
566 	 * Not taking the buf_mtx as there is little
567 	 * point doing it. Even if the lock is taken the
568 	 * state can change right after that. If their
569 	 * needs to be a synchronization, it must be driven
570 	 * by the caller
571 	 */
572 	if (vp->v_cleanblkhd.lh_first) {
573 		return 1;
574 	}
575 	return 0;
576 }
577 
578 void
vnode_iterate_setup(mount_t mp)579 vnode_iterate_setup(mount_t mp)
580 {
581 	mp->mnt_lflag |= MNT_LITER;
582 }
583 
584 int
vnode_umount_preflight(mount_t mp,vnode_t skipvp,int flags)585 vnode_umount_preflight(mount_t mp, vnode_t skipvp, int flags)
586 {
587 	vnode_t vp;
588 	int ret = 0;
589 
590 	TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
591 		if (vp->v_type == VDIR) {
592 			continue;
593 		}
594 		if (vp == skipvp) {
595 			continue;
596 		}
597 		if ((flags & SKIPSYSTEM) && ((vp->v_flag & VSYSTEM) || (vp->v_flag & VNOFLUSH))) {
598 			continue;
599 		}
600 		if ((flags & SKIPSWAP) && (vp->v_flag & VSWAP)) {
601 			continue;
602 		}
603 		if ((flags & WRITECLOSE) && (vp->v_writecount == 0 || vp->v_type != VREG)) {
604 			continue;
605 		}
606 
607 		/* Look for busy vnode */
608 		if ((vp->v_usecount != 0) && ((vp->v_usecount - vp->v_kusecount) != 0)) {
609 			ret = 1;
610 			if (print_busy_vnodes && ((flags & FORCECLOSE) == 0)) {
611 				vprint("vnode_umount_preflight - busy vnode", vp);
612 			} else {
613 				return ret;
614 			}
615 		} else if (vp->v_iocount > 0) {
616 			/* Busy if iocount is > 0 for more than 3 seconds */
617 			tsleep(&vp->v_iocount, PVFS, "vnode_drain_network", 3 * hz);
618 			if (vp->v_iocount > 0) {
619 				ret = 1;
620 				if (print_busy_vnodes && ((flags & FORCECLOSE) == 0)) {
621 					vprint("vnode_umount_preflight - busy vnode", vp);
622 				} else {
623 					return ret;
624 				}
625 			}
626 			continue;
627 		}
628 	}
629 
630 	return ret;
631 }
632 
633 /*
634  * This routine prepares iteration by moving all the vnodes to worker queue
635  * called with mount lock held
636  */
637 int
vnode_iterate_prepare(mount_t mp)638 vnode_iterate_prepare(mount_t mp)
639 {
640 	vnode_t vp;
641 
642 	if (TAILQ_EMPTY(&mp->mnt_vnodelist)) {
643 		/* nothing to do */
644 		return 0;
645 	}
646 
647 	vp = TAILQ_FIRST(&mp->mnt_vnodelist);
648 	vp->v_mntvnodes.tqe_prev = &(mp->mnt_workerqueue.tqh_first);
649 	mp->mnt_workerqueue.tqh_first = mp->mnt_vnodelist.tqh_first;
650 	mp->mnt_workerqueue.tqh_last = mp->mnt_vnodelist.tqh_last;
651 
652 	TAILQ_INIT(&mp->mnt_vnodelist);
653 	if (mp->mnt_newvnodes.tqh_first != NULL) {
654 		panic("vnode_iterate_prepare: newvnode when entering vnode");
655 	}
656 	TAILQ_INIT(&mp->mnt_newvnodes);
657 
658 	return 1;
659 }
660 
661 
662 /* called with mount lock held */
663 int
vnode_iterate_reloadq(mount_t mp)664 vnode_iterate_reloadq(mount_t mp)
665 {
666 	int moved = 0;
667 
668 	/* add the remaining entries in workerq to the end of mount vnode list */
669 	if (!TAILQ_EMPTY(&mp->mnt_workerqueue)) {
670 		struct vnode * mvp;
671 		mvp = TAILQ_LAST(&mp->mnt_vnodelist, vnodelst);
672 
673 		/* Joining the workerque entities to mount vnode list */
674 		if (mvp) {
675 			mvp->v_mntvnodes.tqe_next = mp->mnt_workerqueue.tqh_first;
676 		} else {
677 			mp->mnt_vnodelist.tqh_first = mp->mnt_workerqueue.tqh_first;
678 		}
679 		mp->mnt_workerqueue.tqh_first->v_mntvnodes.tqe_prev = mp->mnt_vnodelist.tqh_last;
680 		mp->mnt_vnodelist.tqh_last = mp->mnt_workerqueue.tqh_last;
681 		TAILQ_INIT(&mp->mnt_workerqueue);
682 	}
683 
684 	/* add the newvnodes to the head of mount vnode list */
685 	if (!TAILQ_EMPTY(&mp->mnt_newvnodes)) {
686 		struct vnode * nlvp;
687 		nlvp = TAILQ_LAST(&mp->mnt_newvnodes, vnodelst);
688 
689 		mp->mnt_newvnodes.tqh_first->v_mntvnodes.tqe_prev = &mp->mnt_vnodelist.tqh_first;
690 		nlvp->v_mntvnodes.tqe_next = mp->mnt_vnodelist.tqh_first;
691 		if (mp->mnt_vnodelist.tqh_first) {
692 			mp->mnt_vnodelist.tqh_first->v_mntvnodes.tqe_prev = &nlvp->v_mntvnodes.tqe_next;
693 		} else {
694 			mp->mnt_vnodelist.tqh_last = mp->mnt_newvnodes.tqh_last;
695 		}
696 		mp->mnt_vnodelist.tqh_first = mp->mnt_newvnodes.tqh_first;
697 		TAILQ_INIT(&mp->mnt_newvnodes);
698 		moved = 1;
699 	}
700 
701 	return moved;
702 }
703 
704 
705 void
vnode_iterate_clear(mount_t mp)706 vnode_iterate_clear(mount_t mp)
707 {
708 	mp->mnt_lflag &= ~MNT_LITER;
709 }
710 
711 #if defined(__x86_64__)
712 
713 #include <i386/panic_hooks.h>
714 
715 struct vnode_iterate_panic_hook {
716 	panic_hook_t hook;
717 	mount_t mp;
718 	struct vnode *vp;
719 };
720 
721 static void
vnode_iterate_panic_hook(panic_hook_t * hook_)722 vnode_iterate_panic_hook(panic_hook_t *hook_)
723 {
724 	struct vnode_iterate_panic_hook *hook = (struct vnode_iterate_panic_hook *)hook_;
725 	panic_phys_range_t range;
726 	uint64_t phys;
727 
728 	if (panic_phys_range_before(hook->mp, &phys, &range)) {
729 		paniclog_append_noflush("mp = %p, phys = %p, prev (%p: %p-%p)\n",
730 		    hook->mp, phys, range.type, range.phys_start,
731 		    range.phys_start + range.len);
732 	} else {
733 		paniclog_append_noflush("mp = %p, phys = %p, prev (!)\n", hook->mp, phys);
734 	}
735 
736 	if (panic_phys_range_before(hook->vp, &phys, &range)) {
737 		paniclog_append_noflush("vp = %p, phys = %p, prev (%p: %p-%p)\n",
738 		    hook->vp, phys, range.type, range.phys_start,
739 		    range.phys_start + range.len);
740 	} else {
741 		paniclog_append_noflush("vp = %p, phys = %p, prev (!)\n", hook->vp, phys);
742 	}
743 	panic_dump_mem((void *)(((vm_offset_t)hook->mp - 4096) & ~4095), 12288);
744 }
745 #endif /* defined(__x86_64__) */
746 
747 int
vnode_iterate(mount_t mp,int flags,int (* callout)(struct vnode *,void *),void * arg)748 vnode_iterate(mount_t mp, int flags, int (*callout)(struct vnode *, void *),
749     void *arg)
750 {
751 	struct vnode *vp;
752 	int vid, retval;
753 	int ret = 0;
754 
755 	/*
756 	 * The mount iterate mutex is held for the duration of the iteration.
757 	 * This can be done by a state flag on the mount structure but we can
758 	 * run into priority inversion issues sometimes.
759 	 * Using a mutex allows us to benefit from the priority donation
760 	 * mechanisms in the kernel for locks. This mutex should never be
761 	 * acquired in spin mode and it should be acquired before attempting to
762 	 * acquire the mount lock.
763 	 */
764 	mount_iterate_lock(mp);
765 
766 	mount_lock(mp);
767 
768 	vnode_iterate_setup(mp);
769 
770 	/* If it returns 0 then there is nothing to do */
771 	retval = vnode_iterate_prepare(mp);
772 
773 	if (retval == 0) {
774 		vnode_iterate_clear(mp);
775 		mount_unlock(mp);
776 		mount_iterate_unlock(mp);
777 		return ret;
778 	}
779 
780 #if defined(__x86_64__)
781 	struct vnode_iterate_panic_hook hook;
782 	hook.mp = mp;
783 	hook.vp = NULL;
784 	panic_hook(&hook.hook, vnode_iterate_panic_hook);
785 #endif
786 	/* iterate over all the vnodes */
787 	while (!TAILQ_EMPTY(&mp->mnt_workerqueue)) {
788 		vp = TAILQ_FIRST(&mp->mnt_workerqueue);
789 #if defined(__x86_64__)
790 		hook.vp = vp;
791 #endif
792 		TAILQ_REMOVE(&mp->mnt_workerqueue, vp, v_mntvnodes);
793 		TAILQ_INSERT_TAIL(&mp->mnt_vnodelist, vp, v_mntvnodes);
794 		vid = vp->v_id;
795 		if ((vp->v_data == NULL) || (vp->v_type == VNON) || (vp->v_mount != mp)) {
796 			continue;
797 		}
798 		vnode_hold(vp);
799 		mount_unlock(mp);
800 
801 		if (vget_internal(vp, vid, (flags | VNODE_NODEAD | VNODE_WITHID | VNODE_NOSUSPEND))) {
802 			mount_lock(mp);
803 			vnode_drop(vp);
804 			continue;
805 		}
806 		vnode_drop(vp);
807 		if (flags & VNODE_RELOAD) {
808 			/*
809 			 * we're reloading the filesystem
810 			 * cast out any inactive vnodes...
811 			 */
812 			if (vnode_reload(vp)) {
813 				/* vnode will be recycled on the refcount drop */
814 				vnode_put(vp);
815 				mount_lock(mp);
816 				continue;
817 			}
818 		}
819 
820 		retval = callout(vp, arg);
821 
822 		switch (retval) {
823 		case VNODE_RETURNED:
824 		case VNODE_RETURNED_DONE:
825 			vnode_put(vp);
826 			if (retval == VNODE_RETURNED_DONE) {
827 				mount_lock(mp);
828 				ret = 0;
829 				goto out;
830 			}
831 			break;
832 
833 		case VNODE_CLAIMED_DONE:
834 			mount_lock(mp);
835 			ret = 0;
836 			goto out;
837 		case VNODE_CLAIMED:
838 		default:
839 			break;
840 		}
841 		mount_lock(mp);
842 	}
843 
844 out:
845 #if defined(__x86_64__)
846 	panic_unhook(&hook.hook);
847 #endif
848 	(void)vnode_iterate_reloadq(mp);
849 	vnode_iterate_clear(mp);
850 	mount_unlock(mp);
851 	mount_iterate_unlock(mp);
852 	return ret;
853 }
854 
855 void
mount_lock_renames(mount_t mp)856 mount_lock_renames(mount_t mp)
857 {
858 	lck_mtx_lock(&mp->mnt_renamelock);
859 }
860 
861 void
mount_unlock_renames(mount_t mp)862 mount_unlock_renames(mount_t mp)
863 {
864 	lck_mtx_unlock(&mp->mnt_renamelock);
865 }
866 
867 void
mount_iterate_lock(mount_t mp)868 mount_iterate_lock(mount_t mp)
869 {
870 	lck_mtx_lock(&mp->mnt_iter_lock);
871 }
872 
873 void
mount_iterate_unlock(mount_t mp)874 mount_iterate_unlock(mount_t mp)
875 {
876 	lck_mtx_unlock(&mp->mnt_iter_lock);
877 }
878 
879 void
mount_lock(mount_t mp)880 mount_lock(mount_t mp)
881 {
882 	lck_mtx_lock(&mp->mnt_mlock);
883 }
884 
885 void
mount_lock_spin(mount_t mp)886 mount_lock_spin(mount_t mp)
887 {
888 	lck_mtx_lock_spin(&mp->mnt_mlock);
889 }
890 
891 void
mount_unlock(mount_t mp)892 mount_unlock(mount_t mp)
893 {
894 	lck_mtx_unlock(&mp->mnt_mlock);
895 }
896 
897 
898 void
mount_ref(mount_t mp,int locked)899 mount_ref(mount_t mp, int locked)
900 {
901 	if (!locked) {
902 		mount_lock_spin(mp);
903 	}
904 
905 	mp->mnt_count++;
906 
907 	if (!locked) {
908 		mount_unlock(mp);
909 	}
910 }
911 
912 
913 void
mount_drop(mount_t mp,int locked)914 mount_drop(mount_t mp, int locked)
915 {
916 	if (!locked) {
917 		mount_lock_spin(mp);
918 	}
919 
920 	mp->mnt_count--;
921 
922 	if (mp->mnt_count == 0 && (mp->mnt_lflag & MNT_LDRAIN)) {
923 		wakeup(&mp->mnt_lflag);
924 	}
925 
926 	if (!locked) {
927 		mount_unlock(mp);
928 	}
929 }
930 
931 
932 int
mount_iterref(mount_t mp,int locked)933 mount_iterref(mount_t mp, int locked)
934 {
935 	int retval = 0;
936 
937 	if (!locked) {
938 		mount_list_lock();
939 	}
940 	if (mp->mnt_iterref < 0) {
941 		retval = 1;
942 	} else {
943 		mp->mnt_iterref++;
944 	}
945 	if (!locked) {
946 		mount_list_unlock();
947 	}
948 	return retval;
949 }
950 
951 int
mount_isdrained(mount_t mp,int locked)952 mount_isdrained(mount_t mp, int locked)
953 {
954 	int retval;
955 
956 	if (!locked) {
957 		mount_list_lock();
958 	}
959 	if (mp->mnt_iterref < 0) {
960 		retval = 1;
961 	} else {
962 		retval = 0;
963 	}
964 	if (!locked) {
965 		mount_list_unlock();
966 	}
967 	return retval;
968 }
969 
970 void
mount_iterdrop(mount_t mp)971 mount_iterdrop(mount_t mp)
972 {
973 	mount_list_lock();
974 	mp->mnt_iterref--;
975 	wakeup(&mp->mnt_iterref);
976 	mount_list_unlock();
977 }
978 
979 void
mount_iterdrain(mount_t mp)980 mount_iterdrain(mount_t mp)
981 {
982 	mount_list_lock();
983 	while (mp->mnt_iterref) {
984 		msleep((caddr_t)&mp->mnt_iterref, &mnt_list_mtx_lock, PVFS, "mount_iterdrain", NULL);
985 	}
986 	/* mount iterations drained */
987 	mp->mnt_iterref = -1;
988 	mount_list_unlock();
989 }
990 void
mount_iterreset(mount_t mp)991 mount_iterreset(mount_t mp)
992 {
993 	mount_list_lock();
994 	if (mp->mnt_iterref == -1) {
995 		mp->mnt_iterref = 0;
996 	}
997 	mount_list_unlock();
998 }
999 
1000 /* always called with  mount lock held */
1001 int
mount_refdrain(mount_t mp)1002 mount_refdrain(mount_t mp)
1003 {
1004 	if (mp->mnt_lflag & MNT_LDRAIN) {
1005 		panic("already in drain");
1006 	}
1007 	mp->mnt_lflag |= MNT_LDRAIN;
1008 
1009 	while (mp->mnt_count) {
1010 		msleep((caddr_t)&mp->mnt_lflag, &mp->mnt_mlock, PVFS, "mount_drain", NULL);
1011 	}
1012 
1013 	if (mp->mnt_vnodelist.tqh_first != NULL) {
1014 		panic("mount_refdrain: dangling vnode");
1015 	}
1016 
1017 	mp->mnt_lflag &= ~MNT_LDRAIN;
1018 
1019 	return 0;
1020 }
1021 
1022 /* Tags the mount point as not supportine extended readdir for NFS exports */
1023 void
mount_set_noreaddirext(mount_t mp)1024 mount_set_noreaddirext(mount_t mp)
1025 {
1026 	mount_lock(mp);
1027 	mp->mnt_kern_flag |= MNTK_DENY_READDIREXT;
1028 	mount_unlock(mp);
1029 }
1030 
1031 /*
1032  * Mark a mount point as busy. Used to synchronize access and to delay
1033  * unmounting.
1034  */
1035 int
vfs_busy(mount_t mp,int flags)1036 vfs_busy(mount_t mp, int flags)
1037 {
1038 restart:
1039 	if (mp->mnt_lflag & MNT_LDEAD) {
1040 		return ENOENT;
1041 	}
1042 
1043 	mount_lock(mp);
1044 
1045 	if (mp->mnt_lflag & MNT_LUNMOUNT) {
1046 		if (flags & LK_NOWAIT || mp->mnt_lflag & MNT_LDEAD) {
1047 			mount_unlock(mp);
1048 			return ENOENT;
1049 		}
1050 
1051 		/*
1052 		 * Since all busy locks are shared except the exclusive
1053 		 * lock granted when unmounting, the only place that a
1054 		 * wakeup needs to be done is at the release of the
1055 		 * exclusive lock at the end of dounmount.
1056 		 */
1057 		mp->mnt_lflag |= MNT_LWAIT;
1058 		msleep((caddr_t)mp, &mp->mnt_mlock, (PVFS | PDROP), "vfsbusy", NULL);
1059 		return ENOENT;
1060 	}
1061 
1062 	mount_unlock(mp);
1063 
1064 	lck_rw_lock_shared(&mp->mnt_rwlock);
1065 
1066 	/*
1067 	 * Until we are granted the rwlock, it's possible for the mount point to
1068 	 * change state, so re-evaluate before granting the vfs_busy.
1069 	 */
1070 	if (mp->mnt_lflag & (MNT_LDEAD | MNT_LUNMOUNT)) {
1071 		lck_rw_done(&mp->mnt_rwlock);
1072 		goto restart;
1073 	}
1074 	return 0;
1075 }
1076 
1077 /*
1078  * Free a busy filesystem.
1079  */
1080 void
vfs_unbusy(mount_t mp)1081 vfs_unbusy(mount_t mp)
1082 {
1083 	lck_rw_done(&mp->mnt_rwlock);
1084 }
1085 
1086 
1087 
1088 static void
vfs_rootmountfailed(mount_t mp)1089 vfs_rootmountfailed(mount_t mp)
1090 {
1091 	mount_list_lock();
1092 	mp->mnt_vtable->vfc_refcount--;
1093 	mount_list_unlock();
1094 
1095 	vfs_unbusy(mp);
1096 
1097 	if (nc_smr_enabled) {
1098 		vfs_smr_synchronize();
1099 	}
1100 
1101 	mount_lock_destroy(mp);
1102 
1103 #if CONFIG_MACF
1104 	mac_mount_label_destroy(mp);
1105 #endif
1106 
1107 	zfree(mount_zone, mp);
1108 }
1109 
1110 /*
1111  * Lookup a filesystem type, and if found allocate and initialize
1112  * a mount structure for it.
1113  *
1114  * Devname is usually updated by mount(8) after booting.
1115  */
1116 static mount_t
vfs_rootmountalloc_internal(struct vfstable * vfsp,const char * devname)1117 vfs_rootmountalloc_internal(struct vfstable *vfsp, const char *devname)
1118 {
1119 	mount_t mp;
1120 
1121 	mp = zalloc_flags(mount_zone, Z_WAITOK | Z_ZERO);
1122 	/* Initialize the default IO constraints */
1123 	mp->mnt_maxreadcnt = mp->mnt_maxwritecnt = MAXPHYS;
1124 	mp->mnt_segreadcnt = mp->mnt_segwritecnt = 32;
1125 	mp->mnt_maxsegreadsize = mp->mnt_maxreadcnt;
1126 	mp->mnt_maxsegwritesize = mp->mnt_maxwritecnt;
1127 	mp->mnt_devblocksize = DEV_BSIZE;
1128 	mp->mnt_alignmentmask = PAGE_MASK;
1129 	mp->mnt_ioqueue_depth = MNT_DEFAULT_IOQUEUE_DEPTH;
1130 	mp->mnt_ioscale = 1;
1131 	mp->mnt_ioflags = 0;
1132 	mp->mnt_realrootvp = NULLVP;
1133 	mp->mnt_authcache_ttl = CACHED_LOOKUP_RIGHT_TTL;
1134 	mp->mnt_throttle_mask = LOWPRI_MAX_NUM_DEV - 1;
1135 	mp->mnt_devbsdunit = 0;
1136 
1137 	mount_lock_init(mp);
1138 	(void)vfs_busy(mp, LK_NOWAIT);
1139 
1140 	TAILQ_INIT(&mp->mnt_vnodelist);
1141 	TAILQ_INIT(&mp->mnt_workerqueue);
1142 	TAILQ_INIT(&mp->mnt_newvnodes);
1143 
1144 	mp->mnt_vtable = vfsp;
1145 	mp->mnt_op = vfsp->vfc_vfsops;
1146 	mp->mnt_flag = MNT_RDONLY | MNT_ROOTFS;
1147 	mp->mnt_vnodecovered = NULLVP;
1148 	//mp->mnt_stat.f_type = vfsp->vfc_typenum;
1149 	mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
1150 
1151 	mount_list_lock();
1152 	vfsp->vfc_refcount++;
1153 	mount_list_unlock();
1154 
1155 	strlcpy(mp->mnt_vfsstat.f_fstypename, vfsp->vfc_name, MFSTYPENAMELEN);
1156 	mp->mnt_vfsstat.f_mntonname[0] = '/';
1157 	/* XXX const poisoning layering violation */
1158 	(void) copystr((const void *)devname, mp->mnt_vfsstat.f_mntfromname, MAXPATHLEN - 1, NULL);
1159 
1160 #if CONFIG_MACF
1161 	mac_mount_label_init(mp);
1162 	mac_mount_label_associate(vfs_context_kernel(), mp);
1163 #endif
1164 	return mp;
1165 }
1166 
1167 errno_t
vfs_rootmountalloc(const char * fstypename,const char * devname,mount_t * mpp)1168 vfs_rootmountalloc(const char *fstypename, const char *devname, mount_t *mpp)
1169 {
1170 	struct vfstable *vfsp;
1171 
1172 	for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
1173 		if (!strncmp(vfsp->vfc_name, fstypename,
1174 		    sizeof(vfsp->vfc_name))) {
1175 			break;
1176 		}
1177 	}
1178 	if (vfsp == NULL) {
1179 		return ENODEV;
1180 	}
1181 
1182 	*mpp = vfs_rootmountalloc_internal(vfsp, devname);
1183 
1184 	if (*mpp) {
1185 		return 0;
1186 	}
1187 
1188 	return ENOMEM;
1189 }
1190 
1191 #define DBG_MOUNTROOT (FSDBG_CODE(DBG_MOUNT, 0))
1192 
1193 /*
1194  * Find an appropriate filesystem to use for the root. If a filesystem
1195  * has not been preselected, walk through the list of known filesystems
1196  * trying those that have mountroot routines, and try them until one
1197  * works or we have tried them all.
1198  */
1199 extern int (*mountroot)(void);
1200 
1201 int
vfs_mountroot(void)1202 vfs_mountroot(void)
1203 {
1204 #if CONFIG_MACF
1205 	struct vnode *vp;
1206 #endif
1207 	struct vfstable *vfsp;
1208 	vfs_context_t ctx = vfs_context_kernel();
1209 	struct vfs_attr vfsattr;
1210 	int     error;
1211 	mount_t mp;
1212 	vnode_t bdevvp_rootvp;
1213 
1214 	/*
1215 	 * Reset any prior "unmounting everything" state.  This handles the
1216 	 * situation where mount root and then unmountall and re-mountroot
1217 	 * a new image (see bsd/kern/imageboot.c).
1218 	 */
1219 	vfs_unmountall_started = vfs_unmountall_finished = 0;
1220 	OSMemoryBarrier();
1221 
1222 	KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_START);
1223 	if (mountroot != NULL) {
1224 		/*
1225 		 * used for netboot which follows a different set of rules
1226 		 */
1227 		error = (*mountroot)();
1228 
1229 		KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, error, 0);
1230 		return error;
1231 	}
1232 	if ((error = bdevvp(rootdev, &rootvp))) {
1233 		printf("vfs_mountroot: can't setup bdevvp\n");
1234 
1235 		KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, error, 1);
1236 		return error;
1237 	}
1238 	/*
1239 	 * 4951998 - code we call in vfc_mountroot may replace rootvp
1240 	 * so keep a local copy for some house keeping.
1241 	 */
1242 	bdevvp_rootvp = rootvp;
1243 
1244 	for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
1245 		if (vfsp->vfc_mountroot == NULL
1246 		    && !ISSET(vfsp->vfc_vfsflags, VFC_VFSCANMOUNTROOT)) {
1247 			continue;
1248 		}
1249 
1250 		mp = vfs_rootmountalloc_internal(vfsp, "root_device");
1251 		mp->mnt_devvp = rootvp;
1252 
1253 		if (vfsp->vfc_mountroot) {
1254 			error = (*vfsp->vfc_mountroot)(mp, rootvp, ctx);
1255 		} else {
1256 			error = VFS_MOUNT(mp, rootvp, 0, ctx);
1257 		}
1258 
1259 		if (!error) {
1260 			if (bdevvp_rootvp != rootvp) {
1261 				/*
1262 				 * rootvp changed...
1263 				 *   bump the iocount and fix up mnt_devvp for the
1264 				 *   new rootvp (it will already have a usecount taken)...
1265 				 *   drop the iocount and the usecount on the orignal
1266 				 *   since we are no longer going to use it...
1267 				 */
1268 				vnode_getwithref(rootvp);
1269 				mp->mnt_devvp = rootvp;
1270 
1271 				vnode_rele(bdevvp_rootvp);
1272 				vnode_put(bdevvp_rootvp);
1273 			}
1274 			mp->mnt_devvp->v_specflags |= SI_MOUNTEDON;
1275 
1276 			vfs_unbusy(mp);
1277 
1278 			mount_list_add(mp);
1279 
1280 			/*
1281 			 *   cache the IO attributes for the underlying physical media...
1282 			 *   an error return indicates the underlying driver doesn't
1283 			 *   support all the queries necessary... however, reasonable
1284 			 *   defaults will have been set, so no reason to bail or care
1285 			 */
1286 			vfs_init_io_attributes(rootvp, mp);
1287 
1288 			if (mp->mnt_ioflags & MNT_IOFLAGS_FUSION_DRIVE) {
1289 				root_is_CF_drive = TRUE;
1290 			}
1291 
1292 			/*
1293 			 * Shadow the VFC_VFSNATIVEXATTR flag to MNTK_EXTENDED_ATTRS.
1294 			 */
1295 			if (mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR) {
1296 				mp->mnt_kern_flag |= MNTK_EXTENDED_ATTRS;
1297 			}
1298 			if (mp->mnt_vtable->vfc_vfsflags & VFC_VFSPREFLIGHT) {
1299 				mp->mnt_kern_flag |= MNTK_UNMOUNT_PREFLIGHT;
1300 			}
1301 
1302 #if defined(XNU_TARGET_OS_OSX)
1303 			uint32_t speed;
1304 
1305 			if (MNTK_VIRTUALDEV & mp->mnt_kern_flag) {
1306 				speed = 128;
1307 			} else if (disk_conditioner_mount_is_ssd(mp)) {
1308 				speed = 7 * 256;
1309 			} else {
1310 				speed = 256;
1311 			}
1312 			vc_progress_setdiskspeed(speed);
1313 #endif /* XNU_TARGET_OS_OSX */
1314 			/*
1315 			 * Probe root file system for additional features.
1316 			 */
1317 			(void)VFS_START(mp, 0, ctx);
1318 
1319 			VFSATTR_INIT(&vfsattr);
1320 			VFSATTR_WANTED(&vfsattr, f_capabilities);
1321 			if (vfs_getattr(mp, &vfsattr, ctx) == 0 &&
1322 			    VFSATTR_IS_SUPPORTED(&vfsattr, f_capabilities)) {
1323 				if ((vfsattr.f_capabilities.capabilities[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_EXTENDED_ATTR) &&
1324 				    (vfsattr.f_capabilities.valid[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_EXTENDED_ATTR)) {
1325 					mp->mnt_kern_flag |= MNTK_EXTENDED_ATTRS;
1326 				}
1327 #if NAMEDSTREAMS
1328 				if ((vfsattr.f_capabilities.capabilities[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_NAMEDSTREAMS) &&
1329 				    (vfsattr.f_capabilities.valid[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_NAMEDSTREAMS)) {
1330 					mp->mnt_kern_flag |= MNTK_NAMED_STREAMS;
1331 				}
1332 #endif
1333 				if ((vfsattr.f_capabilities.capabilities[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_PATH_FROM_ID) &&
1334 				    (vfsattr.f_capabilities.valid[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_PATH_FROM_ID)) {
1335 					mp->mnt_kern_flag |= MNTK_PATH_FROM_ID;
1336 				}
1337 
1338 				if ((vfsattr.f_capabilities.capabilities[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_DIR_HARDLINKS) &&
1339 				    (vfsattr.f_capabilities.valid[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_DIR_HARDLINKS)) {
1340 					mp->mnt_kern_flag |= MNTK_DIR_HARDLINKS;
1341 				}
1342 			}
1343 
1344 			/*
1345 			 * get rid of iocount reference returned
1346 			 * by bdevvp (or picked up by us on the substitued
1347 			 * rootvp)... it (or we) will have also taken
1348 			 * a usecount reference which we want to keep
1349 			 */
1350 			vnode_put(rootvp);
1351 
1352 #if CONFIG_MACF
1353 			if ((vfs_flags(mp) & MNT_MULTILABEL) == 0) {
1354 				KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, 0, 2);
1355 				return 0;
1356 			}
1357 
1358 			error = VFS_ROOT(mp, &vp, ctx);
1359 			if (error) {
1360 				printf("%s() VFS_ROOT() returned %d\n",
1361 				    __func__, error);
1362 				dounmount(mp, MNT_FORCE, 0, ctx);
1363 				goto fail;
1364 			}
1365 			error = vnode_label(mp, NULL, vp, NULL, 0, ctx);
1366 			/*
1367 			 * get rid of reference provided by VFS_ROOT
1368 			 */
1369 			vnode_put(vp);
1370 
1371 			if (error) {
1372 				printf("%s() vnode_label() returned %d\n",
1373 				    __func__, error);
1374 				dounmount(mp, MNT_FORCE, 0, ctx);
1375 				goto fail;
1376 			}
1377 #endif
1378 			KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, 0, 3);
1379 			return 0;
1380 		}
1381 		vfs_rootmountfailed(mp);
1382 #if CONFIG_MACF
1383 fail:
1384 #endif
1385 		if (error != EINVAL) {
1386 			printf("%s_mountroot failed: %d\n", vfsp->vfc_name, error);
1387 		}
1388 	}
1389 	KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, error ? error : ENODEV, 4);
1390 	return ENODEV;
1391 }
1392 
1393 static int
cache_purge_callback(mount_t mp,__unused void * arg)1394 cache_purge_callback(mount_t mp, __unused void * arg)
1395 {
1396 	cache_purgevfs(mp);
1397 	return VFS_RETURNED;
1398 }
1399 
1400 extern lck_rw_t rootvnode_rw_lock;
1401 extern void set_rootvnode(vnode_t);
1402 
1403 
1404 static int
mntonname_fixup_callback(mount_t mp,__unused void * arg)1405 mntonname_fixup_callback(mount_t mp, __unused void *arg)
1406 {
1407 	int error = 0;
1408 
1409 	if ((strncmp(&mp->mnt_vfsstat.f_mntonname[0], "/", sizeof("/")) == 0) ||
1410 	    (strncmp(&mp->mnt_vfsstat.f_mntonname[0], "/dev", sizeof("/dev")) == 0)) {
1411 		return 0;
1412 	}
1413 
1414 	if ((error = vfs_busy(mp, LK_NOWAIT))) {
1415 		printf("vfs_busy failed with %d for %s\n", error, mp->mnt_vfsstat.f_mntonname);
1416 		return -1;
1417 	}
1418 
1419 	size_t pathlen = MAXPATHLEN;
1420 	if ((error = vn_getpath_ext(mp->mnt_vnodecovered, NULL, mp->mnt_vfsstat.f_mntonname, &pathlen, VN_GETPATH_FSENTER))) {
1421 		printf("vn_getpath_ext failed with %d for mnt_vnodecovered of %s\n", error, mp->mnt_vfsstat.f_mntonname);
1422 	}
1423 
1424 	vfs_unbusy(mp);
1425 
1426 	return error;
1427 }
1428 
1429 static int
clear_mntk_backs_root_callback(mount_t mp,__unused void * arg)1430 clear_mntk_backs_root_callback(mount_t mp, __unused void *arg)
1431 {
1432 	lck_rw_lock_exclusive(&mp->mnt_rwlock);
1433 	mp->mnt_kern_flag &= ~MNTK_BACKS_ROOT;
1434 	lck_rw_done(&mp->mnt_rwlock);
1435 	return VFS_RETURNED;
1436 }
1437 
1438 static int
verify_incoming_rootfs(vnode_t * incoming_rootvnodep,vfs_context_t ctx,vfs_switch_root_flags_t flags)1439 verify_incoming_rootfs(vnode_t *incoming_rootvnodep, vfs_context_t ctx,
1440     vfs_switch_root_flags_t flags)
1441 {
1442 	mount_t mp;
1443 	vnode_t tdp;
1444 	vnode_t incoming_rootvnode_with_iocount = *incoming_rootvnodep;
1445 	vnode_t incoming_rootvnode_with_usecount = NULLVP;
1446 	int error = 0;
1447 
1448 	if (vnode_vtype(incoming_rootvnode_with_iocount) != VDIR) {
1449 		printf("Incoming rootfs path not a directory\n");
1450 		error = ENOTDIR;
1451 		goto done;
1452 	}
1453 
1454 	/*
1455 	 * Before we call VFS_ROOT, we have to let go of the iocount already
1456 	 * acquired, but before doing that get a usecount.
1457 	 */
1458 	vnode_ref_ext(incoming_rootvnode_with_iocount, 0, VNODE_REF_FORCE);
1459 	incoming_rootvnode_with_usecount = incoming_rootvnode_with_iocount;
1460 	vnode_lock_spin(incoming_rootvnode_with_usecount);
1461 	if ((mp = incoming_rootvnode_with_usecount->v_mount)) {
1462 		mp->mnt_crossref++;
1463 		vnode_unlock(incoming_rootvnode_with_usecount);
1464 	} else {
1465 		vnode_unlock(incoming_rootvnode_with_usecount);
1466 		printf("Incoming rootfs root vnode does not have associated mount\n");
1467 		error = ENOTDIR;
1468 		goto done;
1469 	}
1470 
1471 	if (vfs_busy(mp, LK_NOWAIT)) {
1472 		printf("Incoming rootfs root vnode mount is busy\n");
1473 		error = ENOENT;
1474 		goto out;
1475 	}
1476 
1477 	vnode_put(incoming_rootvnode_with_iocount);
1478 	incoming_rootvnode_with_iocount = NULLVP;
1479 
1480 	error = VFS_ROOT(mp, &tdp, ctx);
1481 
1482 	if (error) {
1483 		printf("Could not get rootvnode of incoming rootfs\n");
1484 	} else if (tdp != incoming_rootvnode_with_usecount) {
1485 		vnode_put(tdp);
1486 		tdp = NULLVP;
1487 		printf("Incoming rootfs root vnode mount is is not a mountpoint\n");
1488 		error = EINVAL;
1489 		goto out_busy;
1490 	} else {
1491 		incoming_rootvnode_with_iocount = tdp;
1492 		tdp = NULLVP;
1493 	}
1494 
1495 	if ((flags & VFSSR_VIRTUALDEV_PROHIBITED) != 0) {
1496 		if (mp->mnt_kern_flag & MNTK_VIRTUALDEV) {
1497 			error = ENODEV;
1498 		}
1499 		if (error) {
1500 			printf("Incoming rootfs is backed by a virtual device; cannot switch to it");
1501 			goto out_busy;
1502 		}
1503 	}
1504 
1505 out_busy:
1506 	vfs_unbusy(mp);
1507 
1508 out:
1509 	vnode_lock(incoming_rootvnode_with_usecount);
1510 	mp->mnt_crossref--;
1511 	if (mp->mnt_crossref < 0) {
1512 		panic("mount cross refs -ve");
1513 	}
1514 	vnode_unlock(incoming_rootvnode_with_usecount);
1515 
1516 done:
1517 	if (incoming_rootvnode_with_usecount) {
1518 		vnode_rele(incoming_rootvnode_with_usecount);
1519 		incoming_rootvnode_with_usecount = NULLVP;
1520 	}
1521 
1522 	if (error && incoming_rootvnode_with_iocount) {
1523 		vnode_put(incoming_rootvnode_with_iocount);
1524 		incoming_rootvnode_with_iocount = NULLVP;
1525 	}
1526 
1527 	*incoming_rootvnodep = incoming_rootvnode_with_iocount;
1528 	return error;
1529 }
1530 
1531 /*
1532  * vfs_switch_root()
1533  *
1534  * Move the current root volume, and put a different volume at the root.
1535  *
1536  * incoming_vol_old_path: This is the path where the incoming root volume
1537  *	is mounted when this function begins.
1538  * outgoing_vol_new_path: This is the path where the outgoing root volume
1539  *	will be mounted when this function (successfully) ends.
1540  *	Note: Do not use a leading slash.
1541  *
1542  * Volumes mounted at several fixed points (including /dev) will be preserved
1543  * at the same absolute path. That means they will move within the folder
1544  * hierarchy during the pivot operation. For example, /dev before the pivot
1545  * will be at /dev after the pivot.
1546  *
1547  * If any filesystem has MNTK_BACKS_ROOT set, it will be cleared. If the
1548  * incoming root volume is actually a disk image backed by some other
1549  * filesystem, it is the caller's responsibility to re-set MNTK_BACKS_ROOT
1550  * as appropriate.
1551  */
1552 int
vfs_switch_root(const char * incoming_vol_old_path,const char * outgoing_vol_new_path,vfs_switch_root_flags_t flags)1553 vfs_switch_root(const char *incoming_vol_old_path,
1554     const char *outgoing_vol_new_path,
1555     vfs_switch_root_flags_t flags)
1556 {
1557 	// grumble grumble
1558 #define countof(x) (sizeof(x) / sizeof(x[0]))
1559 
1560 	struct preserved_mount {
1561 		vnode_t pm_rootvnode;
1562 		mount_t pm_mount;
1563 		vnode_t pm_new_covered_vp;
1564 		vnode_t pm_old_covered_vp;
1565 		const char *pm_path;
1566 	};
1567 
1568 	vfs_context_t ctx = vfs_context_kernel();
1569 	vnode_t incoming_rootvnode = NULLVP;
1570 	vnode_t outgoing_vol_new_covered_vp = NULLVP;
1571 	vnode_t incoming_vol_old_covered_vp = NULLVP;
1572 	mount_t outgoing = NULL;
1573 	mount_t incoming = NULL;
1574 
1575 	struct preserved_mount devfs = { NULLVP, NULL, NULLVP, NULLVP, "dev" };
1576 	struct preserved_mount preboot = { NULLVP, NULL, NULLVP, NULLVP, "System/Volumes/Preboot" };
1577 	struct preserved_mount recovery = { NULLVP, NULL, NULLVP, NULLVP, "System/Volumes/Recovery" };
1578 	struct preserved_mount vm = { NULLVP, NULL, NULLVP, NULLVP, "System/Volumes/VM" };
1579 	struct preserved_mount update = { NULLVP, NULL, NULLVP, NULLVP, "System/Volumes/Update" };
1580 	struct preserved_mount iscPreboot = { NULLVP, NULL, NULLVP, NULLVP, "System/Volumes/iSCPreboot" };
1581 	struct preserved_mount hardware = { NULLVP, NULL, NULLVP, NULLVP, "System/Volumes/Hardware" };
1582 	struct preserved_mount xarts = { NULLVP, NULL, NULLVP, NULLVP, "System/Volumes/xarts" };
1583 	struct preserved_mount factorylogs = { NULLVP, NULL, NULLVP, NULLVP, "FactoryLogs" };
1584 	struct preserved_mount idiags = { NULLVP, NULL, NULLVP, NULLVP, "System/Volumes/Diags" };
1585 
1586 	struct preserved_mount *preserved[10];
1587 	preserved[0] = &devfs;
1588 	preserved[1] = &preboot;
1589 	preserved[2] = &recovery;
1590 	preserved[3] = &vm;
1591 	preserved[4] = &update;
1592 	preserved[5] = &iscPreboot;
1593 	preserved[6] = &hardware;
1594 	preserved[7] = &xarts;
1595 	preserved[8] = &factorylogs;
1596 	preserved[9] = &idiags;
1597 
1598 	int error;
1599 
1600 	printf("%s : shuffling mount points : %s <-> / <-> %s\n", __FUNCTION__, incoming_vol_old_path, outgoing_vol_new_path);
1601 
1602 	if (outgoing_vol_new_path[0] == '/') {
1603 		// I should have written this to be more helpful and just advance the pointer forward past the slash
1604 		printf("Do not use a leading slash in outgoing_vol_new_path\n");
1605 		return EINVAL;
1606 	}
1607 
1608 	// Set incoming_rootvnode.
1609 	// Find the vnode representing the mountpoint of the new root
1610 	// filesystem. That will be the new root directory.
1611 	error = vnode_lookup(incoming_vol_old_path, 0, &incoming_rootvnode, ctx);
1612 	if (error) {
1613 		printf("Incoming rootfs root vnode not found\n");
1614 		error = ENOENT;
1615 		goto done;
1616 	}
1617 
1618 	/*
1619 	 * This function drops the icoount and sets the vnode to NULL on error.
1620 	 */
1621 	error = verify_incoming_rootfs(&incoming_rootvnode, ctx, flags);
1622 	if (error) {
1623 		goto done;
1624 	}
1625 
1626 	/*
1627 	 * Set outgoing_vol_new_covered_vp.
1628 	 * Find the vnode representing the future mountpoint of the old
1629 	 * root filesystem, inside the directory incoming_rootvnode.
1630 	 * Right now it's at "/incoming_vol_old_path/outgoing_vol_new_path".
1631 	 * soon it will become "/oldrootfs_path_after", which will be covered.
1632 	 */
1633 	error = vnode_lookupat(outgoing_vol_new_path, 0, &outgoing_vol_new_covered_vp, ctx, incoming_rootvnode);
1634 	if (error) {
1635 		printf("Outgoing rootfs path not found, abandoning / switch, error = %d\n", error);
1636 		error = ENOENT;
1637 		goto done;
1638 	}
1639 	if (vnode_vtype(outgoing_vol_new_covered_vp) != VDIR) {
1640 		printf("Outgoing rootfs path is not a directory, abandoning / switch\n");
1641 		error = ENOTDIR;
1642 		goto done;
1643 	}
1644 
1645 	/*
1646 	 * Find the preserved mounts - see if they are mounted. Get their root
1647 	 * vnode if they are. If they aren't, leave rootvnode NULL which will
1648 	 * be the signal to ignore this mount later on.
1649 	 *
1650 	 * Also get preserved mounts' new_covered_vp.
1651 	 * Find the node representing the folder "dev" inside the directory newrootvnode.
1652 	 * Right now it's at "/incoming_vol_old_path/dev".
1653 	 * Soon it will become /dev, which will be covered by the devfs mountpoint.
1654 	 */
1655 	for (size_t i = 0; i < countof(preserved); i++) {
1656 		struct preserved_mount *pmi = preserved[i];
1657 
1658 		error = vnode_lookupat(pmi->pm_path, 0, &pmi->pm_rootvnode, ctx, rootvnode);
1659 		if (error) {
1660 			printf("skipping preserved mountpoint because not found or error: %d: %s\n", error, pmi->pm_path);
1661 			// not fatal. try the next one in the list.
1662 			continue;
1663 		}
1664 		bool is_mountpoint = false;
1665 		vnode_lock_spin(pmi->pm_rootvnode);
1666 		if ((pmi->pm_rootvnode->v_flag & VROOT) != 0) {
1667 			is_mountpoint = true;
1668 		}
1669 		vnode_unlock(pmi->pm_rootvnode);
1670 		if (!is_mountpoint) {
1671 			printf("skipping preserved mountpoint because not a mountpoint: %s\n", pmi->pm_path);
1672 			vnode_put(pmi->pm_rootvnode);
1673 			pmi->pm_rootvnode = NULLVP;
1674 			// not fatal. try the next one in the list.
1675 			continue;
1676 		}
1677 
1678 		error = vnode_lookupat(pmi->pm_path, 0, &pmi->pm_new_covered_vp, ctx, incoming_rootvnode);
1679 		if (error) {
1680 			printf("preserved new mount directory not found or error: %d: %s\n", error, pmi->pm_path);
1681 			error = ENOENT;
1682 			goto done;
1683 		}
1684 		if (vnode_vtype(pmi->pm_new_covered_vp) != VDIR) {
1685 			printf("preserved new mount directory not directory: %s\n", pmi->pm_path);
1686 			error = ENOTDIR;
1687 			goto done;
1688 		}
1689 
1690 		printf("will preserve mountpoint across pivot: /%s\n", pmi->pm_path);
1691 	}
1692 
1693 	/*
1694 	 * --
1695 	 * At this point, everything has been prepared and all error conditions
1696 	 * have been checked. We check everything we can before this point;
1697 	 * from now on we start making destructive changes, and we can't stop
1698 	 * until we reach the end.
1699 	 * ----
1700 	 */
1701 
1702 	/* this usecount is transferred to the mnt_vnodecovered */
1703 	vnode_ref_ext(outgoing_vol_new_covered_vp, 0, VNODE_REF_FORCE);
1704 	/* this usecount is transferred to set_rootvnode */
1705 	vnode_ref_ext(incoming_rootvnode, 0, VNODE_REF_FORCE);
1706 
1707 
1708 	for (size_t i = 0; i < countof(preserved); i++) {
1709 		struct preserved_mount *pmi = preserved[i];
1710 		if (pmi->pm_rootvnode == NULLVP) {
1711 			continue;
1712 		}
1713 
1714 		/* this usecount is transferred to the mnt_vnodecovered */
1715 		vnode_ref_ext(pmi->pm_new_covered_vp, 0, VNODE_REF_FORCE);
1716 
1717 		/* The new_covered_vp is a mountpoint from now on. */
1718 		vnode_lock_spin(pmi->pm_new_covered_vp);
1719 		pmi->pm_new_covered_vp->v_flag |= VMOUNTEDHERE;
1720 		vnode_unlock(pmi->pm_new_covered_vp);
1721 	}
1722 
1723 	/* The outgoing_vol_new_covered_vp is a mountpoint from now on. */
1724 	vnode_lock_spin(outgoing_vol_new_covered_vp);
1725 	outgoing_vol_new_covered_vp->v_flag |= VMOUNTEDHERE;
1726 	vnode_unlock(outgoing_vol_new_covered_vp);
1727 
1728 
1729 	/*
1730 	 * Identify the mount_ts of the mounted filesystems that are being
1731 	 * manipulated: outgoing rootfs, incoming rootfs, and the preserved
1732 	 * mounts.
1733 	 */
1734 	outgoing = rootvnode->v_mount;
1735 	incoming = incoming_rootvnode->v_mount;
1736 	for (size_t i = 0; i < countof(preserved); i++) {
1737 		struct preserved_mount *pmi = preserved[i];
1738 		if (pmi->pm_rootvnode == NULLVP) {
1739 			continue;
1740 		}
1741 
1742 		pmi->pm_mount = pmi->pm_rootvnode->v_mount;
1743 	}
1744 
1745 	lck_rw_lock_exclusive(&rootvnode_rw_lock);
1746 
1747 	/* Setup incoming as the new rootfs */
1748 	lck_rw_lock_exclusive(&incoming->mnt_rwlock);
1749 	incoming_vol_old_covered_vp = incoming->mnt_vnodecovered;
1750 	incoming->mnt_vnodecovered = NULLVP;
1751 	strlcpy(incoming->mnt_vfsstat.f_mntonname, "/", MAXPATHLEN);
1752 	incoming->mnt_flag |= MNT_ROOTFS;
1753 	lck_rw_done(&incoming->mnt_rwlock);
1754 
1755 	/*
1756 	 * The preserved mountpoints will now be moved to
1757 	 * incoming_rootnode/pm_path, and then by the end of the function,
1758 	 * since incoming_rootnode is going to /, the preserved mounts
1759 	 * will be end up back at /pm_path
1760 	 */
1761 	for (size_t i = 0; i < countof(preserved); i++) {
1762 		struct preserved_mount *pmi = preserved[i];
1763 		if (pmi->pm_rootvnode == NULLVP) {
1764 			continue;
1765 		}
1766 
1767 		lck_rw_lock_exclusive(&pmi->pm_mount->mnt_rwlock);
1768 		pmi->pm_old_covered_vp = pmi->pm_mount->mnt_vnodecovered;
1769 		pmi->pm_mount->mnt_vnodecovered = pmi->pm_new_covered_vp;
1770 		vnode_lock_spin(pmi->pm_new_covered_vp);
1771 		pmi->pm_new_covered_vp->v_mountedhere = pmi->pm_mount;
1772 		SET(pmi->pm_new_covered_vp->v_flag, VMOUNTEDHERE);
1773 		vnode_unlock(pmi->pm_new_covered_vp);
1774 		lck_rw_done(&pmi->pm_mount->mnt_rwlock);
1775 	}
1776 
1777 	/*
1778 	 * The old root volume now covers outgoing_vol_new_covered_vp
1779 	 * on the new root volume. Remove the ROOTFS marker.
1780 	 * Now it is to be found at outgoing_vol_new_path
1781 	 */
1782 	lck_rw_lock_exclusive(&outgoing->mnt_rwlock);
1783 	outgoing->mnt_vnodecovered = outgoing_vol_new_covered_vp;
1784 	strlcpy(outgoing->mnt_vfsstat.f_mntonname, "/", MAXPATHLEN);
1785 	strlcat(outgoing->mnt_vfsstat.f_mntonname, outgoing_vol_new_path, MAXPATHLEN);
1786 	outgoing->mnt_flag &= ~MNT_ROOTFS;
1787 	vnode_lock_spin(outgoing_vol_new_covered_vp);
1788 	outgoing_vol_new_covered_vp->v_mountedhere = outgoing;
1789 	vnode_unlock(outgoing_vol_new_covered_vp);
1790 	lck_rw_done(&outgoing->mnt_rwlock);
1791 
1792 	if (!(outgoing->mnt_kern_flag & MNTK_VIRTUALDEV) &&
1793 	    (TAILQ_FIRST(&mountlist) == outgoing)) {
1794 		vfs_setmntsystem(outgoing);
1795 	}
1796 
1797 	/*
1798 	 * Finally, remove the mount_t linkage from the previously covered
1799 	 * vnodes on the old root volume. These were incoming_vol_old_path,
1800 	 * and each preserved mounts's "/pm_path". The filesystems previously
1801 	 * mounted there have already been moved away.
1802 	 */
1803 	vnode_lock_spin(incoming_vol_old_covered_vp);
1804 	incoming_vol_old_covered_vp->v_flag &= ~VMOUNT;
1805 	incoming_vol_old_covered_vp->v_mountedhere = NULL;
1806 	vnode_unlock(incoming_vol_old_covered_vp);
1807 
1808 	for (size_t i = 0; i < countof(preserved); i++) {
1809 		struct preserved_mount *pmi = preserved[i];
1810 		if (pmi->pm_rootvnode == NULLVP) {
1811 			continue;
1812 		}
1813 
1814 		vnode_lock_spin(pmi->pm_old_covered_vp);
1815 		CLR(pmi->pm_old_covered_vp->v_flag, VMOUNTEDHERE);
1816 		pmi->pm_old_covered_vp->v_mountedhere = NULL;
1817 		vnode_unlock(pmi->pm_old_covered_vp);
1818 	}
1819 
1820 	/*
1821 	 * Clear the name cache since many cached names are now invalid.
1822 	 */
1823 	vfs_iterate(0 /* flags */, cache_purge_callback, NULL);
1824 
1825 	/*
1826 	 * Actually change the rootvnode! And finally drop the lock that
1827 	 * prevents concurrent vnode_lookups.
1828 	 */
1829 	set_rootvnode(incoming_rootvnode);
1830 	lck_rw_unlock_exclusive(&rootvnode_rw_lock);
1831 
1832 	if (!(incoming->mnt_kern_flag & MNTK_VIRTUALDEV) &&
1833 	    !(outgoing->mnt_kern_flag & MNTK_VIRTUALDEV)) {
1834 		/*
1835 		 * Switch the order of mount structures in the mountlist, new root
1836 		 * mount moves to the head of the list followed by /dev and the other
1837 		 * preserved mounts then all the preexisting mounts (old rootfs + any
1838 		 * others)
1839 		 */
1840 		mount_list_lock();
1841 		for (size_t i = 0; i < countof(preserved); i++) {
1842 			struct preserved_mount *pmi = preserved[i];
1843 			if (pmi->pm_rootvnode == NULLVP) {
1844 				continue;
1845 			}
1846 
1847 			TAILQ_REMOVE(&mountlist, pmi->pm_mount, mnt_list);
1848 			TAILQ_INSERT_HEAD(&mountlist, pmi->pm_mount, mnt_list);
1849 		}
1850 		TAILQ_REMOVE(&mountlist, incoming, mnt_list);
1851 		TAILQ_INSERT_HEAD(&mountlist, incoming, mnt_list);
1852 		mount_list_unlock();
1853 	}
1854 
1855 	/*
1856 	 * Fixups across all volumes
1857 	 */
1858 	vfs_iterate(0 /* flags */, mntonname_fixup_callback, NULL);
1859 	vfs_iterate(0 /* flags */, clear_mntk_backs_root_callback, NULL);
1860 
1861 	error = 0;
1862 
1863 done:
1864 	for (size_t i = 0; i < countof(preserved); i++) {
1865 		struct preserved_mount *pmi = preserved[i];
1866 
1867 		if (pmi->pm_rootvnode) {
1868 			vnode_put(pmi->pm_rootvnode);
1869 		}
1870 		if (pmi->pm_new_covered_vp) {
1871 			vnode_put(pmi->pm_new_covered_vp);
1872 		}
1873 		if (pmi->pm_old_covered_vp) {
1874 			vnode_rele(pmi->pm_old_covered_vp);
1875 		}
1876 	}
1877 
1878 	if (outgoing_vol_new_covered_vp) {
1879 		vnode_put(outgoing_vol_new_covered_vp);
1880 	}
1881 
1882 	if (incoming_vol_old_covered_vp) {
1883 		vnode_rele(incoming_vol_old_covered_vp);
1884 	}
1885 
1886 	if (incoming_rootvnode) {
1887 		vnode_put(incoming_rootvnode);
1888 	}
1889 
1890 	printf("%s : done shuffling mount points with error: %d\n", __FUNCTION__, error);
1891 	return error;
1892 }
1893 
1894 /*
1895  * Mount the Recovery volume of a container
1896  */
1897 int
vfs_mount_recovery(void)1898 vfs_mount_recovery(void)
1899 {
1900 #if CONFIG_MOUNT_PREBOOTRECOVERY
1901 	int error = 0;
1902 
1903 	error = vnode_get(rootvnode);
1904 	if (error) {
1905 		/* root must be mounted first */
1906 		printf("vnode_get(rootvnode) failed with error %d\n", error);
1907 		return error;
1908 	}
1909 
1910 	char recoverypath[] = PLATFORM_RECOVERY_VOLUME_MOUNT_POINT; /* !const because of internal casting */
1911 
1912 	/* Mount the recovery volume */
1913 	printf("attempting kernel mount for recovery volume... \n");
1914 	error = kernel_mount(rootvnode->v_mount->mnt_vfsstat.f_fstypename, NULLVP, NULLVP,
1915 	    recoverypath, (rootvnode->v_mount), 0, 0, (KERNEL_MOUNT_RECOVERYVOL), vfs_context_kernel());
1916 
1917 	if (error) {
1918 		printf("Failed to mount recovery volume (%d)\n", error);
1919 	} else {
1920 		printf("mounted recovery volume\n");
1921 	}
1922 
1923 	vnode_put(rootvnode);
1924 	return error;
1925 #else
1926 	return 0;
1927 #endif
1928 }
1929 
1930 /*
1931  * Lookup a mount point by filesystem identifier.
1932  */
1933 
1934 struct mount *
vfs_getvfs(fsid_t * fsid)1935 vfs_getvfs(fsid_t *fsid)
1936 {
1937 	return mount_list_lookupby_fsid(fsid, 0, 0);
1938 }
1939 
1940 static struct mount *
vfs_getvfs_locked(fsid_t * fsid)1941 vfs_getvfs_locked(fsid_t *fsid)
1942 {
1943 	return mount_list_lookupby_fsid(fsid, 1, 0);
1944 }
1945 
1946 struct mount *
vfs_getvfs_with_vfsops(fsid_t * fsid,const struct vfsops * const ops)1947 vfs_getvfs_with_vfsops(fsid_t *fsid, const struct vfsops * const ops)
1948 {
1949 	mount_t mp = mount_list_lookupby_fsid(fsid, 0, 0);
1950 
1951 	if (mp != NULL && mp->mnt_op != ops) {
1952 		mp = NULL;
1953 	}
1954 	return mp;
1955 }
1956 
1957 struct mount *
vfs_getvfs_by_mntonname(char * path)1958 vfs_getvfs_by_mntonname(char *path)
1959 {
1960 	mount_t retmp = (mount_t)0;
1961 	mount_t mp;
1962 
1963 	mount_list_lock();
1964 	TAILQ_FOREACH(mp, &mountlist, mnt_list) {
1965 		if (!strncmp(mp->mnt_vfsstat.f_mntonname, path,
1966 		    sizeof(mp->mnt_vfsstat.f_mntonname))) {
1967 			retmp = mp;
1968 			if (mount_iterref(retmp, 1)) {
1969 				retmp = NULL;
1970 			}
1971 			goto out;
1972 		}
1973 	}
1974 out:
1975 	mount_list_unlock();
1976 	return retmp;
1977 }
1978 
1979 /* generation number for creation of new fsids */
1980 u_short mntid_gen = 0;
1981 /*
1982  * Get a new unique fsid
1983  */
1984 void
vfs_getnewfsid(struct mount * mp)1985 vfs_getnewfsid(struct mount *mp)
1986 {
1987 	fsid_t tfsid;
1988 	int mtype;
1989 
1990 	mount_list_lock();
1991 
1992 	/* generate a new fsid */
1993 	mtype = mp->mnt_vtable->vfc_typenum;
1994 	if (++mntid_gen == 0) {
1995 		mntid_gen++;
1996 	}
1997 	tfsid.val[0] = makedev(nblkdev + mtype, mntid_gen);
1998 	tfsid.val[1] = mtype;
1999 
2000 	while (vfs_getvfs_locked(&tfsid)) {
2001 		if (++mntid_gen == 0) {
2002 			mntid_gen++;
2003 		}
2004 		tfsid.val[0] = makedev(nblkdev + mtype, mntid_gen);
2005 	}
2006 
2007 	mp->mnt_vfsstat.f_fsid.val[0] = tfsid.val[0];
2008 	mp->mnt_vfsstat.f_fsid.val[1] = tfsid.val[1];
2009 	mount_list_unlock();
2010 }
2011 
2012 /*
2013  * Routines having to do with the management of the vnode table.
2014  */
2015 extern int(**dead_vnodeop_p)(void *);
2016 long numvnodes, freevnodes, deadvnodes, async_work_vnodes;
2017 long busyvnodes = 0;
2018 long deadvnodes_noreuse = 0;
2019 int32_t freeablevnodes = 0;
2020 uint64_t allocedvnodes = 0;
2021 uint64_t deallocedvnodes = 0;
2022 
2023 
2024 int async_work_timed_out = 0;
2025 int async_work_handled = 0;
2026 int dead_vnode_wanted = 0;
2027 int dead_vnode_waited = 0;
2028 
2029 /*
2030  * Move a vnode from one mount queue to another.
2031  */
2032 static void
insmntque(vnode_t vp,mount_t mp)2033 insmntque(vnode_t vp, mount_t mp)
2034 {
2035 	mount_t lmp;
2036 	/*
2037 	 * Delete from old mount point vnode list, if on one.
2038 	 */
2039 	if ((lmp = vp->v_mount) != NULL && lmp != dead_mountp) {
2040 		if ((vp->v_lflag & VNAMED_MOUNT) == 0) {
2041 			panic("insmntque: vp not in mount vnode list");
2042 		}
2043 		vp->v_lflag &= ~VNAMED_MOUNT;
2044 
2045 		mount_lock_spin(lmp);
2046 
2047 		mount_drop(lmp, 1);
2048 
2049 		if (vp->v_mntvnodes.tqe_next == NULL) {
2050 			if (TAILQ_LAST(&lmp->mnt_vnodelist, vnodelst) == vp) {
2051 				TAILQ_REMOVE(&lmp->mnt_vnodelist, vp, v_mntvnodes);
2052 			} else if (TAILQ_LAST(&lmp->mnt_newvnodes, vnodelst) == vp) {
2053 				TAILQ_REMOVE(&lmp->mnt_newvnodes, vp, v_mntvnodes);
2054 			} else if (TAILQ_LAST(&lmp->mnt_workerqueue, vnodelst) == vp) {
2055 				TAILQ_REMOVE(&lmp->mnt_workerqueue, vp, v_mntvnodes);
2056 			}
2057 		} else {
2058 			vp->v_mntvnodes.tqe_next->v_mntvnodes.tqe_prev = vp->v_mntvnodes.tqe_prev;
2059 			*vp->v_mntvnodes.tqe_prev = vp->v_mntvnodes.tqe_next;
2060 		}
2061 		vp->v_mntvnodes.tqe_next = NULL;
2062 		vp->v_mntvnodes.tqe_prev = NULL;
2063 		mount_unlock(lmp);
2064 		vnode_drop(vp);
2065 		return;
2066 	}
2067 
2068 	/*
2069 	 * Insert into list of vnodes for the new mount point, if available.
2070 	 */
2071 	if ((vp->v_mount = mp) != NULL) {
2072 		mount_lock_spin(mp);
2073 		if ((vp->v_mntvnodes.tqe_next != 0) && (vp->v_mntvnodes.tqe_prev != 0)) {
2074 			panic("vp already in mount list");
2075 		}
2076 		if (mp->mnt_lflag & MNT_LITER) {
2077 			TAILQ_INSERT_HEAD(&mp->mnt_newvnodes, vp, v_mntvnodes);
2078 		} else {
2079 			TAILQ_INSERT_HEAD(&mp->mnt_vnodelist, vp, v_mntvnodes);
2080 		}
2081 		if (vp->v_lflag & VNAMED_MOUNT) {
2082 			panic("insmntque: vp already in mount vnode list");
2083 		}
2084 		vnode_hold(vp);
2085 		vp->v_lflag |= VNAMED_MOUNT;
2086 		mount_ref(mp, 1);
2087 		mount_unlock(mp);
2088 	}
2089 }
2090 
2091 
2092 /*
2093  * Create a vnode for a block device.
2094  * Used for root filesystem, argdev, and swap areas.
2095  * Also used for memory file system special devices.
2096  */
2097 int
bdevvp(dev_t dev,vnode_t * vpp)2098 bdevvp(dev_t dev, vnode_t *vpp)
2099 {
2100 	vnode_t nvp;
2101 	int     error;
2102 	struct vnode_fsparam vfsp;
2103 	struct vfs_context context;
2104 
2105 	if (dev == NODEV) {
2106 		*vpp = NULLVP;
2107 		return ENODEV;
2108 	}
2109 
2110 	context.vc_thread = current_thread();
2111 	context.vc_ucred = FSCRED;
2112 
2113 	vfsp.vnfs_mp = (struct mount *)0;
2114 	vfsp.vnfs_vtype = VBLK;
2115 	vfsp.vnfs_str = "bdevvp";
2116 	vfsp.vnfs_dvp = NULL;
2117 	vfsp.vnfs_fsnode = NULL;
2118 	vfsp.vnfs_cnp = NULL;
2119 	vfsp.vnfs_vops = spec_vnodeop_p;
2120 	vfsp.vnfs_rdev = dev;
2121 	vfsp.vnfs_filesize = 0;
2122 
2123 	vfsp.vnfs_flags = VNFS_NOCACHE | VNFS_CANTCACHE;
2124 
2125 	vfsp.vnfs_marksystem = 0;
2126 	vfsp.vnfs_markroot = 0;
2127 
2128 	if ((error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &vfsp, &nvp))) {
2129 		*vpp = NULLVP;
2130 		return error;
2131 	}
2132 	vnode_lock_spin(nvp);
2133 	nvp->v_flag |= VBDEVVP;
2134 	nvp->v_tag = VT_NON;    /* set this to VT_NON so during aliasing it can be replaced */
2135 	vnode_unlock(nvp);
2136 	if ((error = vnode_ref(nvp))) {
2137 		panic("bdevvp failed: vnode_ref");
2138 		return error;
2139 	}
2140 	if ((error = VNOP_FSYNC(nvp, MNT_WAIT, &context))) {
2141 		panic("bdevvp failed: fsync");
2142 		return error;
2143 	}
2144 	if ((error = buf_invalidateblks(nvp, BUF_WRITE_DATA, 0, 0))) {
2145 		panic("bdevvp failed: invalidateblks");
2146 		return error;
2147 	}
2148 
2149 #if CONFIG_MACF
2150 	/*
2151 	 * XXXMAC: We can't put a MAC check here, the system will
2152 	 * panic without this vnode.
2153 	 */
2154 #endif /* MAC */
2155 
2156 	if ((error = VNOP_OPEN(nvp, FREAD, &context))) {
2157 		panic("bdevvp failed: open");
2158 		return error;
2159 	}
2160 	*vpp = nvp;
2161 
2162 	return 0;
2163 }
2164 
2165 /*
2166  * Check to see if the new vnode represents a special device
2167  * for which we already have a vnode (either because of
2168  * bdevvp() or because of a different vnode representing
2169  * the same block device). If such an alias exists, deallocate
2170  * the existing contents and return the aliased vnode. The
2171  * caller is responsible for filling it with its new contents.
2172  */
2173 static vnode_t
checkalias(struct vnode * nvp,dev_t nvp_rdev)2174 checkalias(struct vnode *nvp, dev_t nvp_rdev)
2175 {
2176 	struct vnode *vp;
2177 	struct vnode **vpp;
2178 	struct specinfo *sin = NULL;
2179 	int vid = 0;
2180 
2181 	vpp = &speclisth[SPECHASH(nvp_rdev)];
2182 loop:
2183 	SPECHASH_LOCK();
2184 
2185 	for (vp = *vpp; vp; vp = vp->v_specnext) {
2186 		if (nvp_rdev == vp->v_rdev && nvp->v_type == vp->v_type) {
2187 			vid = vp->v_id;
2188 			vnode_hold(vp);
2189 			break;
2190 		}
2191 	}
2192 	SPECHASH_UNLOCK();
2193 
2194 	if (vp) {
2195 found_alias:
2196 		if (vnode_getwithvid(vp, vid)) {
2197 			vnode_drop(vp);
2198 			goto loop;
2199 		}
2200 		vnode_drop(vp);
2201 		/*
2202 		 * Termination state is checked in vnode_getwithvid
2203 		 */
2204 		vnode_lock(vp);
2205 
2206 		/*
2207 		 * Alias, but not in use, so flush it out.
2208 		 */
2209 		if ((vp->v_iocount == 1) && (vp->v_usecount == 0)) {
2210 			vnode_hold(vp);
2211 			vnode_reclaim_internal(vp, 1, 1, 0);
2212 			vnode_put_locked(vp);
2213 			vnode_drop_and_unlock(vp);
2214 			goto loop;
2215 		}
2216 	}
2217 	if (vp == NULL || vp->v_tag != VT_NON) {
2218 		if (sin == NULL) {
2219 			sin = zalloc_flags(specinfo_zone, Z_WAITOK | Z_ZERO);
2220 		} else {
2221 			bzero(sin, sizeof(struct specinfo));
2222 		}
2223 
2224 		nvp->v_specinfo = sin;
2225 		nvp->v_rdev = nvp_rdev;
2226 		nvp->v_specflags = 0;
2227 		nvp->v_speclastr = -1;
2228 		nvp->v_specinfo->si_opencount = 0;
2229 		nvp->v_specinfo->si_initted = 0;
2230 		nvp->v_specinfo->si_throttleable = 0;
2231 		nvp->v_specinfo->si_devbsdunit = LOWPRI_MAX_NUM_DEV;
2232 
2233 		SPECHASH_LOCK();
2234 
2235 		/* We dropped the lock, someone could have added */
2236 		if (vp == NULLVP) {
2237 			for (vp = *vpp; vp; vp = vp->v_specnext) {
2238 				if (nvp_rdev == vp->v_rdev && nvp->v_type == vp->v_type) {
2239 					vid = vp->v_id;
2240 					vnode_hold(vp);
2241 					SPECHASH_UNLOCK();
2242 					goto found_alias;
2243 				}
2244 			}
2245 		}
2246 
2247 		nvp->v_hashchain = vpp;
2248 		nvp->v_specnext = *vpp;
2249 		*vpp = nvp;
2250 
2251 		if (vp != NULLVP) {
2252 			nvp->v_specflags |= SI_ALIASED;
2253 			vp->v_specflags |= SI_ALIASED;
2254 			SPECHASH_UNLOCK();
2255 			vnode_put_locked(vp);
2256 			vnode_unlock(vp);
2257 		} else {
2258 			SPECHASH_UNLOCK();
2259 		}
2260 
2261 		return NULLVP;
2262 	}
2263 
2264 	if (sin) {
2265 		zfree(specinfo_zone, sin);
2266 	}
2267 
2268 	if ((vp->v_flag & (VBDEVVP | VDEVFLUSH)) != 0) {
2269 		return vp;
2270 	}
2271 
2272 	panic("checkalias with VT_NON vp that shouldn't: %p", vp);
2273 
2274 	return vp;
2275 }
2276 
2277 
2278 /*
2279  * Get a reference on a particular vnode and lock it if requested.
2280  * If the vnode was on the inactive list, remove it from the list.
2281  * If the vnode was on the free list, remove it from the list and
2282  * move it to inactive list as needed.
2283  * The vnode lock bit is set if the vnode is being eliminated in
2284  * vgone. The process is awakened when the transition is completed,
2285  * and an error returned to indicate that the vnode is no longer
2286  * usable (possibly having been changed to a new file system type).
2287  */
2288 int
vget_internal(vnode_t vp,int vid,int vflags)2289 vget_internal(vnode_t vp, int vid, int vflags)
2290 {
2291 	int error = 0;
2292 
2293 	vnode_lock_spin(vp);
2294 
2295 	if ((vflags & VNODE_WRITEABLE) && (vp->v_writecount == 0)) {
2296 		/*
2297 		 * vnode to be returned only if it has writers opened
2298 		 */
2299 		error = EINVAL;
2300 	} else {
2301 		error = vnode_getiocount(vp, vid, vflags);
2302 	}
2303 
2304 	vnode_unlock(vp);
2305 
2306 	return error;
2307 }
2308 
2309 /*
2310  * Returns:	0			Success
2311  *		ENOENT			No such file or directory [terminating]
2312  */
2313 int
vnode_ref(vnode_t vp)2314 vnode_ref(vnode_t vp)
2315 {
2316 	return vnode_ref_ext(vp, 0, 0);
2317 }
2318 
2319 /*
2320  * Returns:	0			Success
2321  *		ENOENT			No such file or directory [terminating]
2322  */
2323 int
vnode_ref_ext(vnode_t vp,int fmode,int flags)2324 vnode_ref_ext(vnode_t vp, int fmode, int flags)
2325 {
2326 	int     error = 0;
2327 
2328 	vnode_lock_spin(vp);
2329 
2330 	/*
2331 	 * once all the current call sites have been fixed to insure they have
2332 	 * taken an iocount, we can toughen this assert up and insist that the
2333 	 * iocount is non-zero... a non-zero usecount doesn't insure correctness
2334 	 */
2335 	if (vp->v_iocount <= 0 && vp->v_usecount <= 0) {
2336 		panic("vnode_ref_ext: vp %p has no valid reference %d, %d", vp, vp->v_iocount, vp->v_usecount);
2337 	}
2338 
2339 	/*
2340 	 * if you are the owner of drain/termination, can acquire usecount
2341 	 */
2342 	if ((flags & VNODE_REF_FORCE) == 0) {
2343 		if ((vp->v_lflag & (VL_DRAIN | VL_TERMINATE | VL_DEAD))) {
2344 			if (vp->v_owner != current_thread()) {
2345 				error = ENOENT;
2346 				goto out;
2347 			}
2348 		}
2349 	}
2350 
2351 	/* Enable atomic ops on v_usecount without the vnode lock */
2352 	os_atomic_inc(&vp->v_usecount, relaxed);
2353 
2354 	if (fmode & FWRITE) {
2355 		if (++vp->v_writecount <= 0) {
2356 			panic("vnode_ref_ext: v_writecount");
2357 		}
2358 	}
2359 	if (fmode & O_EVTONLY) {
2360 		if (++vp->v_kusecount <= 0) {
2361 			panic("vnode_ref_ext: v_kusecount");
2362 		}
2363 	}
2364 	if (vp->v_flag & VRAGE) {
2365 		struct  uthread *ut;
2366 
2367 		ut = current_uthread();
2368 
2369 		if (!(current_proc()->p_lflag & P_LRAGE_VNODES) &&
2370 		    !(ut->uu_flag & UT_RAGE_VNODES)) {
2371 			/*
2372 			 * a 'normal' process accessed this vnode
2373 			 * so make sure its no longer marked
2374 			 * for rapid aging...  also, make sure
2375 			 * it gets removed from the rage list...
2376 			 * when v_usecount drops back to 0, it
2377 			 * will be put back on the real free list
2378 			 */
2379 			vp->v_flag &= ~VRAGE;
2380 			vp->v_references = 0;
2381 			vnode_list_remove(vp);
2382 		}
2383 	}
2384 	if (vp->v_usecount == 1 && vp->v_type == VREG && !(vp->v_flag & VSYSTEM)) {
2385 		if (vp->v_ubcinfo) {
2386 			vnode_lock_convert(vp);
2387 			memory_object_mark_used(vp->v_ubcinfo->ui_control);
2388 		}
2389 	}
2390 out:
2391 	vnode_unlock(vp);
2392 
2393 	return error;
2394 }
2395 
2396 
2397 boolean_t
vnode_on_reliable_media(vnode_t vp)2398 vnode_on_reliable_media(vnode_t vp)
2399 {
2400 	mount_t mp = vp->v_mount;
2401 
2402 	/*
2403 	 * A NULL mountpoint would imply it's not attached to a any filesystem.
2404 	 * This can only happen with a vnode created by bdevvp(). We'll consider
2405 	 * those as not unreliable as the primary use of this function is determine
2406 	 * which vnodes are to be handed off to the async cleaner thread for
2407 	 * reclaim.
2408 	 */
2409 	if (!mp || (!(mp->mnt_kern_flag & MNTK_VIRTUALDEV) && (mp->mnt_flag & MNT_LOCAL))) {
2410 		return TRUE;
2411 	}
2412 
2413 	return FALSE;
2414 }
2415 
2416 static void
vnode_async_list_add_locked(vnode_t vp)2417 vnode_async_list_add_locked(vnode_t vp)
2418 {
2419 	if (VONLIST(vp) || (vp->v_lflag & (VL_TERMINATE | VL_DEAD))) {
2420 		panic("vnode_async_list_add: %p is in wrong state", vp);
2421 	}
2422 
2423 	TAILQ_INSERT_HEAD(&vnode_async_work_list, vp, v_freelist);
2424 	vp->v_listflag |= VLIST_ASYNC_WORK;
2425 
2426 	async_work_vnodes++;
2427 	if (!(vp->v_listflag & VLIST_NO_REUSE)) {
2428 		reusablevnodes++;
2429 	}
2430 	if (vp->v_flag & VCANDEALLOC) {
2431 		os_atomic_dec(&busyvnodes, relaxed);
2432 	}
2433 }
2434 
2435 static void
vnode_async_list_add(vnode_t vp)2436 vnode_async_list_add(vnode_t vp)
2437 {
2438 	vnode_list_lock();
2439 
2440 	if (VONLIST(vp)) {
2441 		if (!(vp->v_listflag & VLIST_ASYNC_WORK)) {
2442 			vnode_list_remove_locked(vp);
2443 			vnode_async_list_add_locked(vp);
2444 		}
2445 	} else {
2446 		vnode_async_list_add_locked(vp);
2447 	}
2448 
2449 	vnode_list_unlock();
2450 
2451 	wakeup(&vnode_async_work_list);
2452 }
2453 
2454 
2455 /*
2456  * put the vnode on appropriate free list.
2457  * called with vnode LOCKED
2458  */
2459 static void
vnode_list_add(vnode_t vp)2460 vnode_list_add(vnode_t vp)
2461 {
2462 	boolean_t need_dead_wakeup = FALSE;
2463 	bool no_busy_decrement = false;
2464 
2465 #if DIAGNOSTIC
2466 	lck_mtx_assert(&vp->v_lock, LCK_MTX_ASSERT_OWNED);
2467 #endif
2468 
2469 again:
2470 
2471 	/*
2472 	 * if it is already on a list or non zero references return
2473 	 */
2474 	if (VONLIST(vp) || (vp->v_usecount != 0) || (vp->v_iocount != 0) || (vp->v_lflag & VL_TERMINATE)) {
2475 		return;
2476 	}
2477 
2478 	/*
2479 	 * In vclean, we might have deferred ditching locked buffers
2480 	 * because something was still referencing them (indicated by
2481 	 * usecount).  We can ditch them now.
2482 	 */
2483 	if (ISSET(vp->v_lflag, VL_DEAD)
2484 	    && (!LIST_EMPTY(&vp->v_cleanblkhd) || !LIST_EMPTY(&vp->v_dirtyblkhd))) {
2485 		++vp->v_iocount;        // Probably not necessary, but harmless
2486 #ifdef CONFIG_IOCOUNT_TRACE
2487 		record_vp(vp, 1);
2488 #endif
2489 		vnode_unlock(vp);
2490 		buf_invalidateblks(vp, BUF_INVALIDATE_LOCKED, 0, 0);
2491 		vnode_lock(vp);
2492 		vnode_dropiocount(vp);
2493 		goto again;
2494 	}
2495 
2496 	vnode_list_lock();
2497 
2498 	if (!(vp->v_lflag & VL_DEAD) && (vp->v_listflag & VLIST_NO_REUSE)) {
2499 		if (!(vp->v_listflag & VLIST_ASYNC_WORK)) {
2500 			vnode_async_list_add_locked(vp);
2501 		}
2502 		no_busy_decrement = true;
2503 	} else if ((vp->v_flag & VRAGE) && !(vp->v_lflag & VL_DEAD)) {
2504 		/*
2505 		 * add the new guy to the appropriate end of the RAGE list
2506 		 */
2507 		if ((vp->v_flag & VAGE)) {
2508 			TAILQ_INSERT_HEAD(&vnode_rage_list, vp, v_freelist);
2509 		} else {
2510 			TAILQ_INSERT_TAIL(&vnode_rage_list, vp, v_freelist);
2511 		}
2512 
2513 		vp->v_listflag |= VLIST_RAGE;
2514 		ragevnodes++;
2515 		reusablevnodes++;
2516 		wakeup_laundry_thread();
2517 
2518 		/*
2519 		 * reset the timestamp for the last inserted vp on the RAGE
2520 		 * queue to let new_vnode know that its not ok to start stealing
2521 		 * from this list... as long as we're actively adding to this list
2522 		 * we'll push out the vnodes we want to donate to the real free list
2523 		 * once we stop pushing, we'll let some time elapse before we start
2524 		 * stealing them in the new_vnode routine
2525 		 */
2526 		microuptime(&rage_tv);
2527 	} else {
2528 		/*
2529 		 * if VL_DEAD, insert it at head of the dead list
2530 		 * else insert at tail of LRU list or at head if VAGE is set
2531 		 */
2532 		if ((vp->v_lflag & VL_DEAD)) {
2533 			if (vp->v_flag & VCANDEALLOC) {
2534 				TAILQ_INSERT_TAIL(&vnode_dead_list, vp, v_freelist);
2535 				if (vp->v_listflag & VLIST_NO_REUSE) {
2536 					deadvnodes_noreuse++;
2537 				}
2538 			} else {
2539 				TAILQ_INSERT_HEAD(&vnode_dead_list, vp, v_freelist);
2540 			}
2541 			vp->v_listflag |= VLIST_DEAD;
2542 			deadvnodes++;
2543 
2544 			if (dead_vnode_wanted) {
2545 				dead_vnode_wanted--;
2546 				need_dead_wakeup = TRUE;
2547 			}
2548 		} else if ((vp->v_flag & VAGE)) {
2549 			TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
2550 			vp->v_flag &= ~VAGE;
2551 			freevnodes++;
2552 			reusablevnodes++;
2553 			wakeup_laundry_thread();
2554 		} else {
2555 			TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
2556 			freevnodes++;
2557 			reusablevnodes++;
2558 			wakeup_laundry_thread();
2559 		}
2560 	}
2561 	if ((vp->v_flag & VCANDEALLOC) && !no_busy_decrement) {
2562 		os_atomic_dec(&busyvnodes, relaxed);
2563 	}
2564 	vnode_list_unlock();
2565 
2566 	if (need_dead_wakeup == TRUE) {
2567 		wakeup_one((caddr_t)&dead_vnode_wanted);
2568 	}
2569 }
2570 
2571 
2572 /*
2573  * remove the vnode from appropriate free list.
2574  * called with vnode LOCKED and
2575  * the list lock held
2576  */
2577 static void
vnode_list_remove_locked(vnode_t vp)2578 vnode_list_remove_locked(vnode_t vp)
2579 {
2580 	if (VONLIST(vp)) {
2581 		/*
2582 		 * the v_listflag field is
2583 		 * protected by the vnode_list_lock
2584 		 */
2585 		if (vp->v_listflag & VLIST_RAGE) {
2586 			VREMRAGE("vnode_list_remove", vp);
2587 		} else if (vp->v_listflag & VLIST_DEAD) {
2588 			VREMDEAD("vnode_list_remove", vp);
2589 			wakeup_laundry_thread();
2590 		} else if (vp->v_listflag & VLIST_ASYNC_WORK) {
2591 			VREMASYNC_WORK("vnode_list_remove", vp);
2592 		} else {
2593 			VREMFREE("vnode_list_remove", vp);
2594 		}
2595 		if (vp->v_flag & VCANDEALLOC) {
2596 			os_atomic_inc(&busyvnodes, relaxed);
2597 		}
2598 	}
2599 }
2600 
2601 
2602 /*
2603  * remove the vnode from appropriate free list.
2604  * called with vnode LOCKED
2605  */
2606 static void
vnode_list_remove(vnode_t vp)2607 vnode_list_remove(vnode_t vp)
2608 {
2609 #if DIAGNOSTIC
2610 	lck_mtx_assert(&vp->v_lock, LCK_MTX_ASSERT_OWNED);
2611 #endif
2612 	/*
2613 	 * we want to avoid taking the list lock
2614 	 * in the case where we're not on the free
2615 	 * list... this will be true for most
2616 	 * directories and any currently in use files
2617 	 *
2618 	 * we're guaranteed that we can't go from
2619 	 * the not-on-list state to the on-list
2620 	 * state since we hold the vnode lock...
2621 	 * all calls to vnode_list_add are done
2622 	 * under the vnode lock... so we can
2623 	 * check for that condition (the prevelant one)
2624 	 * without taking the list lock
2625 	 */
2626 	if (VONLIST(vp)) {
2627 		vnode_list_lock();
2628 		/*
2629 		 * however, we're not guaranteed that
2630 		 * we won't go from the on-list state
2631 		 * to the not-on-list state until we
2632 		 * hold the vnode_list_lock... this
2633 		 * is due to "new_vnode" removing vnodes
2634 		 * from the free list uder the list_lock
2635 		 * w/o the vnode lock... so we need to
2636 		 * check again whether we're currently
2637 		 * on the free list
2638 		 */
2639 		vnode_list_remove_locked(vp);
2640 
2641 		vnode_list_unlock();
2642 	}
2643 }
2644 
2645 
2646 void
vnode_rele(vnode_t vp)2647 vnode_rele(vnode_t vp)
2648 {
2649 	vnode_rele_internal(vp, 0, 0, 0);
2650 }
2651 
2652 
2653 void
vnode_rele_ext(vnode_t vp,int fmode,int dont_reenter)2654 vnode_rele_ext(vnode_t vp, int fmode, int dont_reenter)
2655 {
2656 	vnode_rele_internal(vp, fmode, dont_reenter, 0);
2657 }
2658 
2659 
2660 void
vnode_rele_internal(vnode_t vp,int fmode,int dont_reenter,int locked)2661 vnode_rele_internal(vnode_t vp, int fmode, int dont_reenter, int locked)
2662 {
2663 	int32_t old_usecount;
2664 
2665 	if (!locked) {
2666 		vnode_hold(vp);
2667 		vnode_lock_spin(vp);
2668 	}
2669 #if DIAGNOSTIC
2670 	else {
2671 		lck_mtx_assert(&vp->v_lock, LCK_MTX_ASSERT_OWNED);
2672 	}
2673 #endif
2674 	/* Enable atomic ops on v_usecount without the vnode lock */
2675 	old_usecount = os_atomic_dec_orig(&vp->v_usecount, relaxed);
2676 	if (old_usecount < 1) {
2677 		/*
2678 		 * Because we allow atomic ops on usecount (in lookup only, under
2679 		 * specific conditions of already having a usecount) it is
2680 		 * possible that when the vnode is examined, its usecount is
2681 		 * different than what will be printed in this panic message.
2682 		 */
2683 		panic("vnode_rele_ext: vp %p usecount -ve : %d.  v_tag = %d, v_type = %d, v_flag = %x.",
2684 		    vp, old_usecount - 1, vp->v_tag, vp->v_type, vp->v_flag);
2685 	}
2686 
2687 	if (fmode & FWRITE) {
2688 		if (--vp->v_writecount < 0) {
2689 			panic("vnode_rele_ext: vp %p writecount -ve : %d.  v_tag = %d, v_type = %d, v_flag = %x.", vp, vp->v_writecount, vp->v_tag, vp->v_type, vp->v_flag);
2690 		}
2691 	}
2692 	if (fmode & O_EVTONLY) {
2693 		if (--vp->v_kusecount < 0) {
2694 			panic("vnode_rele_ext: vp %p kusecount -ve : %d.  v_tag = %d, v_type = %d, v_flag = %x.", vp, vp->v_kusecount, vp->v_tag, vp->v_type, vp->v_flag);
2695 		}
2696 	}
2697 	if (vp->v_kusecount > vp->v_usecount) {
2698 		panic("vnode_rele_ext: vp %p kusecount(%d) out of balance with usecount(%d).  v_tag = %d, v_type = %d, v_flag = %x.", vp, vp->v_kusecount, vp->v_usecount, vp->v_tag, vp->v_type, vp->v_flag);
2699 	}
2700 
2701 	if ((vp->v_iocount > 0) || (vp->v_usecount > 0)) {
2702 		/*
2703 		 * vnode is still busy... if we're the last
2704 		 * usecount, mark for a future call to VNOP_INACTIVE
2705 		 * when the iocount finally drops to 0
2706 		 */
2707 		if (vp->v_usecount == 0) {
2708 			vp->v_lflag |= VL_NEEDINACTIVE;
2709 			vp->v_flag  &= ~(VNOCACHE_DATA | VRAOFF | VOPENEVT);
2710 		}
2711 		goto done;
2712 	}
2713 	vp->v_flag  &= ~(VNOCACHE_DATA | VRAOFF | VOPENEVT);
2714 
2715 	if (ISSET(vp->v_lflag, VL_TERMINATE | VL_DEAD) || dont_reenter) {
2716 		/*
2717 		 * vnode is being cleaned, or
2718 		 * we've requested that we don't reenter
2719 		 * the filesystem on this release...in
2720 		 * the latter case, we'll mark the vnode aged
2721 		 */
2722 		if (dont_reenter) {
2723 			if (!(vp->v_lflag & (VL_TERMINATE | VL_DEAD | VL_MARKTERM))) {
2724 				vp->v_lflag |= VL_NEEDINACTIVE;
2725 
2726 				if (vnode_on_reliable_media(vp) == FALSE || vp->v_flag & VISDIRTY) {
2727 					vnode_async_list_add(vp);
2728 					goto done;
2729 				}
2730 			}
2731 			vp->v_flag |= VAGE;
2732 		}
2733 		vnode_list_add(vp);
2734 
2735 		goto done;
2736 	}
2737 	/*
2738 	 * at this point both the iocount and usecount
2739 	 * are zero
2740 	 * pick up an iocount so that we can call
2741 	 * VNOP_INACTIVE with the vnode lock unheld
2742 	 */
2743 	vp->v_iocount++;
2744 #ifdef CONFIG_IOCOUNT_TRACE
2745 	record_vp(vp, 1);
2746 #endif
2747 	vp->v_lflag &= ~VL_NEEDINACTIVE;
2748 
2749 	if (UBCINFOEXISTS(vp)) {
2750 		ubc_cs_free_and_vnode_unlock(vp);
2751 	} else {
2752 		vnode_unlock(vp);
2753 	}
2754 
2755 	VNOP_INACTIVE(vp, vfs_context_current());
2756 
2757 	vnode_lock_spin(vp);
2758 
2759 	/*
2760 	 * because we dropped the vnode lock to call VNOP_INACTIVE
2761 	 * the state of the vnode may have changed... we may have
2762 	 * picked up an iocount, usecount or the MARKTERM may have
2763 	 * been set... we need to reevaluate the reference counts
2764 	 * to determine if we can call vnode_reclaim_internal at
2765 	 * this point... if the reference counts are up, we'll pick
2766 	 * up the MARKTERM state when they get subsequently dropped
2767 	 */
2768 	if ((vp->v_iocount == 1) && (vp->v_usecount == 0) &&
2769 	    ((vp->v_lflag & (VL_MARKTERM | VL_TERMINATE | VL_DEAD)) == VL_MARKTERM)) {
2770 		struct  uthread *ut;
2771 
2772 		ut = current_uthread();
2773 
2774 		if (ut->uu_defer_reclaims) {
2775 			vp->v_defer_reclaimlist = ut->uu_vreclaims;
2776 			ut->uu_vreclaims = vp;
2777 			goto done;
2778 		}
2779 		vnode_lock_convert(vp);
2780 		vnode_reclaim_internal(vp, 1, 1, 0);
2781 	}
2782 	vnode_dropiocount(vp);
2783 	vnode_list_add(vp);
2784 done:
2785 	if (vp->v_usecount == 0 && vp->v_type == VREG && !(vp->v_flag & VSYSTEM)) {
2786 		if (vp->v_ubcinfo) {
2787 			vnode_lock_convert(vp);
2788 			memory_object_mark_unused(vp->v_ubcinfo->ui_control, (vp->v_flag & VRAGE) == VRAGE);
2789 		}
2790 	}
2791 	if (!locked) {
2792 		vnode_drop_and_unlock(vp);
2793 	}
2794 	return;
2795 }
2796 
2797 /*
2798  * Remove any vnodes in the vnode table belonging to mount point mp.
2799  *
2800  * If MNT_NOFORCE is specified, there should not be any active ones,
2801  * return error if any are found (nb: this is a user error, not a
2802  * system error). If MNT_FORCE is specified, detach any active vnodes
2803  * that are found.
2804  */
2805 
2806 int
vflush(struct mount * mp,struct vnode * skipvp,int flags)2807 vflush(struct mount *mp, struct vnode *skipvp, int flags)
2808 {
2809 	struct vnode *vp;
2810 	int busy = 0;
2811 	int reclaimed = 0;
2812 	int retval;
2813 	unsigned int vid;
2814 	bool first_try = true;
2815 
2816 	/*
2817 	 * See comments in vnode_iterate() for the rationale for this lock
2818 	 */
2819 	mount_iterate_lock(mp);
2820 
2821 	mount_lock(mp);
2822 	vnode_iterate_setup(mp);
2823 	/*
2824 	 * On regular unmounts(not forced) do a
2825 	 * quick check for vnodes to be in use. This
2826 	 * preserves the caching of vnodes. automounter
2827 	 * tries unmounting every so often to see whether
2828 	 * it is still busy or not.
2829 	 */
2830 	if (((flags & FORCECLOSE) == 0) && ((mp->mnt_kern_flag & MNTK_UNMOUNT_PREFLIGHT) != 0)) {
2831 		if (vnode_umount_preflight(mp, skipvp, flags)) {
2832 			vnode_iterate_clear(mp);
2833 			mount_unlock(mp);
2834 			mount_iterate_unlock(mp);
2835 			return EBUSY;
2836 		}
2837 	}
2838 loop:
2839 	/* If it returns 0 then there is nothing to do */
2840 	retval = vnode_iterate_prepare(mp);
2841 
2842 	if (retval == 0) {
2843 		vnode_iterate_clear(mp);
2844 		mount_unlock(mp);
2845 		mount_iterate_unlock(mp);
2846 		return retval;
2847 	}
2848 
2849 	/* iterate over all the vnodes */
2850 	while (!TAILQ_EMPTY(&mp->mnt_workerqueue)) {
2851 		vp = TAILQ_FIRST(&mp->mnt_workerqueue);
2852 		TAILQ_REMOVE(&mp->mnt_workerqueue, vp, v_mntvnodes);
2853 		TAILQ_INSERT_TAIL(&mp->mnt_vnodelist, vp, v_mntvnodes);
2854 
2855 		if ((vp->v_mount != mp) || (vp == skipvp)) {
2856 			continue;
2857 		}
2858 		vid = vp->v_id;
2859 		mount_unlock(mp);
2860 
2861 		vnode_lock_spin(vp);
2862 
2863 		// If vnode is already terminating, wait for it...
2864 		while (vp->v_id == vid && ISSET(vp->v_lflag, VL_TERMINATE)) {
2865 			vp->v_lflag |= VL_TERMWANT;
2866 			msleep(&vp->v_lflag, &vp->v_lock, PVFS, "vflush", NULL);
2867 		}
2868 
2869 		if ((vp->v_id != vid) || ISSET(vp->v_lflag, VL_DEAD)) {
2870 			vnode_unlock(vp);
2871 			mount_lock(mp);
2872 			continue;
2873 		}
2874 
2875 		/*
2876 		 * If requested, skip over vnodes marked VSYSTEM.
2877 		 * Skip over all vnodes marked VNOFLUSH.
2878 		 */
2879 		if ((flags & SKIPSYSTEM) && ((vp->v_flag & VSYSTEM) ||
2880 		    (vp->v_flag & VNOFLUSH))) {
2881 			vnode_unlock(vp);
2882 			mount_lock(mp);
2883 			continue;
2884 		}
2885 		/*
2886 		 * If requested, skip over vnodes marked VSWAP.
2887 		 */
2888 		if ((flags & SKIPSWAP) && (vp->v_flag & VSWAP)) {
2889 			vnode_unlock(vp);
2890 			mount_lock(mp);
2891 			continue;
2892 		}
2893 		/*
2894 		 * If requested, skip over vnodes marked VROOT.
2895 		 */
2896 		if ((flags & SKIPROOT) && (vp->v_flag & VROOT)) {
2897 			vnode_unlock(vp);
2898 			mount_lock(mp);
2899 			continue;
2900 		}
2901 		/*
2902 		 * If WRITECLOSE is set, only flush out regular file
2903 		 * vnodes open for writing.
2904 		 */
2905 		if ((flags & WRITECLOSE) &&
2906 		    (vp->v_writecount == 0 || vp->v_type != VREG)) {
2907 			vnode_unlock(vp);
2908 			mount_lock(mp);
2909 			continue;
2910 		}
2911 		/*
2912 		 * If the real usecount is 0, all we need to do is clear
2913 		 * out the vnode data structures and we are done.
2914 		 */
2915 		if (((vp->v_usecount == 0) ||
2916 		    ((vp->v_usecount - vp->v_kusecount) == 0))) {
2917 			vnode_lock_convert(vp);
2918 			vnode_hold(vp);
2919 			vp->v_iocount++;        /* so that drain waits for * other iocounts */
2920 #ifdef CONFIG_IOCOUNT_TRACE
2921 			record_vp(vp, 1);
2922 #endif
2923 			vnode_reclaim_internal(vp, 1, 1, 0);
2924 			vnode_dropiocount(vp);
2925 			vnode_list_add(vp);
2926 			vnode_drop_and_unlock(vp);
2927 
2928 			reclaimed++;
2929 			mount_lock(mp);
2930 			continue;
2931 		}
2932 		/*
2933 		 * If FORCECLOSE is set, forcibly close the vnode.
2934 		 * For block or character devices, revert to an
2935 		 * anonymous device. For all other files, just kill them.
2936 		 */
2937 		if (flags & FORCECLOSE) {
2938 			vnode_lock_convert(vp);
2939 
2940 			if (vp->v_type != VBLK && vp->v_type != VCHR) {
2941 				vp->v_iocount++;        /* so that drain waits * for other iocounts */
2942 				vnode_hold(vp);
2943 #ifdef CONFIG_IOCOUNT_TRACE
2944 				record_vp(vp, 1);
2945 #endif
2946 				vnode_abort_advlocks(vp);
2947 				vnode_reclaim_internal(vp, 1, 1, 0);
2948 				vnode_dropiocount(vp);
2949 				vnode_list_add(vp);
2950 				vnode_drop_and_unlock(vp);
2951 			} else {
2952 				vnode_hold(vp);
2953 				vp->v_lflag |= VL_OPSCHANGE;
2954 				vclean(vp, 0);
2955 				vp->v_lflag &= ~VL_DEAD;
2956 				vp->v_op = spec_vnodeop_p;
2957 				vp->v_flag |= VDEVFLUSH;
2958 				vnode_drop_and_unlock(vp);
2959 				wakeup(&vp->v_lflag); /* chkvnlock is waitng for VL_DEAD to get unset */
2960 			}
2961 			mount_lock(mp);
2962 			continue;
2963 		}
2964 
2965 		/* log vnodes blocking unforced unmounts */
2966 		if (print_busy_vnodes && first_try && ((flags & FORCECLOSE) == 0)) {
2967 			vprint("vflush - busy vnode", vp);
2968 		}
2969 
2970 		vnode_unlock(vp);
2971 		mount_lock(mp);
2972 		busy++;
2973 	}
2974 
2975 	/* At this point the worker queue is completed */
2976 	if (busy && ((flags & FORCECLOSE) == 0) && reclaimed) {
2977 		busy = 0;
2978 		reclaimed = 0;
2979 		(void)vnode_iterate_reloadq(mp);
2980 		first_try = false;
2981 		/* returned with mount lock held */
2982 		goto loop;
2983 	}
2984 
2985 	/* if new vnodes were created in between retry the reclaim */
2986 	if (vnode_iterate_reloadq(mp) != 0) {
2987 		if (!(busy && ((flags & FORCECLOSE) == 0))) {
2988 			first_try = false;
2989 			goto loop;
2990 		}
2991 	}
2992 	vnode_iterate_clear(mp);
2993 	mount_unlock(mp);
2994 	mount_iterate_unlock(mp);
2995 
2996 	if (busy && ((flags & FORCECLOSE) == 0)) {
2997 		return EBUSY;
2998 	}
2999 	return 0;
3000 }
3001 
3002 long num_recycledvnodes = 0;
3003 /*
3004  * Disassociate the underlying file system from a vnode.
3005  * The vnode lock is held on entry.
3006  */
3007 static void
vclean(vnode_t vp,int flags)3008 vclean(vnode_t vp, int flags)
3009 {
3010 	vfs_context_t ctx = vfs_context_current();
3011 	int active;
3012 	int need_inactive;
3013 	int already_terminating;
3014 	int clflags = 0;
3015 #if NAMEDSTREAMS
3016 	int is_namedstream;
3017 #endif
3018 
3019 	/*
3020 	 * Check to see if the vnode is in use.
3021 	 * If so we have to reference it before we clean it out
3022 	 * so that its count cannot fall to zero and generate a
3023 	 * race against ourselves to recycle it.
3024 	 */
3025 	active = vp->v_usecount;
3026 
3027 	/*
3028 	 * just in case we missed sending a needed
3029 	 * VNOP_INACTIVE, we'll do it now
3030 	 */
3031 	need_inactive = (vp->v_lflag & VL_NEEDINACTIVE);
3032 
3033 	vp->v_lflag &= ~VL_NEEDINACTIVE;
3034 
3035 	/*
3036 	 * Prevent the vnode from being recycled or
3037 	 * brought into use while we clean it out.
3038 	 */
3039 	already_terminating = (vp->v_lflag & VL_TERMINATE);
3040 
3041 	vp->v_lflag |= VL_TERMINATE;
3042 
3043 #if NAMEDSTREAMS
3044 	is_namedstream = vnode_isnamedstream(vp);
3045 #endif
3046 
3047 	vnode_unlock(vp);
3048 
3049 	OSAddAtomicLong(1, &num_recycledvnodes);
3050 
3051 	if (flags & DOCLOSE) {
3052 		clflags |= IO_NDELAY;
3053 	}
3054 	if (flags & REVOKEALL) {
3055 		clflags |= IO_REVOKE;
3056 	}
3057 
3058 #if CONFIG_MACF
3059 	if (vp->v_mount) {
3060 		/*
3061 		 * It is possible for bdevvp vnodes to not have a mount
3062 		 * pointer. It's fine to let it get reclaimed without
3063 		 * notifying.
3064 		 */
3065 		mac_vnode_notify_reclaim(vp);
3066 	}
3067 #endif
3068 
3069 	if (active && (flags & DOCLOSE)) {
3070 		VNOP_CLOSE(vp, clflags, ctx);
3071 	}
3072 
3073 	/*
3074 	 * Clean out any buffers associated with the vnode.
3075 	 */
3076 	if (flags & DOCLOSE) {
3077 		if (vp->v_tag == VT_NFS) {
3078 			nfs_vinvalbuf(vp, V_SAVE, ctx, 0);
3079 		} else {
3080 			VNOP_FSYNC(vp, MNT_WAIT, ctx);
3081 
3082 			/*
3083 			 * If the vnode is still in use (by the journal for
3084 			 * example) we don't want to invalidate locked buffers
3085 			 * here.  In that case, either the journal will tidy them
3086 			 * up, or we will deal with it when the usecount is
3087 			 * finally released in vnode_rele_internal.
3088 			 */
3089 			buf_invalidateblks(vp, BUF_WRITE_DATA | (active ? 0 : BUF_INVALIDATE_LOCKED), 0, 0);
3090 		}
3091 		if (UBCINFOEXISTS(vp)) {
3092 			/*
3093 			 * Clean the pages in VM.
3094 			 */
3095 			(void)ubc_msync(vp, (off_t)0, ubc_getsize(vp), NULL, UBC_PUSHALL | UBC_INVALIDATE | UBC_SYNC);
3096 		}
3097 	}
3098 	if (active || need_inactive) {
3099 		VNOP_INACTIVE(vp, ctx);
3100 	}
3101 
3102 #if NAMEDSTREAMS
3103 	if ((is_namedstream != 0) && (vp->v_parent != NULLVP)) {
3104 		vnode_t pvp = vp->v_parent;
3105 
3106 		/* Delete the shadow stream file before we reclaim its vnode */
3107 		if (vnode_isshadow(vp)) {
3108 			vnode_relenamedstream(pvp, vp);
3109 		}
3110 
3111 		/*
3112 		 * No more streams associated with the parent.  We
3113 		 * have a ref on it, so its identity is stable.
3114 		 * If the parent is on an opaque volume, then we need to know
3115 		 * whether it has associated named streams.
3116 		 */
3117 		if (vfs_authopaque(pvp->v_mount)) {
3118 			vnode_lock_spin(pvp);
3119 			pvp->v_lflag &= ~VL_HASSTREAMS;
3120 			vnode_unlock(pvp);
3121 		}
3122 	}
3123 #endif
3124 
3125 	vm_object_destroy_reason_t reason = VM_OBJECT_DESTROY_RECLAIM;
3126 	bool forced_unmount = vnode_mount(vp) != NULL && (vnode_mount(vp)->mnt_lflag & MNT_LFORCE) != 0;
3127 	bool ungraft_heuristic = flags & REVOKEALL;
3128 	bool unmount = vnode_mount(vp) != NULL && (vnode_mount(vp)->mnt_lflag & MNT_LUNMOUNT) != 0;
3129 	if (forced_unmount) {
3130 		reason = VM_OBJECT_DESTROY_FORCED_UNMOUNT;
3131 	} else if (ungraft_heuristic) {
3132 		reason = VM_OBJECT_DESTROY_UNGRAFT;
3133 	} else if (unmount) {
3134 		reason = VM_OBJECT_DESTROY_UNMOUNT;
3135 	}
3136 
3137 	/*
3138 	 * Destroy ubc named reference
3139 	 * cluster_release is done on this path
3140 	 * along with dropping the reference on the ucred
3141 	 * (and in the case of forced unmount of an mmap-ed file,
3142 	 * the ubc reference on the vnode is dropped here too).
3143 	 */
3144 	ubc_destroy_named(vp, reason);
3145 
3146 #if CONFIG_TRIGGERS
3147 	/*
3148 	 * cleanup trigger info from vnode (if any)
3149 	 */
3150 	if (vp->v_resolve) {
3151 		vnode_resolver_detach(vp);
3152 	}
3153 #endif
3154 
3155 #if CONFIG_IO_COMPRESSION_STATS
3156 	if ((vp->io_compression_stats)) {
3157 		vnode_iocs_record_and_free(vp);
3158 	}
3159 #endif /* CONFIG_IO_COMPRESSION_STATS */
3160 
3161 	/*
3162 	 * Reclaim the vnode.
3163 	 */
3164 	if (VNOP_RECLAIM(vp, ctx)) {
3165 		panic("vclean: cannot reclaim");
3166 	}
3167 
3168 	// make sure the name & parent ptrs get cleaned out!
3169 	vnode_update_identity(vp, NULLVP, NULL, 0, 0, VNODE_UPDATE_PARENT | VNODE_UPDATE_NAME | VNODE_UPDATE_PURGE | VNODE_UPDATE_PURGEFIRMLINK);
3170 
3171 	vnode_lock(vp);
3172 
3173 	/*
3174 	 * Remove the vnode from any mount list it might be on.  It is not
3175 	 * safe to do this any earlier because unmount needs to wait for
3176 	 * any vnodes to terminate and it cannot do that if it cannot find
3177 	 * them.
3178 	 */
3179 	insmntque(vp, (struct mount *)0);
3180 
3181 	vp->v_lflag |= VL_DEAD;
3182 	vp->v_mount = dead_mountp;
3183 	vp->v_op = dead_vnodeop_p;
3184 	vp->v_tag = VT_NON;
3185 	vp->v_data = NULL;
3186 
3187 	vp->v_flag &= ~VISDIRTY;
3188 
3189 	if (already_terminating == 0) {
3190 		vp->v_lflag &= ~VL_TERMINATE;
3191 		/*
3192 		 * Done with purge, notify sleepers of the grim news.
3193 		 */
3194 		if (vp->v_lflag & VL_TERMWANT) {
3195 			vp->v_lflag &= ~VL_TERMWANT;
3196 			wakeup(&vp->v_lflag);
3197 		}
3198 	}
3199 }
3200 
3201 /*
3202  * Eliminate all activity associated with  the requested vnode
3203  * and with all vnodes aliased to the requested vnode.
3204  */
3205 int
3206 #if DIAGNOSTIC
vn_revoke(vnode_t vp,int flags,__unused vfs_context_t a_context)3207 vn_revoke(vnode_t vp, int flags, __unused vfs_context_t a_context)
3208 #else
3209 vn_revoke(vnode_t vp, __unused int flags, __unused vfs_context_t a_context)
3210 #endif
3211 {
3212 	struct vnode *vq;
3213 	int vid;
3214 
3215 #if DIAGNOSTIC
3216 	if ((flags & REVOKEALL) == 0) {
3217 		panic("vnop_revoke");
3218 	}
3219 #endif
3220 
3221 	if (vnode_isaliased(vp)) {
3222 		/*
3223 		 * If a vgone (or vclean) is already in progress,
3224 		 * return an immediate error
3225 		 */
3226 		if (vp->v_lflag & VL_TERMINATE) {
3227 			return ENOENT;
3228 		}
3229 
3230 		/*
3231 		 * Ensure that vp will not be vgone'd while we
3232 		 * are eliminating its aliases.
3233 		 */
3234 		SPECHASH_LOCK();
3235 		while ((vp->v_specflags & SI_ALIASED)) {
3236 			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
3237 				if (vq->v_rdev != vp->v_rdev ||
3238 				    vq->v_type != vp->v_type || vp == vq) {
3239 					continue;
3240 				}
3241 				vid = vq->v_id;
3242 				vnode_hold(vq);
3243 				SPECHASH_UNLOCK();
3244 				if (vnode_getwithvid(vq, vid)) {
3245 					vq = vnode_drop(vq);
3246 					SPECHASH_LOCK();
3247 					break;
3248 				}
3249 				vnode_lock(vq);
3250 				if (!(vq->v_lflag & VL_TERMINATE)) {
3251 					vnode_reclaim_internal(vq, 1, 1, 0);
3252 				}
3253 				vnode_put_locked(vq);
3254 				vq = vnode_drop_and_unlock(vq);
3255 				SPECHASH_LOCK();
3256 				break;
3257 			}
3258 		}
3259 		SPECHASH_UNLOCK();
3260 	}
3261 	vnode_lock(vp);
3262 	if (vp->v_lflag & VL_TERMINATE) {
3263 		vnode_unlock(vp);
3264 		return ENOENT;
3265 	}
3266 	vnode_reclaim_internal(vp, 1, 0, REVOKEALL);
3267 	vnode_unlock(vp);
3268 
3269 	return 0;
3270 }
3271 
3272 /*
3273  * Recycle an unused vnode to the front of the free list.
3274  * Release the passed interlock if the vnode will be recycled.
3275  */
3276 int
vnode_recycle(struct vnode * vp)3277 vnode_recycle(struct vnode *vp)
3278 {
3279 	vnode_lock_spin(vp);
3280 
3281 	if (vp->v_iocount || vp->v_usecount) {
3282 		vp->v_lflag |= VL_MARKTERM;
3283 		vnode_unlock(vp);
3284 		return 0;
3285 	}
3286 	vnode_lock_convert(vp);
3287 	vnode_hold(vp);
3288 	vnode_reclaim_internal(vp, 1, 0, 0);
3289 
3290 	vnode_drop_and_unlock(vp);
3291 
3292 	return 1;
3293 }
3294 
3295 static int
vnode_reload(vnode_t vp)3296 vnode_reload(vnode_t vp)
3297 {
3298 	vnode_lock_spin(vp);
3299 
3300 	if ((vp->v_iocount > 1) || vp->v_usecount) {
3301 		vnode_unlock(vp);
3302 		return 0;
3303 	}
3304 	if (vp->v_iocount <= 0) {
3305 		panic("vnode_reload with no iocount %d", vp->v_iocount);
3306 	}
3307 
3308 	/* mark for release when iocount is dopped */
3309 	vp->v_lflag |= VL_MARKTERM;
3310 	vnode_unlock(vp);
3311 
3312 	return 1;
3313 }
3314 
3315 
3316 static void
vgone(vnode_t vp,int flags)3317 vgone(vnode_t vp, int flags)
3318 {
3319 	struct vnode *vq;
3320 	struct vnode *vx;
3321 
3322 	/*
3323 	 * Clean out the filesystem specific data.
3324 	 * vclean also takes care of removing the
3325 	 * vnode from any mount list it might be on
3326 	 */
3327 	vclean(vp, flags | DOCLOSE);
3328 
3329 	/*
3330 	 * If special device, remove it from special device alias list
3331 	 * if it is on one.
3332 	 */
3333 	if ((vp->v_type == VBLK || vp->v_type == VCHR) && vp->v_specinfo != 0) {
3334 		SPECHASH_LOCK();
3335 		if (*vp->v_hashchain == vp) {
3336 			*vp->v_hashchain = vp->v_specnext;
3337 		} else {
3338 			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
3339 				if (vq->v_specnext != vp) {
3340 					continue;
3341 				}
3342 				vq->v_specnext = vp->v_specnext;
3343 				break;
3344 			}
3345 			if (vq == NULL) {
3346 				panic("missing bdev");
3347 			}
3348 		}
3349 		if (vp->v_specflags & SI_ALIASED) {
3350 			vx = NULL;
3351 			for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
3352 				if (vq->v_rdev != vp->v_rdev ||
3353 				    vq->v_type != vp->v_type) {
3354 					continue;
3355 				}
3356 				if (vx) {
3357 					break;
3358 				}
3359 				vx = vq;
3360 			}
3361 			if (vx == NULL) {
3362 				panic("missing alias");
3363 			}
3364 			if (vq == NULL) {
3365 				vx->v_specflags &= ~SI_ALIASED;
3366 			}
3367 			vp->v_specflags &= ~SI_ALIASED;
3368 		}
3369 		SPECHASH_UNLOCK();
3370 		{
3371 			struct specinfo *tmp = vp->v_specinfo;
3372 			vp->v_specinfo = NULL;
3373 			zfree(specinfo_zone, tmp);
3374 		}
3375 	}
3376 }
3377 
3378 /*
3379  * internal helper function only!
3380  * vend an _iocounted_ vnode via output argument, or return an error if unable.
3381  */
3382 static int
get_vp_from_dev(dev_t dev,enum vtype type,vnode_t * outvp)3383 get_vp_from_dev(dev_t dev, enum vtype type, vnode_t *outvp)
3384 {
3385 	vnode_t vp;
3386 	int vid;
3387 
3388 loop:
3389 	SPECHASH_LOCK();
3390 	for (vp = speclisth[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
3391 		if (dev != vp->v_rdev || type != vp->v_type) {
3392 			continue;
3393 		}
3394 		vid = vp->v_id;
3395 		vnode_hold(vp);
3396 		SPECHASH_UNLOCK();
3397 
3398 		/* acquire iocount */
3399 		if (vnode_getwithvid(vp, vid)) {
3400 			vnode_drop(vp);
3401 			goto loop;
3402 		}
3403 		vnode_drop(vp);
3404 
3405 		/* Vend iocounted vnode */
3406 		*outvp = vp;
3407 		return 0;
3408 	}
3409 
3410 	/* vnode not found, error out */
3411 	SPECHASH_UNLOCK();
3412 	return ENOENT;
3413 }
3414 
3415 
3416 
3417 /*
3418  * Lookup a vnode by device number.
3419  */
3420 int
check_mountedon(dev_t dev,enum vtype type,int * errorp)3421 check_mountedon(dev_t dev, enum vtype type, int *errorp)
3422 {
3423 	vnode_t vp = NULLVP;
3424 	int rc = 0;
3425 
3426 	rc = get_vp_from_dev(dev, type, &vp);
3427 	if (rc) {
3428 		/* if no vnode found, it cannot be mounted on */
3429 		return 0;
3430 	}
3431 
3432 	/* otherwise, examine it */
3433 	vnode_lock_spin(vp);
3434 	/* note: exclude the iocount we JUST got (e.g. >1, not >0) */
3435 	if ((vp->v_usecount > 0) || (vp->v_iocount > 1)) {
3436 		vnode_unlock(vp);
3437 		if ((*errorp = vfs_mountedon(vp)) != 0) {
3438 			rc = 1;
3439 		}
3440 	} else {
3441 		vnode_unlock(vp);
3442 	}
3443 	/* release iocount! */
3444 	vnode_put(vp);
3445 
3446 	return rc;
3447 }
3448 
3449 extern dev_t chrtoblk(dev_t d);
3450 
3451 /*
3452  * Examine the supplied vnode's dev_t and find its counterpart
3453  * (e.g.  VCHR => VDEV) to compare against.
3454  */
3455 static int
vnode_cmp_paired_dev(vnode_t vp,vnode_t bdev_vp,enum vtype in_type,enum vtype out_type)3456 vnode_cmp_paired_dev(vnode_t vp, vnode_t bdev_vp, enum vtype in_type,
3457     enum vtype out_type)
3458 {
3459 	if (!vp || !bdev_vp) {
3460 		return EINVAL;
3461 	}
3462 	/* Verify iocounts */
3463 	if (vnode_iocount(vp) <= 0 ||
3464 	    vnode_iocount(bdev_vp) <= 0) {
3465 		return EINVAL;
3466 	}
3467 
3468 	/* check for basic matches */
3469 	if (vnode_vtype(vp) != in_type) {
3470 		return EINVAL;
3471 	}
3472 	if (vnode_vtype(bdev_vp) != out_type) {
3473 		return EINVAL;
3474 	}
3475 
3476 	dev_t dev = vnode_specrdev(vp);
3477 	dev_t blk_devt = vnode_specrdev(bdev_vp);
3478 
3479 	if (in_type == VCHR) {
3480 		if (out_type != VBLK) {
3481 			return EINVAL;
3482 		}
3483 		dev_t bdev = chrtoblk(dev);
3484 		if (bdev == NODEV) {
3485 			return EINVAL;
3486 		} else if (bdev == blk_devt) {
3487 			return 0;
3488 		}
3489 		//fall through
3490 	}
3491 	/*
3492 	 * else case:
3493 	 *
3494 	 * in_type == VBLK? => VCHR?
3495 	 * not implemented...
3496 	 * exercise to the reader: this can be built by
3497 	 * taking the device's major, and iterating the `chrtoblktab`
3498 	 * array to look for a value that matches.
3499 	 */
3500 	return EINVAL;
3501 }
3502 /*
3503  * Vnode compare: does the supplied vnode's CHR device, match the dev_t
3504  * of the accompanying `blk_vp` ?
3505  * NOTE: vnodes MUST be iocounted BEFORE calling this!
3506  */
3507 
3508 int
vnode_cmp_chrtoblk(vnode_t vp,vnode_t blk_vp)3509 vnode_cmp_chrtoblk(vnode_t vp, vnode_t blk_vp)
3510 {
3511 	return vnode_cmp_paired_dev(vp, blk_vp, VCHR, VBLK);
3512 }
3513 
3514 
3515 
3516 /*
3517  * Calculate the total number of references to a special device.
3518  */
3519 int
vcount(vnode_t vp)3520 vcount(vnode_t vp)
3521 {
3522 	vnode_t vq, vnext;
3523 	int count;
3524 	int vid;
3525 
3526 	if (!vnode_isspec(vp)) {
3527 		return vp->v_usecount - vp->v_kusecount;
3528 	}
3529 
3530 loop:
3531 	if (!vnode_isaliased(vp)) {
3532 		return vp->v_specinfo->si_opencount;
3533 	}
3534 	count = 0;
3535 
3536 	SPECHASH_LOCK();
3537 	/*
3538 	 * Grab first vnode and its vid.
3539 	 */
3540 	vq = *vp->v_hashchain;
3541 	if (vq) {
3542 		vid = vq->v_id;
3543 		vnode_hold(vq);
3544 	} else {
3545 		vid = 0;
3546 	}
3547 	SPECHASH_UNLOCK();
3548 
3549 	while (vq) {
3550 		/*
3551 		 * Attempt to get the vnode outside the SPECHASH lock.
3552 		 * Don't take iocount on 'vp' as iocount is already held by the caller.
3553 		 */
3554 		if ((vq != vp) && vnode_getwithvid(vq, vid)) {
3555 			vnode_drop(vq);
3556 			goto loop;
3557 		}
3558 		vnode_drop(vq);
3559 		vnode_lock(vq);
3560 
3561 		if (vq->v_rdev == vp->v_rdev && vq->v_type == vp->v_type) {
3562 			if ((vq->v_usecount == 0) && (vq->v_iocount == 1) && vq != vp) {
3563 				/*
3564 				 * Alias, but not in use, so flush it out.
3565 				 */
3566 				vnode_hold(vq);
3567 				vnode_reclaim_internal(vq, 1, 1, 0);
3568 				vnode_put_locked(vq);
3569 				vnode_drop_and_unlock(vq);
3570 				goto loop;
3571 			}
3572 			count += vq->v_specinfo->si_opencount;
3573 		}
3574 		vnode_unlock(vq);
3575 
3576 		SPECHASH_LOCK();
3577 		/*
3578 		 * must do this with the reference still held on 'vq'
3579 		 * so that it can't be destroyed while we're poking
3580 		 * through v_specnext
3581 		 */
3582 		vnext = vq->v_specnext;
3583 		if (vnext) {
3584 			vid = vnext->v_id;
3585 			vnode_hold(vnext);
3586 		} else {
3587 			vid = 0;
3588 		}
3589 		SPECHASH_UNLOCK();
3590 
3591 		if (vq != vp) {
3592 			vnode_put(vq);
3593 		}
3594 
3595 		vq = vnext;
3596 	}
3597 
3598 	return count;
3599 }
3600 
3601 int     prtactive = 0;          /* 1 => print out reclaim of active vnodes */
3602 
3603 /*
3604  * Print out a description of a vnode.
3605  */
3606 static const char *typename[] =
3607 { "VNON", "VREG", "VDIR", "VBLK", "VCHR", "VLNK", "VSOCK", "VFIFO", "VBAD" };
3608 
3609 void
vprint(const char * label,struct vnode * vp)3610 vprint(const char *label, struct vnode *vp)
3611 {
3612 	char sbuf[64];
3613 
3614 	if (label != NULL) {
3615 		printf("%s: ", label);
3616 	}
3617 	printf("name %s type %s, usecount %d, writecount %d\n",
3618 	    vp->v_name, typename[vp->v_type],
3619 	    vp->v_usecount, vp->v_writecount);
3620 	sbuf[0] = '\0';
3621 	if (vp->v_flag & VROOT) {
3622 		strlcat(sbuf, "|VROOT", sizeof(sbuf));
3623 	}
3624 	if (vp->v_flag & VTEXT) {
3625 		strlcat(sbuf, "|VTEXT", sizeof(sbuf));
3626 	}
3627 	if (vp->v_flag & VSYSTEM) {
3628 		strlcat(sbuf, "|VSYSTEM", sizeof(sbuf));
3629 	}
3630 	if (vp->v_flag & VNOFLUSH) {
3631 		strlcat(sbuf, "|VNOFLUSH", sizeof(sbuf));
3632 	}
3633 	if (vp->v_flag & VBWAIT) {
3634 		strlcat(sbuf, "|VBWAIT", sizeof(sbuf));
3635 	}
3636 	if (vnode_isaliased(vp)) {
3637 		strlcat(sbuf, "|VALIASED", sizeof(sbuf));
3638 	}
3639 	if (sbuf[0] != '\0') {
3640 		printf("vnode flags (%s\n", &sbuf[1]);
3641 	}
3642 }
3643 
3644 static int
vn_getpath_flags_to_buildpath_flags(int flags)3645 vn_getpath_flags_to_buildpath_flags(int flags)
3646 {
3647 	int bpflags = (flags & VN_GETPATH_FSENTER) ? 0 : BUILDPATH_NO_FS_ENTER;
3648 
3649 	if (flags && (flags != VN_GETPATH_FSENTER)) {
3650 		if (flags & VN_GETPATH_NO_FIRMLINK) {
3651 			bpflags |= BUILDPATH_NO_FIRMLINK;
3652 		}
3653 		if (flags & VN_GETPATH_VOLUME_RELATIVE) {
3654 			bpflags |= (BUILDPATH_VOLUME_RELATIVE |
3655 			    BUILDPATH_NO_FIRMLINK);
3656 		}
3657 		if (flags & VN_GETPATH_NO_PROCROOT) {
3658 			bpflags |= BUILDPATH_NO_PROCROOT;
3659 		}
3660 		if (flags & VN_GETPATH_CHECK_MOVED) {
3661 			bpflags |= BUILDPATH_CHECK_MOVED;
3662 		}
3663 	}
3664 
3665 	return bpflags;
3666 }
3667 
3668 int
vn_getpath_ext_with_mntlen(struct vnode * vp,struct vnode * dvp,char * pathbuf,size_t * len,size_t * mntlen,int flags)3669 vn_getpath_ext_with_mntlen(struct vnode *vp, struct vnode *dvp, char *pathbuf,
3670     size_t *len, size_t *mntlen, int flags)
3671 {
3672 	int bpflags = vn_getpath_flags_to_buildpath_flags(flags);
3673 	int local_len;
3674 	int error;
3675 
3676 	if (*len > INT_MAX) {
3677 		return EINVAL;
3678 	}
3679 
3680 	local_len = *len;
3681 
3682 	error = build_path_with_parent(vp, dvp, pathbuf, local_len, &local_len,
3683 	    mntlen, bpflags, vfs_context_current());
3684 
3685 	if (local_len >= 0 && local_len <= (int)*len) {
3686 		*len = (size_t)local_len;
3687 	}
3688 
3689 	return error;
3690 }
3691 
3692 int
vn_getpath_ext(struct vnode * vp,struct vnode * dvp,char * pathbuf,size_t * len,int flags)3693 vn_getpath_ext(struct vnode *vp, struct vnode *dvp, char *pathbuf, size_t *len,
3694     int flags)
3695 {
3696 	return vn_getpath_ext_with_mntlen(vp, dvp, pathbuf, len, NULL, flags);
3697 }
3698 
3699 /*
3700  * Wrapper around vn_getpath_ext() that takes care of the int * <-> size_t *
3701  * conversion for the legacy KPIs.
3702  */
3703 static int
vn_getpath_ext_int(struct vnode * vp,struct vnode * dvp,char * pathbuf,int * len,int flags)3704 vn_getpath_ext_int(struct vnode *vp, struct vnode *dvp, char *pathbuf,
3705     int *len, int flags)
3706 {
3707 	size_t slen = *len;
3708 	int error;
3709 
3710 	if (*len < 0) {
3711 		return EINVAL;
3712 	}
3713 
3714 	error = vn_getpath_ext(vp, dvp, pathbuf, &slen, flags);
3715 
3716 	if (slen <= INT_MAX) {
3717 		*len = (int)slen;
3718 	}
3719 
3720 	return error;
3721 }
3722 
3723 int
vn_getpath(struct vnode * vp,char * pathbuf,int * len)3724 vn_getpath(struct vnode *vp, char *pathbuf, int *len)
3725 {
3726 	return vn_getpath_ext_int(vp, NULL, pathbuf, len, 0);
3727 }
3728 
3729 int
vn_getpath_fsenter(struct vnode * vp,char * pathbuf,int * len)3730 vn_getpath_fsenter(struct vnode *vp, char *pathbuf, int *len)
3731 {
3732 	return vn_getpath_ext_int(vp, NULL, pathbuf, len, VN_GETPATH_FSENTER);
3733 }
3734 
3735 /*
3736  * vn_getpath_fsenter_with_parent will reenter the file system to fine the path of the
3737  * vnode.  It requires that there are IO counts on both the vnode and the directory vnode.
3738  *
3739  * vn_getpath_fsenter is called by MAC hooks to authorize operations for every thing, but
3740  * unlink, rmdir and rename. For these operation the MAC hook  calls vn_getpath. This presents
3741  * problems where if the path can not be found from the name cache, those operations can
3742  * erroneously fail with EPERM even though the call should succeed. When removing or moving
3743  * file system objects with operations such as unlink or rename, those operations need to
3744  * take IO counts on the target and containing directory. Calling vn_getpath_fsenter from a
3745  * MAC hook from these operations during forced unmount operations can lead to dead
3746  * lock. This happens when the operation starts, IO counts are taken on the containing
3747  * directories and targets. Before the MAC hook is called a forced unmount from another
3748  * thread takes place and blocks on the on going operation's directory vnode in vdrain.
3749  * After which, the MAC hook gets called and calls vn_getpath_fsenter.  vn_getpath_fsenter
3750  * is called with the understanding that there is an IO count on the target. If in
3751  * build_path the directory vnode is no longer in the cache, then the parent object id via
3752  * vnode_getattr from the target is obtain and used to call VFS_VGET to get the parent
3753  * vnode. The file system's VFS_VGET then looks up by inode in its hash and tries to get
3754  * an IO count. But VFS_VGET "sees" the directory vnode is in vdrain and can block
3755  * depending on which version and how it calls the vnode_get family of interfaces.
3756  *
3757  * N.B.  A reasonable interface to use is vnode_getwithvid. This interface was modified to
3758  * call vnode_getiocount with VNODE_DRAINO, so it will happily get an IO count and not
3759  * cause issues, but there is no guarantee that all or any file systems are doing that.
3760  *
3761  * vn_getpath_fsenter_with_parent can enter the file system safely since there is a known
3762  * IO count on the directory vnode by calling build_path_with_parent.
3763  */
3764 
3765 int
vn_getpath_fsenter_with_parent(struct vnode * dvp,struct vnode * vp,char * pathbuf,int * len)3766 vn_getpath_fsenter_with_parent(struct vnode *dvp, struct vnode *vp, char *pathbuf, int *len)
3767 {
3768 	return build_path_with_parent(vp, dvp, pathbuf, *len, len, NULL, 0, vfs_context_current());
3769 }
3770 
3771 int
vn_getpath_no_firmlink(struct vnode * vp,char * pathbuf,int * len)3772 vn_getpath_no_firmlink(struct vnode *vp, char *pathbuf, int *len)
3773 {
3774 	return vn_getpath_ext_int(vp, NULLVP, pathbuf, len,
3775 	           VN_GETPATH_NO_FIRMLINK);
3776 }
3777 
3778 int
vn_getcdhash(struct vnode * vp,off_t offset,unsigned char * cdhash)3779 vn_getcdhash(struct vnode *vp, off_t offset, unsigned char *cdhash)
3780 {
3781 	return ubc_cs_getcdhash(vp, offset, cdhash);
3782 }
3783 
3784 
3785 static char *extension_table = NULL;
3786 static int   nexts;
3787 static int   max_ext_width;
3788 
3789 static int
extension_cmp(const void * a,const void * b)3790 extension_cmp(const void *a, const void *b)
3791 {
3792 	return (int)(strlen((const char *)a) - strlen((const char *)b));
3793 }
3794 
3795 
3796 //
3797 // This is the api LaunchServices uses to inform the kernel
3798 // the list of package extensions to ignore.
3799 //
3800 // Internally we keep the list sorted by the length of the
3801 // the extension (from longest to shortest).  We sort the
3802 // list of extensions so that we can speed up our searches
3803 // when comparing file names -- we only compare extensions
3804 // that could possibly fit into the file name, not all of
3805 // them (i.e. a short 8 character name can't have an 8
3806 // character extension).
3807 //
3808 extern lck_mtx_t pkg_extensions_lck;
3809 
3810 __private_extern__ int
set_package_extensions_table(user_addr_t data,int nentries,int maxwidth)3811 set_package_extensions_table(user_addr_t data, int nentries, int maxwidth)
3812 {
3813 	char *new_exts, *old_exts;
3814 	int old_nentries = 0, old_maxwidth = 0;
3815 	int error;
3816 
3817 	if (nentries <= 0 || nentries > 1024 || maxwidth <= 0 || maxwidth > 255) {
3818 		return EINVAL;
3819 	}
3820 
3821 
3822 	// allocate one byte extra so we can guarantee null termination
3823 	new_exts = kalloc_data((nentries * maxwidth) + 1, Z_WAITOK);
3824 	if (new_exts == NULL) {
3825 		return ENOMEM;
3826 	}
3827 
3828 	error = copyin(data, new_exts, nentries * maxwidth);
3829 	if (error) {
3830 		kfree_data(new_exts, (nentries * maxwidth) + 1);
3831 		return error;
3832 	}
3833 
3834 	new_exts[(nentries * maxwidth)] = '\0'; // guarantee null termination of the block
3835 
3836 	qsort(new_exts, nentries, maxwidth, extension_cmp);
3837 
3838 	lck_mtx_lock(&pkg_extensions_lck);
3839 
3840 	old_exts        = extension_table;
3841 	old_nentries    = nexts;
3842 	old_maxwidth    = max_ext_width;
3843 	extension_table = new_exts;
3844 	nexts           = nentries;
3845 	max_ext_width   = maxwidth;
3846 
3847 	lck_mtx_unlock(&pkg_extensions_lck);
3848 
3849 	kfree_data(old_exts, (old_nentries * old_maxwidth) + 1);
3850 
3851 	return 0;
3852 }
3853 
3854 
3855 int
is_package_name(const char * name,int len)3856 is_package_name(const char *name, int len)
3857 {
3858 	int i;
3859 	size_t extlen;
3860 	const char *ptr, *name_ext;
3861 
3862 	// if the name is less than 3 bytes it can't be of the
3863 	// form A.B and if it begins with a "." then it is also
3864 	// not a package.
3865 	if (len <= 3 || name[0] == '.') {
3866 		return 0;
3867 	}
3868 
3869 	name_ext = NULL;
3870 	for (ptr = name; *ptr != '\0'; ptr++) {
3871 		if (*ptr == '.') {
3872 			name_ext = ptr;
3873 		}
3874 	}
3875 
3876 	// if there is no "." extension, it can't match
3877 	if (name_ext == NULL) {
3878 		return 0;
3879 	}
3880 
3881 	// advance over the "."
3882 	name_ext++;
3883 
3884 	lck_mtx_lock(&pkg_extensions_lck);
3885 
3886 	// now iterate over all the extensions to see if any match
3887 	ptr = &extension_table[0];
3888 	for (i = 0; i < nexts; i++, ptr += max_ext_width) {
3889 		extlen = strlen(ptr);
3890 		if (strncasecmp(name_ext, ptr, extlen) == 0 && name_ext[extlen] == '\0') {
3891 			// aha, a match!
3892 			lck_mtx_unlock(&pkg_extensions_lck);
3893 			return 1;
3894 		}
3895 	}
3896 
3897 	lck_mtx_unlock(&pkg_extensions_lck);
3898 
3899 	// if we get here, no extension matched
3900 	return 0;
3901 }
3902 
3903 int
vn_path_package_check(__unused vnode_t vp,char * path,int pathlen,int * component)3904 vn_path_package_check(__unused vnode_t vp, char *path, int pathlen, int *component)
3905 {
3906 	char *ptr, *end;
3907 	int comp = 0;
3908 
3909 	if (pathlen < 0) {
3910 		return EINVAL;
3911 	}
3912 
3913 	*component = -1;
3914 	if (*path != '/') {
3915 		return EINVAL;
3916 	}
3917 
3918 	end = path + 1;
3919 	while (end < path + pathlen && *end != '\0') {
3920 		while (end < path + pathlen && *end == '/' && *end != '\0') {
3921 			end++;
3922 		}
3923 
3924 		ptr = end;
3925 
3926 		while (end < path + pathlen && *end != '/' && *end != '\0') {
3927 			end++;
3928 		}
3929 
3930 		if (end > path + pathlen) {
3931 			// hmm, string wasn't null terminated
3932 			return EINVAL;
3933 		}
3934 
3935 		*end = '\0';
3936 		if (is_package_name(ptr, (int)(end - ptr))) {
3937 			*component = comp;
3938 			break;
3939 		}
3940 
3941 		end++;
3942 		comp++;
3943 	}
3944 
3945 	return 0;
3946 }
3947 
3948 /*
3949  * Determine if a name is inappropriate for a searchfs query.
3950  * This list consists of /System currently.
3951  */
3952 
3953 int
vn_searchfs_inappropriate_name(const char * name,int len)3954 vn_searchfs_inappropriate_name(const char *name, int len)
3955 {
3956 	const char *bad_names[] = { "System" };
3957 	int   bad_len[]   = { 6 };
3958 	int  i;
3959 
3960 	if (len < 0) {
3961 		return EINVAL;
3962 	}
3963 
3964 	for (i = 0; i < (int) (sizeof(bad_names) / sizeof(bad_names[0])); i++) {
3965 		if (len == bad_len[i] && strncmp(name, bad_names[i], strlen(bad_names[i]) + 1) == 0) {
3966 			return 1;
3967 		}
3968 	}
3969 
3970 	// if we get here, no name matched
3971 	return 0;
3972 }
3973 
3974 /*
3975  * Top level filesystem related information gathering.
3976  */
3977 extern unsigned int vfs_nummntops;
3978 
3979 /*
3980  * The VFS_NUMMNTOPS shouldn't be at name[1] since
3981  * is a VFS generic variable. Since we no longer support
3982  * VT_UFS, we reserve its value to support this sysctl node.
3983  *
3984  * It should have been:
3985  *    name[0]:  VFS_GENERIC
3986  *    name[1]:  VFS_NUMMNTOPS
3987  */
3988 SYSCTL_INT(_vfs, VFS_NUMMNTOPS, nummntops,
3989     CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
3990     &vfs_nummntops, 0, "");
3991 
3992 int
3993 vfs_sysctl(int *name __unused, u_int namelen __unused,
3994     user_addr_t oldp __unused, size_t *oldlenp __unused,
3995     user_addr_t newp __unused, size_t newlen __unused, proc_t p __unused);
3996 
3997 int
vfs_sysctl(int * name __unused,u_int namelen __unused,user_addr_t oldp __unused,size_t * oldlenp __unused,user_addr_t newp __unused,size_t newlen __unused,proc_t p __unused)3998 vfs_sysctl(int *name __unused, u_int namelen __unused,
3999     user_addr_t oldp __unused, size_t *oldlenp __unused,
4000     user_addr_t newp __unused, size_t newlen __unused, proc_t p __unused)
4001 {
4002 	return EINVAL;
4003 }
4004 
4005 
4006 //
4007 // The following code disallows specific sysctl's that came through
4008 // the direct sysctl interface (vfs_sysctl_node) instead of the newer
4009 // sysctl_vfs_ctlbyfsid() interface.  We can not allow these selectors
4010 // through vfs_sysctl_node() because it passes the user's oldp pointer
4011 // directly to the file system which (for these selectors) casts it
4012 // back to a struct sysctl_req and then proceed to use SYSCTL_IN()
4013 // which jumps through an arbitrary function pointer.  When called
4014 // through the sysctl_vfs_ctlbyfsid() interface this does not happen
4015 // and so it's safe.
4016 //
4017 // Unfortunately we have to pull in definitions from AFP and SMB and
4018 // perform explicit name checks on the file system to determine if
4019 // these selectors are being used.
4020 //
4021 
4022 #define AFPFS_VFS_CTL_GETID            0x00020001
4023 #define AFPFS_VFS_CTL_NETCHANGE        0x00020002
4024 #define AFPFS_VFS_CTL_VOLCHANGE        0x00020003
4025 
4026 #define SMBFS_SYSCTL_REMOUNT           1
4027 #define SMBFS_SYSCTL_REMOUNT_INFO      2
4028 #define SMBFS_SYSCTL_GET_SERVER_SHARE  3
4029 
4030 
4031 static int
is_bad_sysctl_name(struct vfstable * vfsp,int selector_name)4032 is_bad_sysctl_name(struct vfstable *vfsp, int selector_name)
4033 {
4034 	switch (selector_name) {
4035 	case VFS_CTL_QUERY:
4036 	case VFS_CTL_TIMEO:
4037 	case VFS_CTL_NOLOCKS:
4038 	case VFS_CTL_NSTATUS:
4039 	case VFS_CTL_SADDR:
4040 	case VFS_CTL_DISC:
4041 	case VFS_CTL_SERVERINFO:
4042 		return 1;
4043 
4044 	default:
4045 		break;
4046 	}
4047 
4048 	// the more complicated check for some of SMB's special values
4049 	if (strcmp(vfsp->vfc_name, "smbfs") == 0) {
4050 		switch (selector_name) {
4051 		case SMBFS_SYSCTL_REMOUNT:
4052 		case SMBFS_SYSCTL_REMOUNT_INFO:
4053 		case SMBFS_SYSCTL_GET_SERVER_SHARE:
4054 			return 1;
4055 		}
4056 	} else if (strcmp(vfsp->vfc_name, "afpfs") == 0) {
4057 		switch (selector_name) {
4058 		case AFPFS_VFS_CTL_GETID:
4059 		case AFPFS_VFS_CTL_NETCHANGE:
4060 		case AFPFS_VFS_CTL_VOLCHANGE:
4061 			return 1;
4062 		}
4063 	}
4064 
4065 	//
4066 	// If we get here we passed all the checks so the selector is ok
4067 	//
4068 	return 0;
4069 }
4070 
4071 
4072 int vfs_sysctl_node SYSCTL_HANDLER_ARGS
4073 {
4074 	int *name, namelen;
4075 	struct vfstable *vfsp;
4076 	int error;
4077 	int fstypenum;
4078 
4079 	fstypenum = oidp->oid_number;
4080 	name = arg1;
4081 	namelen = arg2;
4082 
4083 	/* all sysctl names at this level should have at least one name slot for the FS */
4084 	if (namelen < 1) {
4085 		return EISDIR; /* overloaded */
4086 	}
4087 	mount_list_lock();
4088 	for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
4089 		if (vfsp->vfc_typenum == fstypenum) {
4090 			vfsp->vfc_refcount++;
4091 			break;
4092 		}
4093 	}
4094 	mount_list_unlock();
4095 
4096 	if (vfsp == NULL) {
4097 		return ENOTSUP;
4098 	}
4099 
4100 	if (is_bad_sysctl_name(vfsp, name[0])) {
4101 		printf("vfs: bad selector 0x%.8x for old-style sysctl().  use the sysctl-by-fsid interface instead\n", name[0]);
4102 		error = EPERM;
4103 	} else {
4104 		error = (vfsp->vfc_vfsops->vfs_sysctl)(name, namelen,
4105 		    req->oldptr, &req->oldlen, req->newptr, req->newlen,
4106 		    vfs_context_current());
4107 	}
4108 
4109 	mount_list_lock();
4110 	vfsp->vfc_refcount--;
4111 	mount_list_unlock();
4112 
4113 	return error;
4114 }
4115 
4116 /*
4117  * Check to see if a filesystem is mounted on a block device.
4118  */
4119 int
vfs_mountedon(struct vnode * vp)4120 vfs_mountedon(struct vnode *vp)
4121 {
4122 	struct vnode *vq;
4123 	int error = 0;
4124 
4125 restart:
4126 	SPECHASH_LOCK();
4127 	if (vp->v_specflags & SI_MOUNTING && (vp->v_specinfo->si_mountingowner != current_thread())) {
4128 		msleep((caddr_t)&vp->v_specflags, SPECHASH_LOCK_ADDR(), PVFS | PDROP, "vnode_waitformounting", NULL);
4129 		goto restart;
4130 	}
4131 	if (vp->v_specflags & SI_MOUNTEDON) {
4132 		error = EBUSY;
4133 		goto out;
4134 	}
4135 	if (vp->v_specflags & SI_ALIASED) {
4136 		for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
4137 			if (vq->v_rdev != vp->v_rdev ||
4138 			    vq->v_type != vp->v_type || vq == vp) {
4139 				continue;
4140 			}
4141 			if (vq->v_specflags & SI_MOUNTING) {
4142 				msleep((caddr_t)&vq->v_specflags, SPECHASH_LOCK_ADDR(), PVFS | PDROP, "vnode_waitformounting", NULL);
4143 				goto restart;
4144 			}
4145 			if (vq->v_specflags & SI_MOUNTEDON) {
4146 				error = EBUSY;
4147 				break;
4148 			}
4149 		}
4150 	}
4151 out:
4152 	SPECHASH_UNLOCK();
4153 	return error;
4154 }
4155 
4156 void
vfs_setmountedon(vnode_t vp)4157 vfs_setmountedon(vnode_t vp)
4158 {
4159 	vnode_lock(vp);
4160 	SPECHASH_LOCK();
4161 	vp->v_specflags |= SI_MOUNTEDON;
4162 	vp->v_specflags &= ~SI_MOUNTING;
4163 	vp->v_specinfo->si_mountingowner = NULL;
4164 	SPECHASH_UNLOCK();
4165 	vnode_unlock(vp);
4166 	wakeup(&vp->v_specflags);
4167 }
4168 
4169 void
vfs_clearmounting(vnode_t vp)4170 vfs_clearmounting(vnode_t vp)
4171 {
4172 	vnode_lock(vp);
4173 	SPECHASH_LOCK();
4174 	vp->v_specflags &= ~SI_MOUNTING;
4175 	vp->v_specinfo->si_mountingowner = NULL;
4176 	SPECHASH_UNLOCK();
4177 	vnode_unlock(vp);
4178 	wakeup(&vp->v_specflags);
4179 }
4180 
4181 /*
4182  * Check to see if a filesystem is mounted on a block device.
4183  */
4184 int
vfs_setmounting(vnode_t vp)4185 vfs_setmounting(vnode_t vp)
4186 {
4187 	struct vnode *vq;
4188 	int error = 0;
4189 
4190 	vnode_lock(vp);
4191 	while (vp->v_specflags & SI_MOUNTING) {
4192 		msleep((caddr_t)&vp->v_specflags, &vp->v_lock, PVFS, "vnode_waitformounting", NULL);
4193 	}
4194 	if (vp->v_specflags & SI_MOUNTEDON) {
4195 		vnode_unlock(vp);
4196 		return EBUSY;
4197 	}
4198 	SPECHASH_LOCK();
4199 	vp->v_specflags |= SI_MOUNTING;
4200 	vp->v_specinfo->si_mountingowner = current_thread();
4201 	vnode_unlock(vp);
4202 restart:
4203 	if (vp->v_specflags & SI_ALIASED) {
4204 		for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) {
4205 			if (vq->v_rdev != vp->v_rdev ||
4206 			    vq->v_type != vp->v_type || vq == vp) {
4207 				continue;
4208 			}
4209 			if (vq->v_specflags & SI_MOUNTING) {
4210 				msleep((caddr_t)&vq->v_specflags, SPECHASH_LOCK_ADDR(), PVFS | PDROP, "vnode_waitformounting", NULL);
4211 				SPECHASH_LOCK();
4212 				goto restart;
4213 			}
4214 			if (vq->v_specflags & SI_MOUNTEDON) {
4215 				error = EBUSY;
4216 				break;
4217 			}
4218 		}
4219 	}
4220 	SPECHASH_UNLOCK();
4221 	if (error) {
4222 		vnode_lock(vp);
4223 		SPECHASH_LOCK();
4224 		vp->v_specflags &= ~SI_MOUNTING;
4225 		SPECHASH_UNLOCK();
4226 		vnode_unlock(vp);
4227 		wakeup(&vp->v_specflags);
4228 	}
4229 	return error;
4230 }
4231 
4232 struct unmount_info {
4233 	int     u_errs; // Total failed unmounts
4234 	int     u_busy; // EBUSY failed unmounts
4235 	int     u_count; // Total volumes iterated
4236 	int     u_only_non_system;
4237 };
4238 
4239 static int
unmount_callback(mount_t mp,void * arg)4240 unmount_callback(mount_t mp, void *arg)
4241 {
4242 	int error;
4243 	char *mntname;
4244 	struct unmount_info *uip = arg;
4245 
4246 	uip->u_count++;
4247 
4248 	mntname = zalloc_flags(ZV_NAMEI, Z_WAITOK | Z_NOFAIL);
4249 	strlcpy(mntname, mp->mnt_vfsstat.f_mntonname, MAXPATHLEN);
4250 
4251 	if (uip->u_only_non_system
4252 	    && ((mp->mnt_flag & MNT_ROOTFS) || (mp->mnt_kern_flag & MNTK_SYSTEM))) { //MNTK_BACKS_ROOT
4253 		printf("unmount(%d) %s skipped\n", uip->u_only_non_system, mntname);
4254 		mount_iterdrop(mp);     // VFS_ITERATE_CB_DROPREF
4255 	} else {
4256 		printf("unmount(%d) %s\n", uip->u_only_non_system, mntname);
4257 
4258 		mount_ref(mp, 0);
4259 		mount_iterdrop(mp);     // VFS_ITERATE_CB_DROPREF
4260 		error = dounmount(mp, MNT_FORCE, 1, vfs_context_current());
4261 		if (error) {
4262 			uip->u_errs++;
4263 			printf("Unmount of %s failed (%d)\n", mntname ? mntname:"?", error);
4264 			if (error == EBUSY) {
4265 				uip->u_busy++;
4266 			}
4267 		}
4268 	}
4269 	zfree(ZV_NAMEI, mntname);
4270 
4271 	return VFS_RETURNED;
4272 }
4273 
4274 /*
4275  * Unmount all filesystems. The list is traversed in reverse order
4276  * of mounting to avoid dependencies.
4277  * Busy mounts are retried.
4278  */
4279 __private_extern__ void
vfs_unmountall(int only_non_system)4280 vfs_unmountall(int only_non_system)
4281 {
4282 	int mounts, sec = 1;
4283 	struct unmount_info ui;
4284 
4285 	/*
4286 	 * Ensure last-completion-time is valid before anyone can see that
4287 	 * VFS shutdown has started.
4288 	 */
4289 	vfs_shutdown_last_completion_time = mach_absolute_time();
4290 	OSMemoryBarrier();
4291 	vfs_unmountall_started = 1;
4292 	printf("vfs_unmountall(%ssystem) start\n", only_non_system ? "non" : "");
4293 
4294 retry:
4295 	ui.u_errs = ui.u_busy = ui.u_count = 0;
4296 	ui.u_only_non_system = only_non_system;
4297 	// avoid vfs_iterate deadlock in dounmount(), use VFS_ITERATE_CB_DROPREF
4298 	vfs_iterate(VFS_ITERATE_CB_DROPREF | VFS_ITERATE_TAIL_FIRST, unmount_callback, &ui);
4299 	mounts = mount_getvfscnt();
4300 	if (mounts == 0) {
4301 		goto out;
4302 	}
4303 	if (ui.u_busy > 0) {            // Busy mounts - wait & retry
4304 		tsleep(&nummounts, PVFS, "busy mount", sec * hz);
4305 		sec *= 2;
4306 		if (sec <= 32) {
4307 			goto retry;
4308 		}
4309 		printf("Unmounting timed out\n");
4310 	} else if (ui.u_count < mounts) {
4311 		// If the vfs_iterate missed mounts in progress - wait a bit
4312 		tsleep(&nummounts, PVFS, "missed mount", 2 * hz);
4313 	}
4314 
4315 out:
4316 	printf("vfs_unmountall(%ssystem) end\n", only_non_system ? "non" : "");
4317 
4318 	/*
4319 	 * reboot_kernel() calls us twice; once to deal with non-system
4320 	 * mounts, and again to sweep up anything left after terminating
4321 	 * DEXTs.  We're only finished once we've completed the second pass.
4322 	 */
4323 	if (!only_non_system) {
4324 		vfs_unmountall_finished = 1;
4325 	}
4326 }
4327 
4328 /*
4329  * vfs_shutdown_in_progress --
4330  *
4331  * Returns whether or not the VFS is shutting down the file systems.
4332  */
4333 boolean_t
vfs_shutdown_in_progress(void)4334 vfs_shutdown_in_progress(void)
4335 {
4336 	return vfs_unmountall_started && !vfs_unmountall_finished;
4337 }
4338 
4339 /*
4340  * vfs_shutdown_finished --
4341  *
4342  * Returns whether or not the VFS shutdown has completed.
4343  */
4344 boolean_t
vfs_shutdown_finished(void)4345 vfs_shutdown_finished(void)
4346 {
4347 	return !!vfs_unmountall_finished;
4348 }
4349 
4350 /*
4351  * vfs_update_last_completion_time --
4352  *
4353  * Updates the "last I/O completion time" timestamp used by the watchdog
4354  * to monitor VFS shutdown progress.  Called by various I/O stack layers
4355  * as operations complete and progress moves forward.
4356  */
4357 void
vfs_update_last_completion_time(void)4358 vfs_update_last_completion_time(void)
4359 {
4360 	if (vfs_unmountall_started) {
4361 		vfs_shutdown_last_completion_time = mach_absolute_time();
4362 	}
4363 }
4364 
4365 /*
4366  * vfs_last_completion_time --
4367  *
4368  * Returns the "last I/O completion time" timestamp.  Return
4369  * value is a mach_absolute_time() value, and is not meaningful
4370  * unless vfs_is_shutting_down() also returns true.
4371  */
4372 uint64_t
vfs_last_completion_time(void)4373 vfs_last_completion_time(void)
4374 {
4375 	return vfs_unmountall_started ? vfs_shutdown_last_completion_time : 0;
4376 }
4377 
4378 /*
4379  * This routine is called from vnode_pager_deallocate out of the VM
4380  * The path to vnode_pager_deallocate can only be initiated by ubc_destroy_named
4381  * on a vnode that has a UBCINFO
4382  */
4383 __private_extern__ void
vnode_pager_vrele(vnode_t vp)4384 vnode_pager_vrele(vnode_t vp)
4385 {
4386 	struct ubc_info *uip;
4387 
4388 	vnode_lock_spin(vp);
4389 
4390 	vp->v_lflag &= ~VNAMED_UBC;
4391 	if (vp->v_usecount != 0) {
4392 		/*
4393 		 * At the eleventh hour, just before the ubcinfo is
4394 		 * destroyed, ensure the ubc-specific v_usecount
4395 		 * reference has gone.  We use v_usecount != 0 as a hint;
4396 		 * ubc_unmap() does nothing if there's no mapping.
4397 		 *
4398 		 * This case is caused by coming here via forced unmount,
4399 		 * versus the usual vm_object_deallocate() path.
4400 		 * In the forced unmount case, ubc_destroy_named()
4401 		 * releases the pager before memory_object_last_unmap()
4402 		 * can be called.
4403 		 */
4404 		vnode_unlock(vp);
4405 		ubc_unmap(vp);
4406 		vnode_lock_spin(vp);
4407 	}
4408 
4409 	uip = vp->v_ubcinfo;
4410 	vp->v_ubcinfo = UBC_INFO_NULL;
4411 
4412 	vnode_unlock(vp);
4413 
4414 	ubc_info_deallocate(uip);
4415 }
4416 
4417 
4418 #include <sys/disk.h>
4419 
4420 u_int32_t rootunit = (u_int32_t)-1;
4421 
4422 #if CONFIG_IOSCHED
4423 extern int lowpri_throttle_enabled;
4424 extern int iosched_enabled;
4425 #endif
4426 
4427 errno_t
vfs_init_io_attributes(vnode_t devvp,mount_t mp)4428 vfs_init_io_attributes(vnode_t devvp, mount_t mp)
4429 {
4430 	int     error;
4431 	off_t   readblockcnt = 0;
4432 	off_t   writeblockcnt = 0;
4433 	off_t   readmaxcnt = 0;
4434 	off_t   writemaxcnt = 0;
4435 	off_t   readsegcnt = 0;
4436 	off_t   writesegcnt = 0;
4437 	off_t   readsegsize = 0;
4438 	off_t   writesegsize = 0;
4439 	off_t   alignment = 0;
4440 	u_int32_t minsaturationbytecount = 0;
4441 	u_int32_t ioqueue_depth = 0;
4442 	u_int32_t blksize;
4443 	u_int64_t temp;
4444 	u_int32_t features;
4445 	u_int64_t location = 0;
4446 	vfs_context_t ctx = vfs_context_current();
4447 	dk_corestorage_info_t cs_info;
4448 	boolean_t cs_present = FALSE;
4449 	int isssd = 0;
4450 	int isvirtual = 0;
4451 
4452 
4453 	VNOP_IOCTL(devvp, DKIOCGETTHROTTLEMASK, (caddr_t)&mp->mnt_throttle_mask, 0, NULL);
4454 	/*
4455 	 * as a reasonable approximation, only use the lowest bit of the mask
4456 	 * to generate a disk unit number
4457 	 */
4458 	mp->mnt_devbsdunit = mp->mnt_throttle_mask ?
4459 	    num_trailing_0(mp->mnt_throttle_mask) : (LOWPRI_MAX_NUM_DEV - 1);
4460 
4461 	if (devvp == rootvp) {
4462 		rootunit = mp->mnt_devbsdunit;
4463 	}
4464 
4465 	if (mp->mnt_devbsdunit == rootunit) {
4466 		/*
4467 		 * this mount point exists on the same device as the root
4468 		 * partition, so it comes under the hard throttle control...
4469 		 * this is true even for the root mount point itself
4470 		 */
4471 		mp->mnt_kern_flag |= MNTK_ROOTDEV;
4472 	}
4473 	/*
4474 	 * force the spec device to re-cache
4475 	 * the underlying block size in case
4476 	 * the filesystem overrode the initial value
4477 	 */
4478 	set_fsblocksize(devvp);
4479 
4480 
4481 	if ((error = VNOP_IOCTL(devvp, DKIOCGETBLOCKSIZE,
4482 	    (caddr_t)&blksize, 0, ctx))) {
4483 		return error;
4484 	}
4485 
4486 	mp->mnt_devblocksize = blksize;
4487 
4488 	/*
4489 	 * set the maximum possible I/O size
4490 	 * this may get clipped to a smaller value
4491 	 * based on which constraints are being advertised
4492 	 * and if those advertised constraints result in a smaller
4493 	 * limit for a given I/O
4494 	 */
4495 	mp->mnt_maxreadcnt = MAX_UPL_SIZE_BYTES;
4496 	mp->mnt_maxwritecnt = MAX_UPL_SIZE_BYTES;
4497 
4498 	if (VNOP_IOCTL(devvp, DKIOCISVIRTUAL, (caddr_t)&isvirtual, 0, ctx) == 0) {
4499 		if (isvirtual) {
4500 			mp->mnt_kern_flag |= MNTK_VIRTUALDEV;
4501 			mp->mnt_flag |= MNT_REMOVABLE;
4502 		}
4503 	}
4504 	if (VNOP_IOCTL(devvp, DKIOCISSOLIDSTATE, (caddr_t)&isssd, 0, ctx) == 0) {
4505 		if (isssd) {
4506 			mp->mnt_kern_flag |= MNTK_SSD;
4507 		}
4508 	}
4509 	if ((error = VNOP_IOCTL(devvp, DKIOCGETFEATURES,
4510 	    (caddr_t)&features, 0, ctx))) {
4511 		return error;
4512 	}
4513 
4514 	if ((error = VNOP_IOCTL(devvp, DKIOCGETMAXBLOCKCOUNTREAD,
4515 	    (caddr_t)&readblockcnt, 0, ctx))) {
4516 		return error;
4517 	}
4518 
4519 	if ((error = VNOP_IOCTL(devvp, DKIOCGETMAXBLOCKCOUNTWRITE,
4520 	    (caddr_t)&writeblockcnt, 0, ctx))) {
4521 		return error;
4522 	}
4523 
4524 	if ((error = VNOP_IOCTL(devvp, DKIOCGETMAXBYTECOUNTREAD,
4525 	    (caddr_t)&readmaxcnt, 0, ctx))) {
4526 		return error;
4527 	}
4528 
4529 	if ((error = VNOP_IOCTL(devvp, DKIOCGETMAXBYTECOUNTWRITE,
4530 	    (caddr_t)&writemaxcnt, 0, ctx))) {
4531 		return error;
4532 	}
4533 
4534 	if ((error = VNOP_IOCTL(devvp, DKIOCGETMAXSEGMENTCOUNTREAD,
4535 	    (caddr_t)&readsegcnt, 0, ctx))) {
4536 		return error;
4537 	}
4538 
4539 	if ((error = VNOP_IOCTL(devvp, DKIOCGETMAXSEGMENTCOUNTWRITE,
4540 	    (caddr_t)&writesegcnt, 0, ctx))) {
4541 		return error;
4542 	}
4543 
4544 	if ((error = VNOP_IOCTL(devvp, DKIOCGETMAXSEGMENTBYTECOUNTREAD,
4545 	    (caddr_t)&readsegsize, 0, ctx))) {
4546 		return error;
4547 	}
4548 
4549 	if ((error = VNOP_IOCTL(devvp, DKIOCGETMAXSEGMENTBYTECOUNTWRITE,
4550 	    (caddr_t)&writesegsize, 0, ctx))) {
4551 		return error;
4552 	}
4553 
4554 	if ((error = VNOP_IOCTL(devvp, DKIOCGETMINSEGMENTALIGNMENTBYTECOUNT,
4555 	    (caddr_t)&alignment, 0, ctx))) {
4556 		return error;
4557 	}
4558 
4559 	if ((error = VNOP_IOCTL(devvp, DKIOCGETCOMMANDPOOLSIZE,
4560 	    (caddr_t)&ioqueue_depth, 0, ctx))) {
4561 		return error;
4562 	}
4563 
4564 	if (readmaxcnt) {
4565 		mp->mnt_maxreadcnt = (readmaxcnt > UINT32_MAX) ? UINT32_MAX :(uint32_t) readmaxcnt;
4566 	}
4567 
4568 	if (readblockcnt) {
4569 		temp = readblockcnt * blksize;
4570 		temp = (temp > UINT32_MAX) ? UINT32_MAX : temp;
4571 
4572 		if (temp < mp->mnt_maxreadcnt) {
4573 			mp->mnt_maxreadcnt = (u_int32_t)temp;
4574 		}
4575 	}
4576 
4577 	if (writemaxcnt) {
4578 		mp->mnt_maxwritecnt = (writemaxcnt > UINT32_MAX) ? UINT32_MAX : (uint32_t)writemaxcnt;
4579 	}
4580 
4581 	if (writeblockcnt) {
4582 		temp = writeblockcnt * blksize;
4583 		temp = (temp > UINT32_MAX) ? UINT32_MAX : temp;
4584 
4585 		if (temp < mp->mnt_maxwritecnt) {
4586 			mp->mnt_maxwritecnt = (u_int32_t)temp;
4587 		}
4588 	}
4589 
4590 	if (readsegcnt) {
4591 		temp = (readsegcnt > UINT16_MAX) ? UINT16_MAX : readsegcnt;
4592 	} else {
4593 		temp = mp->mnt_maxreadcnt / PAGE_SIZE;
4594 
4595 		if (temp > UINT16_MAX) {
4596 			temp = UINT16_MAX;
4597 		}
4598 	}
4599 	mp->mnt_segreadcnt = (u_int16_t)temp;
4600 
4601 	if (writesegcnt) {
4602 		temp = (writesegcnt > UINT16_MAX) ? UINT16_MAX : writesegcnt;
4603 	} else {
4604 		temp = mp->mnt_maxwritecnt / PAGE_SIZE;
4605 
4606 		if (temp > UINT16_MAX) {
4607 			temp = UINT16_MAX;
4608 		}
4609 	}
4610 	mp->mnt_segwritecnt = (u_int16_t)temp;
4611 
4612 	if (readsegsize) {
4613 		temp = (readsegsize > UINT32_MAX) ? UINT32_MAX : readsegsize;
4614 	} else {
4615 		temp = mp->mnt_maxreadcnt;
4616 	}
4617 	mp->mnt_maxsegreadsize = (u_int32_t)temp;
4618 
4619 	if (writesegsize) {
4620 		temp = (writesegsize > UINT32_MAX) ? UINT32_MAX : writesegsize;
4621 	} else {
4622 		temp = mp->mnt_maxwritecnt;
4623 	}
4624 	mp->mnt_maxsegwritesize = (u_int32_t)temp;
4625 
4626 	if (alignment) {
4627 		temp = (alignment > PAGE_SIZE) ? PAGE_MASK : alignment - 1;
4628 	} else {
4629 		temp = 0;
4630 	}
4631 	mp->mnt_alignmentmask = (uint32_t)temp;
4632 
4633 
4634 	if (ioqueue_depth > MNT_DEFAULT_IOQUEUE_DEPTH) {
4635 		temp = ioqueue_depth;
4636 	} else {
4637 		temp = MNT_DEFAULT_IOQUEUE_DEPTH;
4638 	}
4639 
4640 	mp->mnt_ioqueue_depth = (uint32_t)temp;
4641 	mp->mnt_ioscale = MNT_IOSCALE(mp->mnt_ioqueue_depth);
4642 
4643 	if (mp->mnt_ioscale > 1) {
4644 		printf("ioqueue_depth = %d,   ioscale = %d\n", (int)mp->mnt_ioqueue_depth, (int)mp->mnt_ioscale);
4645 	}
4646 
4647 	if (features & DK_FEATURE_FORCE_UNIT_ACCESS) {
4648 		mp->mnt_ioflags |= MNT_IOFLAGS_FUA_SUPPORTED;
4649 	}
4650 
4651 	if (VNOP_IOCTL(devvp, DKIOCGETIOMINSATURATIONBYTECOUNT, (caddr_t)&minsaturationbytecount, 0, ctx) == 0) {
4652 		mp->mnt_minsaturationbytecount = minsaturationbytecount;
4653 	} else {
4654 		mp->mnt_minsaturationbytecount = 0;
4655 	}
4656 
4657 	if (VNOP_IOCTL(devvp, DKIOCCORESTORAGE, (caddr_t)&cs_info, 0, ctx) == 0) {
4658 		cs_present = TRUE;
4659 	}
4660 
4661 	if (features & DK_FEATURE_UNMAP) {
4662 		mp->mnt_ioflags |= MNT_IOFLAGS_UNMAP_SUPPORTED;
4663 
4664 		if (cs_present == TRUE) {
4665 			mp->mnt_ioflags |= MNT_IOFLAGS_CSUNMAP_SUPPORTED;
4666 		}
4667 	}
4668 	if (cs_present == TRUE) {
4669 		/*
4670 		 * for now we'll use the following test as a proxy for
4671 		 * the underlying drive being FUSION in nature
4672 		 */
4673 		if ((cs_info.flags & DK_CORESTORAGE_PIN_YOUR_METADATA)) {
4674 			mp->mnt_ioflags |= MNT_IOFLAGS_FUSION_DRIVE;
4675 		}
4676 	} else {
4677 		/* Check for APFS Fusion */
4678 		dk_apfs_flavour_t flavour;
4679 		if ((VNOP_IOCTL(devvp, DKIOCGETAPFSFLAVOUR, (caddr_t)&flavour, 0, ctx) == 0) &&
4680 		    (flavour == DK_APFS_FUSION)) {
4681 			mp->mnt_ioflags |= MNT_IOFLAGS_FUSION_DRIVE;
4682 		}
4683 	}
4684 
4685 	if (VNOP_IOCTL(devvp, DKIOCGETLOCATION, (caddr_t)&location, 0, ctx) == 0) {
4686 		if (location & DK_LOCATION_EXTERNAL) {
4687 			mp->mnt_ioflags |= MNT_IOFLAGS_PERIPHERAL_DRIVE;
4688 			mp->mnt_flag |= MNT_REMOVABLE;
4689 		}
4690 	}
4691 
4692 #if CONFIG_IOSCHED
4693 	if (iosched_enabled && (features & DK_FEATURE_PRIORITY)) {
4694 		mp->mnt_ioflags |= MNT_IOFLAGS_IOSCHED_SUPPORTED;
4695 		throttle_info_disable_throttle(mp->mnt_devbsdunit, (mp->mnt_ioflags & MNT_IOFLAGS_FUSION_DRIVE) != 0);
4696 	}
4697 #endif /* CONFIG_IOSCHED */
4698 	return error;
4699 }
4700 
4701 static struct klist fs_klist;
4702 static LCK_GRP_DECLARE(fs_klist_lck_grp, "fs_klist");
4703 static LCK_MTX_DECLARE(fs_klist_lock, &fs_klist_lck_grp);
4704 
4705 void
vfs_event_init(void)4706 vfs_event_init(void)
4707 {
4708 	klist_init(&fs_klist);
4709 }
4710 
4711 void
vfs_event_signal(fsid_t * fsid,u_int32_t event,intptr_t data)4712 vfs_event_signal(fsid_t *fsid, u_int32_t event, intptr_t data)
4713 {
4714 	if (event == VQ_DEAD || event == VQ_NOTRESP) {
4715 		struct mount *mp = vfs_getvfs(fsid);
4716 		if (mp) {
4717 			mount_lock_spin(mp);
4718 			if (data) {
4719 				mp->mnt_lflag &= ~MNT_LNOTRESP;     // Now responding
4720 			} else {
4721 				mp->mnt_lflag |= MNT_LNOTRESP;      // Not responding
4722 			}
4723 			mount_unlock(mp);
4724 		}
4725 	}
4726 
4727 	lck_mtx_lock(&fs_klist_lock);
4728 	KNOTE(&fs_klist, event);
4729 	lck_mtx_unlock(&fs_klist_lock);
4730 }
4731 
4732 /*
4733  * return the number of mounted filesystems.
4734  */
4735 static int
sysctl_vfs_getvfscnt(void)4736 sysctl_vfs_getvfscnt(void)
4737 {
4738 	return mount_getvfscnt();
4739 }
4740 
4741 
4742 static int
mount_getvfscnt(void)4743 mount_getvfscnt(void)
4744 {
4745 	int ret;
4746 
4747 	mount_list_lock();
4748 	ret = nummounts;
4749 	mount_list_unlock();
4750 	return ret;
4751 }
4752 
4753 
4754 
4755 static int
mount_fillfsids(fsid_t * fsidlst,int count)4756 mount_fillfsids(fsid_t *fsidlst, int count)
4757 {
4758 	struct mount *mp;
4759 	int actual = 0;
4760 
4761 	actual = 0;
4762 	mount_list_lock();
4763 	TAILQ_FOREACH(mp, &mountlist, mnt_list) {
4764 		if (actual < count) {
4765 			fsidlst[actual] = mp->mnt_vfsstat.f_fsid;
4766 			actual++;
4767 		}
4768 	}
4769 	mount_list_unlock();
4770 	return actual;
4771 }
4772 
4773 /*
4774  * fill in the array of fsid_t's up to a max of 'count', the actual
4775  * number filled in will be set in '*actual'.  If there are more fsid_t's
4776  * than room in fsidlst then ENOMEM will be returned and '*actual' will
4777  * have the actual count.
4778  * having *actual filled out even in the error case is depended upon.
4779  */
4780 static int
sysctl_vfs_getvfslist(fsid_t * fsidlst,unsigned long count,unsigned long * actual)4781 sysctl_vfs_getvfslist(fsid_t *fsidlst, unsigned long count, unsigned long *actual)
4782 {
4783 	struct mount *mp;
4784 
4785 	*actual = 0;
4786 	mount_list_lock();
4787 	TAILQ_FOREACH(mp, &mountlist, mnt_list) {
4788 		(*actual)++;
4789 		if (*actual <= count) {
4790 			fsidlst[(*actual) - 1] = mp->mnt_vfsstat.f_fsid;
4791 		}
4792 	}
4793 	mount_list_unlock();
4794 	return *actual <= count ? 0 : ENOMEM;
4795 }
4796 
4797 static int
sysctl_vfs_vfslist(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)4798 sysctl_vfs_vfslist(__unused struct sysctl_oid *oidp, __unused void *arg1,
4799     __unused int arg2, struct sysctl_req *req)
4800 {
4801 	unsigned long actual;
4802 	int error;
4803 	size_t space;
4804 	fsid_t *fsidlst;
4805 
4806 	/* This is a readonly node. */
4807 	if (req->newptr != USER_ADDR_NULL) {
4808 		return EPERM;
4809 	}
4810 
4811 	/* they are querying us so just return the space required. */
4812 	if (req->oldptr == USER_ADDR_NULL) {
4813 		req->oldidx = sysctl_vfs_getvfscnt() * sizeof(fsid_t);
4814 		return 0;
4815 	}
4816 again:
4817 	/*
4818 	 * Retrieve an accurate count of the amount of space required to copy
4819 	 * out all the fsids in the system.
4820 	 */
4821 	space = req->oldlen;
4822 	req->oldlen = sysctl_vfs_getvfscnt() * sizeof(fsid_t);
4823 
4824 	/* they didn't give us enough space. */
4825 	if (space < req->oldlen) {
4826 		return ENOMEM;
4827 	}
4828 
4829 	fsidlst = kalloc_data(req->oldlen, Z_WAITOK | Z_ZERO);
4830 	if (fsidlst == NULL) {
4831 		return ENOMEM;
4832 	}
4833 
4834 	error = sysctl_vfs_getvfslist(fsidlst, req->oldlen / sizeof(fsid_t),
4835 	    &actual);
4836 	/*
4837 	 * If we get back ENOMEM, then another mount has been added while we
4838 	 * slept in malloc above.  If this is the case then try again.
4839 	 */
4840 	if (error == ENOMEM) {
4841 		kfree_data(fsidlst, req->oldlen);
4842 		req->oldlen = space;
4843 		goto again;
4844 	}
4845 	if (error == 0) {
4846 		error = SYSCTL_OUT(req, fsidlst, actual * sizeof(fsid_t));
4847 	}
4848 	kfree_data(fsidlst, req->oldlen);
4849 	return error;
4850 }
4851 
4852 /*
4853  * Do a sysctl by fsid.
4854  */
4855 static int
sysctl_vfs_ctlbyfsid(__unused struct sysctl_oid * oidp,void * arg1,int arg2,struct sysctl_req * req)4856 sysctl_vfs_ctlbyfsid(__unused struct sysctl_oid *oidp, void *arg1, int arg2,
4857     struct sysctl_req *req)
4858 {
4859 	union union_vfsidctl vc;
4860 	struct mount *mp = NULL;
4861 	struct vfsstatfs *sp;
4862 	int *name, namelen;
4863 	int flags = 0;
4864 	int error = 0, gotref = 0;
4865 	vfs_context_t ctx = vfs_context_current();
4866 	proc_t p = req->p;      /* XXX req->p != current_proc()? */
4867 	boolean_t is_64_bit;
4868 	union {
4869 		struct statfs64 sfs64;
4870 		struct user64_statfs osfs64;
4871 		struct user32_statfs osfs32;
4872 	} *sfsbuf;
4873 
4874 	if (req->newptr == USER_ADDR_NULL) {
4875 		error = EINVAL;
4876 		goto out;
4877 	}
4878 
4879 	name = arg1;
4880 	namelen = arg2;
4881 	is_64_bit = proc_is64bit(p);
4882 
4883 	error = SYSCTL_IN(req, &vc, is_64_bit? sizeof(vc.vc64):sizeof(vc.vc32));
4884 	if (error) {
4885 		goto out;
4886 	}
4887 	if (vc.vc32.vc_vers != VFS_CTL_VERS1) { /* works for 32 and 64 */
4888 		error = EINVAL;
4889 		goto out;
4890 	}
4891 	mp = mount_list_lookupby_fsid(&vc.vc32.vc_fsid, 0, 1); /* works for 32 and 64 */
4892 	if (mp == NULL) {
4893 		error = ENOENT;
4894 		goto out;
4895 	}
4896 	gotref = 1;
4897 	/* reset so that the fs specific code can fetch it. */
4898 	req->newidx = 0;
4899 	/*
4900 	 * Note if this is a VFS_CTL then we pass the actual sysctl req
4901 	 * in for "oldp" so that the lower layer can DTRT and use the
4902 	 * SYSCTL_IN/OUT routines.
4903 	 */
4904 	if (mp->mnt_op->vfs_sysctl != NULL) {
4905 		if (is_64_bit) {
4906 			if (vfs_64bitready(mp)) {
4907 				error = mp->mnt_op->vfs_sysctl(name, namelen,
4908 				    CAST_USER_ADDR_T(req),
4909 				    NULL, USER_ADDR_NULL, 0,
4910 				    ctx);
4911 			} else {
4912 				error = ENOTSUP;
4913 			}
4914 		} else {
4915 			error = mp->mnt_op->vfs_sysctl(name, namelen,
4916 			    CAST_USER_ADDR_T(req),
4917 			    NULL, USER_ADDR_NULL, 0,
4918 			    ctx);
4919 		}
4920 		if (error != ENOTSUP) {
4921 			goto out;
4922 		}
4923 	}
4924 	switch (name[0]) {
4925 	case VFS_CTL_UMOUNT:
4926 #if CONFIG_MACF
4927 		error = mac_mount_check_umount(ctx, mp);
4928 		if (error != 0) {
4929 			goto out;
4930 		}
4931 #endif
4932 		req->newidx = 0;
4933 		if (is_64_bit) {
4934 			req->newptr = vc.vc64.vc_ptr;
4935 			req->newlen = (size_t)vc.vc64.vc_len;
4936 		} else {
4937 			req->newptr = CAST_USER_ADDR_T(vc.vc32.vc_ptr);
4938 			req->newlen = vc.vc32.vc_len;
4939 		}
4940 		error = SYSCTL_IN(req, &flags, sizeof(flags));
4941 		if (error) {
4942 			break;
4943 		}
4944 
4945 		mount_ref(mp, 0);
4946 		mount_iterdrop(mp);
4947 		gotref = 0;
4948 		/* safedounmount consumes a ref */
4949 		error = safedounmount(mp, flags, ctx);
4950 		break;
4951 	case VFS_CTL_OSTATFS:
4952 	case VFS_CTL_STATFS64:
4953 #if CONFIG_MACF
4954 		error = mac_mount_check_stat(ctx, mp);
4955 		if (error != 0) {
4956 			break;
4957 		}
4958 #endif
4959 		req->newidx = 0;
4960 		if (is_64_bit) {
4961 			req->newptr = vc.vc64.vc_ptr;
4962 			req->newlen = (size_t)vc.vc64.vc_len;
4963 		} else {
4964 			req->newptr = CAST_USER_ADDR_T(vc.vc32.vc_ptr);
4965 			req->newlen = vc.vc32.vc_len;
4966 		}
4967 		error = SYSCTL_IN(req, &flags, sizeof(flags));
4968 		if (error) {
4969 			break;
4970 		}
4971 		sp = &mp->mnt_vfsstat;
4972 		if (((flags & MNT_NOWAIT) == 0 || (flags & (MNT_WAIT | MNT_DWAIT))) &&
4973 		    (error = vfs_update_vfsstat(mp, ctx, VFS_USER_EVENT))) {
4974 			goto out;
4975 		}
4976 
4977 		sfsbuf = kalloc_type(typeof(*sfsbuf), Z_WAITOK);
4978 
4979 		if (name[0] == VFS_CTL_STATFS64) {
4980 			struct statfs64 *sfs = &sfsbuf->sfs64;
4981 
4982 			vfs_get_statfs64(mp, sfs);
4983 			error = SYSCTL_OUT(req, sfs, sizeof(*sfs));
4984 		} else if (is_64_bit) {
4985 			struct user64_statfs *sfs = &sfsbuf->osfs64;
4986 
4987 			bzero(sfs, sizeof(*sfs));
4988 			sfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
4989 			sfs->f_type = (short)mp->mnt_vtable->vfc_typenum;
4990 			sfs->f_bsize = (user64_long_t)sp->f_bsize;
4991 			sfs->f_iosize = (user64_long_t)sp->f_iosize;
4992 			sfs->f_blocks = (user64_long_t)sp->f_blocks;
4993 			sfs->f_bfree = (user64_long_t)sp->f_bfree;
4994 			sfs->f_bavail = (user64_long_t)sp->f_bavail;
4995 			sfs->f_files = (user64_long_t)sp->f_files;
4996 			sfs->f_ffree = (user64_long_t)sp->f_ffree;
4997 			sfs->f_fsid = sp->f_fsid;
4998 			sfs->f_owner = sp->f_owner;
4999 			vfs_getfstypename(mp, sfs->f_fstypename, MFSNAMELEN);
5000 			strlcpy(sfs->f_mntonname, sp->f_mntonname, MNAMELEN);
5001 			strlcpy(sfs->f_mntfromname, sp->f_mntfromname, MNAMELEN);
5002 
5003 			error = SYSCTL_OUT(req, sfs, sizeof(*sfs));
5004 		} else {
5005 			struct user32_statfs *sfs = &sfsbuf->osfs32;
5006 			long temp;
5007 
5008 			bzero(sfs, sizeof(*sfs));
5009 			sfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
5010 			sfs->f_type = (short)mp->mnt_vtable->vfc_typenum;
5011 
5012 			/*
5013 			 * It's possible for there to be more than 2^^31 blocks in the filesystem, so we
5014 			 * have to fudge the numbers here in that case.   We inflate the blocksize in order
5015 			 * to reflect the filesystem size as best we can.
5016 			 */
5017 			if (sp->f_blocks > INT_MAX) {
5018 				int             shift;
5019 
5020 				/*
5021 				 * Work out how far we have to shift the block count down to make it fit.
5022 				 * Note that it's possible to have to shift so far that the resulting
5023 				 * blocksize would be unreportably large.  At that point, we will clip
5024 				 * any values that don't fit.
5025 				 *
5026 				 * For safety's sake, we also ensure that f_iosize is never reported as
5027 				 * being smaller than f_bsize.
5028 				 */
5029 				for (shift = 0; shift < 32; shift++) {
5030 					if ((sp->f_blocks >> shift) <= INT_MAX) {
5031 						break;
5032 					}
5033 					if ((((long long)sp->f_bsize) << (shift + 1)) > INT_MAX) {
5034 						break;
5035 					}
5036 				}
5037 #define __SHIFT_OR_CLIP(x, s)   ((((x) >> (s)) > INT_MAX) ? INT_MAX : ((x) >> (s)))
5038 				sfs->f_blocks = (user32_long_t)__SHIFT_OR_CLIP(sp->f_blocks, shift);
5039 				sfs->f_bfree = (user32_long_t)__SHIFT_OR_CLIP(sp->f_bfree, shift);
5040 				sfs->f_bavail = (user32_long_t)__SHIFT_OR_CLIP(sp->f_bavail, shift);
5041 #undef __SHIFT_OR_CLIP
5042 				sfs->f_bsize = (user32_long_t)(sp->f_bsize << shift);
5043 				temp = lmax(sp->f_iosize, sp->f_bsize);
5044 				if (temp > INT32_MAX) {
5045 					error = EINVAL;
5046 					kfree_type(typeof(*sfsbuf), sfsbuf);
5047 					goto out;
5048 				}
5049 				sfs->f_iosize = (user32_long_t)temp;
5050 			} else {
5051 				sfs->f_bsize = (user32_long_t)sp->f_bsize;
5052 				sfs->f_iosize = (user32_long_t)sp->f_iosize;
5053 				sfs->f_blocks = (user32_long_t)sp->f_blocks;
5054 				sfs->f_bfree = (user32_long_t)sp->f_bfree;
5055 				sfs->f_bavail = (user32_long_t)sp->f_bavail;
5056 			}
5057 			sfs->f_files = (user32_long_t)sp->f_files;
5058 			sfs->f_ffree = (user32_long_t)sp->f_ffree;
5059 			sfs->f_fsid = sp->f_fsid;
5060 			sfs->f_owner = sp->f_owner;
5061 
5062 			vfs_getfstypename(mp, sfs->f_fstypename, MFSNAMELEN);
5063 			strlcpy(sfs->f_mntonname, sp->f_mntonname, MNAMELEN);
5064 			strlcpy(sfs->f_mntfromname, sp->f_mntfromname, MNAMELEN);
5065 
5066 			error = SYSCTL_OUT(req, sfs, sizeof(*sfs));
5067 		}
5068 		kfree_type(typeof(*sfsbuf), sfsbuf);
5069 		break;
5070 	default:
5071 		error = ENOTSUP;
5072 		goto out;
5073 	}
5074 out:
5075 	if (gotref != 0) {
5076 		mount_iterdrop(mp);
5077 	}
5078 	return error;
5079 }
5080 
5081 static int      filt_fsattach(struct knote *kn, struct kevent_qos_s *kev);
5082 static void     filt_fsdetach(struct knote *kn);
5083 static int      filt_fsevent(struct knote *kn, long hint);
5084 static int      filt_fstouch(struct knote *kn, struct kevent_qos_s *kev);
5085 static int      filt_fsprocess(struct knote *kn, struct kevent_qos_s *kev);
5086 SECURITY_READ_ONLY_EARLY(struct filterops) fs_filtops = {
5087 	.f_attach = filt_fsattach,
5088 	.f_detach = filt_fsdetach,
5089 	.f_event = filt_fsevent,
5090 	.f_touch = filt_fstouch,
5091 	.f_process = filt_fsprocess,
5092 };
5093 
5094 static int
filt_fsattach(struct knote * kn,__unused struct kevent_qos_s * kev)5095 filt_fsattach(struct knote *kn, __unused struct kevent_qos_s *kev)
5096 {
5097 	kn->kn_flags |= EV_CLEAR; /* automatic */
5098 	kn->kn_sdata = 0;         /* incoming data is ignored */
5099 
5100 	lck_mtx_lock(&fs_klist_lock);
5101 	KNOTE_ATTACH(&fs_klist, kn);
5102 	lck_mtx_unlock(&fs_klist_lock);
5103 
5104 	/*
5105 	 * filter only sees future events,
5106 	 * so it can't be fired already.
5107 	 */
5108 	return 0;
5109 }
5110 
5111 static void
filt_fsdetach(struct knote * kn)5112 filt_fsdetach(struct knote *kn)
5113 {
5114 	lck_mtx_lock(&fs_klist_lock);
5115 	KNOTE_DETACH(&fs_klist, kn);
5116 	lck_mtx_unlock(&fs_klist_lock);
5117 }
5118 
5119 static int
filt_fsevent(struct knote * kn,long hint)5120 filt_fsevent(struct knote *kn, long hint)
5121 {
5122 	/*
5123 	 * Backwards compatibility:
5124 	 * Other filters would do nothing if kn->kn_sfflags == 0
5125 	 */
5126 
5127 	if ((kn->kn_sfflags == 0) || (kn->kn_sfflags & hint)) {
5128 		kn->kn_fflags |= hint;
5129 	}
5130 
5131 	return kn->kn_fflags != 0;
5132 }
5133 
5134 static int
filt_fstouch(struct knote * kn,struct kevent_qos_s * kev)5135 filt_fstouch(struct knote *kn, struct kevent_qos_s *kev)
5136 {
5137 	int res;
5138 
5139 	lck_mtx_lock(&fs_klist_lock);
5140 
5141 	kn->kn_sfflags = kev->fflags;
5142 
5143 	/*
5144 	 * the above filter function sets bits even if nobody is looking for them.
5145 	 * Just preserve those bits even in the new mask is more selective
5146 	 * than before.
5147 	 *
5148 	 * For compatibility with previous implementations, we leave kn_fflags
5149 	 * as they were before.
5150 	 */
5151 	//if (kn->kn_sfflags)
5152 	//	kn->kn_fflags &= kn->kn_sfflags;
5153 	res = (kn->kn_fflags != 0);
5154 
5155 	lck_mtx_unlock(&fs_klist_lock);
5156 
5157 	return res;
5158 }
5159 
5160 static int
filt_fsprocess(struct knote * kn,struct kevent_qos_s * kev)5161 filt_fsprocess(struct knote *kn, struct kevent_qos_s *kev)
5162 {
5163 	int res = 0;
5164 
5165 	lck_mtx_lock(&fs_klist_lock);
5166 	if (kn->kn_fflags) {
5167 		knote_fill_kevent(kn, kev, 0);
5168 		res = 1;
5169 	}
5170 	lck_mtx_unlock(&fs_klist_lock);
5171 	return res;
5172 }
5173 
5174 static int
sysctl_vfs_noremotehang(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)5175 sysctl_vfs_noremotehang(__unused struct sysctl_oid *oidp,
5176     __unused void *arg1, __unused int arg2, struct sysctl_req *req)
5177 {
5178 	int out, error;
5179 	pid_t pid;
5180 	proc_t p;
5181 
5182 	/* We need a pid. */
5183 	if (req->newptr == USER_ADDR_NULL) {
5184 		return EINVAL;
5185 	}
5186 
5187 	error = SYSCTL_IN(req, &pid, sizeof(pid));
5188 	if (error) {
5189 		return error;
5190 	}
5191 
5192 	p = proc_find(pid < 0 ? -pid : pid);
5193 	if (p == NULL) {
5194 		return ESRCH;
5195 	}
5196 
5197 	/*
5198 	 * Fetching the value is ok, but we only fetch if the old
5199 	 * pointer is given.
5200 	 */
5201 	if (req->oldptr != USER_ADDR_NULL) {
5202 		out = !((p->p_flag & P_NOREMOTEHANG) == 0);
5203 		proc_rele(p);
5204 		error = SYSCTL_OUT(req, &out, sizeof(out));
5205 		return error;
5206 	}
5207 
5208 	/* cansignal offers us enough security. */
5209 	if (p != req->p && proc_suser(req->p) != 0) {
5210 		proc_rele(p);
5211 		return EPERM;
5212 	}
5213 
5214 	if (pid < 0) {
5215 		OSBitAndAtomic(~((uint32_t)P_NOREMOTEHANG), &p->p_flag);
5216 	} else {
5217 		OSBitOrAtomic(P_NOREMOTEHANG, &p->p_flag);
5218 	}
5219 	proc_rele(p);
5220 
5221 	return 0;
5222 }
5223 
5224 static int
5225 sysctl_vfs_generic_conf SYSCTL_HANDLER_ARGS
5226 {
5227 	int *name, namelen;
5228 	struct vfstable *vfsp;
5229 	struct vfsconf vfsc = {};
5230 
5231 	(void)oidp;
5232 	name = arg1;
5233 	namelen = arg2;
5234 
5235 	if (namelen < 1) {
5236 		return EISDIR;
5237 	} else if (namelen > 1) {
5238 		return ENOTDIR;
5239 	}
5240 
5241 	mount_list_lock();
5242 	for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
5243 		if (vfsp->vfc_typenum == name[0]) {
5244 			break;
5245 		}
5246 	}
5247 
5248 	if (vfsp == NULL) {
5249 		mount_list_unlock();
5250 		return ENOTSUP;
5251 	}
5252 
5253 	vfsc.vfc_reserved1 = 0;
5254 	bcopy(vfsp->vfc_name, vfsc.vfc_name, sizeof(vfsc.vfc_name));
5255 	vfsc.vfc_typenum = vfsp->vfc_typenum;
5256 	vfsc.vfc_refcount = vfsp->vfc_refcount;
5257 	vfsc.vfc_flags = vfsp->vfc_flags;
5258 	vfsc.vfc_reserved2 = 0;
5259 	vfsc.vfc_reserved3 = 0;
5260 
5261 	mount_list_unlock();
5262 	return SYSCTL_OUT(req, &vfsc, sizeof(struct vfsconf));
5263 }
5264 
5265 /* the vfs.generic. branch. */
5266 SYSCTL_EXTENSIBLE_NODE(_vfs, VFS_GENERIC, generic,
5267     CTLFLAG_RW | CTLFLAG_LOCKED, NULL, "vfs generic hinge");
5268 /* retreive a list of mounted filesystem fsid_t */
5269 SYSCTL_PROC(_vfs_generic, OID_AUTO, vfsidlist,
5270     CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
5271     NULL, 0, sysctl_vfs_vfslist, "S,fsid", "List of mounted filesystem ids");
5272 /* perform operations on filesystem via fsid_t */
5273 SYSCTL_NODE(_vfs_generic, OID_AUTO, ctlbyfsid, CTLFLAG_RW | CTLFLAG_LOCKED,
5274     sysctl_vfs_ctlbyfsid, "ctlbyfsid");
5275 SYSCTL_PROC(_vfs_generic, OID_AUTO, noremotehang, CTLFLAG_RW | CTLFLAG_ANYBODY,
5276     NULL, 0, sysctl_vfs_noremotehang, "I", "noremotehang");
5277 SYSCTL_INT(_vfs_generic, VFS_MAXTYPENUM, maxtypenum,
5278     CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
5279     &maxvfstypenum, 0, "");
5280 SYSCTL_INT(_vfs_generic, OID_AUTO, sync_timeout, CTLFLAG_RW | CTLFLAG_LOCKED, &sync_timeout_seconds, 0, "");
5281 SYSCTL_NODE(_vfs_generic, VFS_CONF, conf,
5282     CTLFLAG_RD | CTLFLAG_LOCKED,
5283     sysctl_vfs_generic_conf, "");
5284 #if DEVELOPMENT || DEBUG
5285 SYSCTL_INT(_vfs_generic, OID_AUTO, print_busy_vnodes,
5286     CTLTYPE_INT | CTLFLAG_RW,
5287     &print_busy_vnodes, 0,
5288     "VFS log busy vnodes blocking unmount");
5289 #endif
5290 
5291 /* Indicate that the root file system unmounted cleanly */
5292 static int vfs_root_unmounted_cleanly = 0;
5293 SYSCTL_INT(_vfs_generic, OID_AUTO, root_unmounted_cleanly, CTLFLAG_RD, &vfs_root_unmounted_cleanly, 0, "Root filesystem was unmounted cleanly");
5294 
5295 void
vfs_set_root_unmounted_cleanly(void)5296 vfs_set_root_unmounted_cleanly(void)
5297 {
5298 	vfs_root_unmounted_cleanly = 1;
5299 }
5300 
5301 /*
5302  * Print vnode state.
5303  */
5304 void
vn_print_state(struct vnode * vp,const char * fmt,...)5305 vn_print_state(struct vnode *vp, const char *fmt, ...)
5306 {
5307 	va_list ap;
5308 	char perm_str[] = "(VM_KERNEL_ADDRPERM pointer)";
5309 	char fs_name[MFSNAMELEN];
5310 
5311 	va_start(ap, fmt);
5312 	vprintf(fmt, ap);
5313 	va_end(ap);
5314 	printf("vp 0x%0llx %s: ", (uint64_t)VM_KERNEL_ADDRPERM(vp), perm_str);
5315 	printf("tag %d, type %d\n", vp->v_tag, vp->v_type);
5316 	/* Counts .. */
5317 	printf("    iocount %d, usecount %d, kusecount %d references %d\n",
5318 	    vp->v_iocount, vp->v_usecount, vp->v_kusecount, vp->v_references);
5319 	printf("    writecount %d, numoutput %d\n", vp->v_writecount,
5320 	    vp->v_numoutput);
5321 	/* Flags */
5322 	printf("    flag 0x%x, lflag 0x%x, listflag 0x%x\n", vp->v_flag,
5323 	    vp->v_lflag, vp->v_listflag);
5324 
5325 	if (vp->v_mount == NULL || vp->v_mount == dead_mountp) {
5326 		strlcpy(fs_name, "deadfs", MFSNAMELEN);
5327 	} else {
5328 		vfs_name(vp->v_mount, fs_name);
5329 	}
5330 
5331 	printf("    v_data 0x%0llx %s\n",
5332 	    (vp->v_data ? (uint64_t)VM_KERNEL_ADDRPERM(vp->v_data) : 0),
5333 	    perm_str);
5334 	printf("    v_mount 0x%0llx %s vfs_name %s\n",
5335 	    (vp->v_mount ? (uint64_t)VM_KERNEL_ADDRPERM(vp->v_mount) : 0),
5336 	    perm_str, fs_name);
5337 }
5338 
5339 long num_reusedvnodes = 0;
5340 
5341 
5342 static vnode_t
process_vp(vnode_t vp,int want_vp,bool can_defer,int * deferred)5343 process_vp(vnode_t vp, int want_vp, bool can_defer, int *deferred)
5344 {
5345 	unsigned int  vpid;
5346 
5347 	*deferred = 0;
5348 
5349 	vpid = vp->v_id;
5350 
5351 	vnode_list_remove_locked(vp);
5352 
5353 	vnode_hold(vp);
5354 	vnode_list_unlock();
5355 
5356 	vnode_lock_spin(vp);
5357 
5358 	/*
5359 	 * We could wait for the vnode_lock after removing the vp from the freelist
5360 	 * and the vid is bumped only at the very end of reclaim. So it is  possible
5361 	 * that we are looking at a vnode that is being terminated. If so skip it.
5362 	 */
5363 	if ((vpid != vp->v_id) || (vp->v_usecount != 0) || (vp->v_iocount != 0) ||
5364 	    VONLIST(vp) || (vp->v_lflag & VL_TERMINATE)) {
5365 		/*
5366 		 * we lost the race between dropping the list lock
5367 		 * and picking up the vnode_lock... someone else
5368 		 * used this vnode and it is now in a new state
5369 		 */
5370 		vnode_drop_and_unlock(vp);
5371 
5372 		return NULLVP;
5373 	}
5374 	if ((vp->v_lflag & (VL_NEEDINACTIVE | VL_MARKTERM)) == VL_NEEDINACTIVE) {
5375 		/*
5376 		 * we did a vnode_rele_ext that asked for
5377 		 * us not to reenter the filesystem during
5378 		 * the release even though VL_NEEDINACTIVE was
5379 		 * set... we'll do it here by doing a
5380 		 * vnode_get/vnode_put
5381 		 *
5382 		 * pick up an iocount so that we can call
5383 		 * vnode_put and drive the VNOP_INACTIVE...
5384 		 * vnode_put will either leave us off
5385 		 * the freelist if a new ref comes in,
5386 		 * or put us back on the end of the freelist
5387 		 * or recycle us if we were marked for termination...
5388 		 * so we'll just go grab a new candidate
5389 		 */
5390 		vp->v_iocount++;
5391 #ifdef CONFIG_IOCOUNT_TRACE
5392 		record_vp(vp, 1);
5393 #endif
5394 		vnode_put_locked(vp);
5395 		vnode_drop_and_unlock(vp);
5396 
5397 		return NULLVP;
5398 	}
5399 	/*
5400 	 * Checks for anyone racing us for recycle
5401 	 */
5402 	if (vp->v_type != VBAD) {
5403 		if ((want_vp || can_defer) && (vnode_on_reliable_media(vp) == FALSE || (vp->v_flag & VISDIRTY))) {
5404 			vnode_async_list_add(vp);
5405 			vnode_drop_and_unlock(vp);
5406 
5407 			*deferred = 1;
5408 
5409 			return NULLVP;
5410 		}
5411 		if (vp->v_lflag & VL_DEAD) {
5412 			panic("new_vnode(%p): the vnode is VL_DEAD but not VBAD", vp);
5413 		}
5414 
5415 		vnode_lock_convert(vp);
5416 		(void)vnode_reclaim_internal(vp, 1, want_vp, 0);
5417 
5418 		if (want_vp) {
5419 			if ((VONLIST(vp))) {
5420 				panic("new_vnode(%p): vp on list", vp);
5421 			}
5422 			if (vp->v_usecount || vp->v_iocount || vp->v_kusecount ||
5423 			    (vp->v_lflag & (VNAMED_UBC | VNAMED_MOUNT | VNAMED_FSHASH))) {
5424 				panic("new_vnode(%p): free vnode still referenced", vp);
5425 			}
5426 			if ((vp->v_mntvnodes.tqe_prev != 0) && (vp->v_mntvnodes.tqe_next != 0)) {
5427 				panic("new_vnode(%p): vnode seems to be on mount list", vp);
5428 			}
5429 			if (!LIST_EMPTY(&vp->v_nclinks) || !TAILQ_EMPTY(&vp->v_ncchildren)) {
5430 				panic("new_vnode(%p): vnode still hooked into the name cache", vp);
5431 			}
5432 		} else {
5433 			vnode_drop_and_unlock(vp);
5434 			vp = NULLVP;
5435 		}
5436 	}
5437 	return vp;
5438 }
5439 
5440 __attribute__((noreturn))
5441 static void
async_work_continue(void)5442 async_work_continue(void)
5443 {
5444 	struct async_work_lst *q;
5445 	int     deferred;
5446 	vnode_t vp;
5447 
5448 	q = &vnode_async_work_list;
5449 
5450 	for (;;) {
5451 		vnode_list_lock();
5452 
5453 		if (TAILQ_EMPTY(q)) {
5454 			assert_wait(q, (THREAD_UNINT));
5455 
5456 			vnode_list_unlock();
5457 
5458 			thread_block((thread_continue_t)async_work_continue);
5459 
5460 			continue;
5461 		}
5462 		async_work_handled++;
5463 
5464 		vp = TAILQ_FIRST(q);
5465 
5466 		vp = process_vp(vp, 0, false, &deferred);
5467 
5468 		if (vp != NULLVP) {
5469 			panic("found VBAD vp (%p) on async queue", vp);
5470 		}
5471 	}
5472 }
5473 
5474 #if CONFIG_JETSAM
5475 bool do_async_jetsam = false;
5476 #endif
5477 
5478 __attribute__((noreturn))
5479 static void
vn_laundry_continue(void)5480 vn_laundry_continue(void)
5481 {
5482 	struct freelst *free_q;
5483 	struct ragelst *rage_q;
5484 	vnode_t vp;
5485 	int deferred;
5486 	bool rage_q_empty;
5487 	bool free_q_empty;
5488 
5489 
5490 	free_q = &vnode_free_list;
5491 	rage_q = &vnode_rage_list;
5492 
5493 	for (;;) {
5494 		vnode_list_lock();
5495 
5496 #if CONFIG_JETSAM
5497 		if (do_async_jetsam) {
5498 			do_async_jetsam = false;
5499 			if (deadvnodes <= deadvnodes_low) {
5500 				vnode_list_unlock();
5501 
5502 				log(LOG_EMERG, "Initiating vnode jetsam : %d desired, %ld numvnodes, "
5503 				    "%ld free, %ld dead, %ld async, %d rage\n",
5504 				    desiredvnodes, numvnodes, freevnodes, deadvnodes, async_work_vnodes, ragevnodes);
5505 
5506 				memorystatus_kill_on_vnode_limit();
5507 
5508 				continue;
5509 			}
5510 		}
5511 #endif
5512 
5513 		if (!TAILQ_EMPTY(&vnode_async_work_list)) {
5514 			vp = TAILQ_FIRST(&vnode_async_work_list);
5515 			async_work_handled++;
5516 
5517 			vp = process_vp(vp, 0, false, &deferred);
5518 
5519 			if (vp != NULLVP) {
5520 				panic("found VBAD vp (%p) on async queue", vp);
5521 			}
5522 			continue;
5523 		}
5524 
5525 		free_q_empty = TAILQ_EMPTY(free_q);
5526 		rage_q_empty = TAILQ_EMPTY(rage_q);
5527 
5528 		if (!rage_q_empty && !free_q_empty) {
5529 			struct timeval current_tv;
5530 
5531 			microuptime(&current_tv);
5532 			if (ragevnodes < rage_limit &&
5533 			    ((current_tv.tv_sec - rage_tv.tv_sec) < RAGE_TIME_LIMIT)) {
5534 				rage_q_empty = true;
5535 			}
5536 		}
5537 
5538 		if (numvnodes < numvnodes_min || (rage_q_empty && free_q_empty) ||
5539 		    (reusablevnodes <= reusablevnodes_max && deadvnodes >= deadvnodes_high)) {
5540 			assert_wait(free_q, (THREAD_UNINT));
5541 
5542 			vnode_list_unlock();
5543 
5544 			thread_block((thread_continue_t)vn_laundry_continue);
5545 
5546 			continue;
5547 		}
5548 
5549 		if (!rage_q_empty) {
5550 			vp = TAILQ_FIRST(rage_q);
5551 		} else {
5552 			vp = TAILQ_FIRST(free_q);
5553 		}
5554 
5555 		vp = process_vp(vp, 0, false, &deferred);
5556 
5557 		if (vp != NULLVP) {
5558 			/* If process_vp returns a vnode, it is locked and has a holdcount */
5559 			vnode_drop_and_unlock(vp);
5560 			vp = NULLVP;
5561 		}
5562 	}
5563 }
5564 
5565 static inline void
wakeup_laundry_thread()5566 wakeup_laundry_thread()
5567 {
5568 	if (deadvnodes_noreuse || (numvnodes >= numvnodes_min && deadvnodes < deadvnodes_low &&
5569 	    (reusablevnodes > reusablevnodes_max || numvnodes >= desiredvnodes))) {
5570 		wakeup(&vnode_free_list);
5571 	}
5572 }
5573 
5574 /*
5575  * This must be called under vnode_list_lock() to prevent race when accessing
5576  * various vnode stats.
5577  */
5578 static void
send_freeable_vnodes_telemetry(void)5579 send_freeable_vnodes_telemetry(void)
5580 {
5581 	bool send_event = false;
5582 
5583 	/*
5584 	 * Log an event when the 'numvnodes' is above the freeable vnodes threshold
5585 	 * or when it falls back within the threshold.
5586 	 * When the 'numvnodes' is above the threshold, log an event when it has
5587 	 * been incrementally growing by 25%.
5588 	 */
5589 	if ((numvnodes > desiredvnodes) && (freevnodes + deadvnodes) == 0) {
5590 		long last_numvnodes = freeable_vnodes_telemetry.numvnodes;
5591 
5592 		if (numvnodes > (last_numvnodes + ((last_numvnodes * 25) / 100)) ||
5593 		    numvnodes >= numvnodes_max) {
5594 			send_event = true;
5595 		}
5596 		freeablevnodes_threshold_crossed = true;
5597 	} else if (freeablevnodes_threshold_crossed &&
5598 	    (freevnodes + deadvnodes) > busyvnodes) {
5599 		freeablevnodes_threshold_crossed = false;
5600 		send_event = true;
5601 	}
5602 
5603 	if (__improbable(send_event)) {
5604 		ca_event_t event = CA_EVENT_ALLOCATE_FLAGS(freeable_vnodes, Z_NOWAIT);
5605 
5606 		if (event) {
5607 			/*
5608 			 * Update the stats except the 'numvnodes_max' and 'desiredvnodes'
5609 			 * as they are immutable after init.
5610 			 */
5611 			freeable_vnodes_telemetry.numvnodes_min = numvnodes_min;
5612 			freeable_vnodes_telemetry.numvnodes = numvnodes;
5613 			freeable_vnodes_telemetry.freevnodes = freevnodes;
5614 			freeable_vnodes_telemetry.deadvnodes = deadvnodes;
5615 			freeable_vnodes_telemetry.freeablevnodes = freeablevnodes;
5616 			freeable_vnodes_telemetry.busyvnodes = busyvnodes;
5617 			freeable_vnodes_telemetry.threshold_crossed =
5618 			    freeablevnodes_threshold_crossed;
5619 
5620 			memcpy(event->data, &freeable_vnodes_telemetry,
5621 			    sizeof(CA_EVENT_TYPE(freeable_vnodes)));
5622 
5623 			if (!freeablevnodes_threshold_crossed) {
5624 				freeable_vnodes_telemetry.numvnodes = 0;
5625 			}
5626 			CA_EVENT_SEND(event);
5627 		}
5628 	}
5629 }
5630 
5631 static int
new_vnode(vnode_t * vpp,bool can_free)5632 new_vnode(vnode_t *vpp, bool can_free)
5633 {
5634 	long force_alloc_min;
5635 	vnode_t vp;
5636 #if CONFIG_JETSAM
5637 	uint32_t retries = 0, max_retries = 2;                  /* retry incase of tablefull */
5638 #else
5639 	uint32_t retries = 0, max_retries = 100;                /* retry incase of tablefull */
5640 #endif
5641 	int force_alloc = 0, walk_count = 0;
5642 	boolean_t need_reliable_vp = FALSE;
5643 	int deferred;
5644 	struct timeval initial_tv;
5645 	struct timeval current_tv;
5646 	proc_t  curproc = current_proc();
5647 	bool force_alloc_freeable = false;
5648 
5649 	if (vn_dealloc_level == DEALLOC_VNODE_NONE) {
5650 		can_free = false;
5651 	}
5652 
5653 	initial_tv.tv_sec = 0;
5654 retry:
5655 	vp = NULLVP;
5656 
5657 	vnode_list_lock();
5658 	newvnode++;
5659 
5660 	if (need_reliable_vp == TRUE) {
5661 		async_work_timed_out++;
5662 	}
5663 
5664 	/*
5665 	 * The vnode list lock was dropped after force_alloc_freeable was set,
5666 	 * reevaluate.
5667 	 */
5668 	force_alloc_min = MAX(desiredvnodes, numvnodes_min);
5669 	if (force_alloc_freeable &&
5670 	    (numvnodes < force_alloc_min || numvnodes >= numvnodes_max)) {
5671 		force_alloc_freeable = false;
5672 	}
5673 
5674 #if CONFIG_JETSAM
5675 	if ((numvnodes_max > desiredvnodes) && numvnodes > (numvnodes_max - 100)
5676 #if (DEVELOPMENT || DEBUG)
5677 	    && !bootarg_no_vnode_jetsam
5678 #endif
5679 	    ) {
5680 		do_async_jetsam = true;
5681 		wakeup(&vnode_free_list);
5682 	}
5683 #endif /* CONFIG_JETSAM */
5684 
5685 	if (((numvnodes - deadvnodes + deadvnodes_noreuse) < desiredvnodes) ||
5686 	    force_alloc || force_alloc_freeable) {
5687 		struct timespec ts;
5688 		uint32_t vflag = 0;
5689 
5690 		/*
5691 		 * Can always reuse a dead one except if it is in the process of
5692 		 * being freed or the FS cannot handle freeable vnodes.
5693 		 */
5694 		if (!TAILQ_EMPTY(&vnode_dead_list)) {
5695 			/* Select an appropriate deadvnode */
5696 			if (numvnodes <= numvnodes_min || !can_free) {
5697 				/* all vnodes upto numvnodes_min are not freeable */
5698 				vp = TAILQ_FIRST(&vnode_dead_list);
5699 				if (numvnodes > numvnodes_min &&
5700 				    (vp->v_flag & VCANDEALLOC)) {
5701 					/*
5702 					 * Freeable vnodes are added to the
5703 					 * back of the queue, so if the first
5704 					 * from the front is freeable, then
5705 					 * there are none on the dead list.
5706 					 */
5707 					vp = NULLVP;
5708 				}
5709 			} else {
5710 				/*
5711 				 * Filesystems which opt in to freeable vnodes
5712 				 * can get either one.
5713 				 */
5714 				TAILQ_FOREACH_REVERSE(vp, &vnode_dead_list,
5715 				    deadlst, v_freelist) {
5716 					if (!(vp->v_listflag & VLIST_NO_REUSE)) {
5717 						break;
5718 					}
5719 				}
5720 			}
5721 
5722 			if (vp) {
5723 				force_alloc_freeable = false;
5724 				goto steal_this_vp;
5725 			}
5726 		}
5727 
5728 		/*
5729 		 * no dead vnodes available... if we're under
5730 		 * the limit, we'll create a new vnode
5731 		 */
5732 		numvnodes++;
5733 		if (force_alloc) {
5734 			numvnodes_min++;
5735 		} else if (can_free && (numvnodes > numvnodes_min)) {
5736 			allocedvnodes++;
5737 			freeablevnodes++;
5738 			vflag = VCANDEALLOC;
5739 
5740 			send_freeable_vnodes_telemetry();
5741 		}
5742 		vnode_list_unlock();
5743 
5744 		if (nc_smr_enabled) {
5745 			vp = zalloc_smr(vnode_zone, Z_WAITOK_ZERO_NOFAIL);
5746 		} else {
5747 			vp = zalloc_flags(vnode_zone, Z_WAITOK_ZERO_NOFAIL);
5748 		}
5749 
5750 		VLISTNONE(vp);          /* avoid double queue removal */
5751 		lck_mtx_init(&vp->v_lock, &vnode_lck_grp, &vnode_lck_attr);
5752 
5753 		TAILQ_INIT(&vp->v_ncchildren);
5754 
5755 		klist_init(&vp->v_knotes);
5756 		nanouptime(&ts);
5757 		vp->v_id = (uint32_t)ts.tv_nsec;
5758 		vp->v_flag = VSTANDARD | vflag;
5759 		if (force_alloc_freeable) {
5760 			/* This vnode should be recycled and freed immediately */
5761 			vp->v_lflag = VL_MARKTERM;
5762 			vp->v_listflag = VLIST_NO_REUSE;
5763 		}
5764 
5765 		if (vflag & VCANDEALLOC) {
5766 			os_atomic_inc(&busyvnodes, relaxed);
5767 		}
5768 
5769 #if CONFIG_MACF
5770 		if (mac_vnode_label_init_needed(vp)) {
5771 			mac_vnode_label_init(vp);
5772 		}
5773 #endif /* MAC */
5774 
5775 #if CONFIG_IOCOUNT_TRACE
5776 		if (__improbable(bootarg_vnode_iocount_trace)) {
5777 			vp->v_iocount_trace = (vnode_iocount_trace_t)zalloc_permanent(
5778 				IOCOUNT_TRACE_MAX_TYPES * sizeof(struct vnode_iocount_trace),
5779 				ZALIGN(struct vnode_iocount_trace));
5780 		}
5781 #endif /* CONFIG_IOCOUNT_TRACE */
5782 
5783 #if CONFIG_FILE_LEASES
5784 		LIST_INIT(&vp->v_leases);
5785 #endif
5786 
5787 		vp->v_iocount = 1;
5788 
5789 		goto done;
5790 	}
5791 
5792 	microuptime(&current_tv);
5793 
5794 #define MAX_WALK_COUNT 1000
5795 
5796 	if (!TAILQ_EMPTY(&vnode_rage_list) &&
5797 	    (ragevnodes >= rage_limit ||
5798 	    (current_tv.tv_sec - rage_tv.tv_sec) >= RAGE_TIME_LIMIT)) {
5799 		TAILQ_FOREACH(vp, &vnode_rage_list, v_freelist) {
5800 			if (!(vp->v_listflag & VLIST_RAGE)) {
5801 				panic("new_vnode: vp (%p) on RAGE list not marked VLIST_RAGE", vp);
5802 			}
5803 
5804 			// if we're a dependency-capable process, skip vnodes that can
5805 			// cause recycling deadlocks. (i.e. this process is diskimages
5806 			// helper and the vnode is in a disk image).  Querying the
5807 			// mnt_kern_flag for the mount's virtual device status
5808 			// is safer than checking the mnt_dependent_process, which
5809 			// may not be updated if there are multiple devnode layers
5810 			// in between the disk image and the final consumer.
5811 
5812 			if (((curproc->p_flag & P_DEPENDENCY_CAPABLE) == 0 || vp->v_mount == NULL ||
5813 			    (vp->v_mount->mnt_kern_flag & MNTK_VIRTUALDEV) == 0) &&
5814 			    !(vp->v_listflag & VLIST_NO_REUSE) &&
5815 			    (can_free || !(vp->v_flag & VCANDEALLOC))) {
5816 				/*
5817 				 * if need_reliable_vp == TRUE, then we've already sent one or more
5818 				 * non-reliable vnodes to the async thread for processing and timed
5819 				 * out waiting for a dead vnode to show up.  Use the MAX_WALK_COUNT
5820 				 * mechanism to first scan for a reliable vnode before forcing
5821 				 * a new vnode to be created
5822 				 */
5823 				if (need_reliable_vp == FALSE || vnode_on_reliable_media(vp) == TRUE) {
5824 					break;
5825 				}
5826 			}
5827 
5828 			// don't iterate more than MAX_WALK_COUNT vnodes to
5829 			// avoid keeping the vnode list lock held for too long.
5830 
5831 			if (walk_count++ > MAX_WALK_COUNT) {
5832 				vp = NULL;
5833 				break;
5834 			}
5835 		}
5836 	}
5837 
5838 	if (vp == NULL && !TAILQ_EMPTY(&vnode_free_list)) {
5839 		/*
5840 		 * Pick the first vp for possible reuse
5841 		 */
5842 		walk_count = 0;
5843 		TAILQ_FOREACH(vp, &vnode_free_list, v_freelist) {
5844 			// if we're a dependency-capable process, skip vnodes that can
5845 			// cause recycling deadlocks. (i.e. this process is diskimages
5846 			// helper and the vnode is in a disk image).  Querying the
5847 			// mnt_kern_flag for the mount's virtual device status
5848 			// is safer than checking the mnt_dependent_process, which
5849 			// may not be updated if there are multiple devnode layers
5850 			// in between the disk image and the final consumer.
5851 
5852 			if (((curproc->p_flag & P_DEPENDENCY_CAPABLE) == 0 || vp->v_mount == NULL ||
5853 			    (vp->v_mount->mnt_kern_flag & MNTK_VIRTUALDEV) == 0) &&
5854 			    !(vp->v_listflag & VLIST_NO_REUSE) &&
5855 			    (can_free || !(vp->v_flag & VCANDEALLOC))) {
5856 				/*
5857 				 * if need_reliable_vp == TRUE, then we've already sent one or more
5858 				 * non-reliable vnodes to the async thread for processing and timed
5859 				 * out waiting for a dead vnode to show up.  Use the MAX_WALK_COUNT
5860 				 * mechanism to first scan for a reliable vnode before forcing
5861 				 * a new vnode to be created
5862 				 */
5863 				if (need_reliable_vp == FALSE || vnode_on_reliable_media(vp) == TRUE) {
5864 					break;
5865 				}
5866 			}
5867 
5868 			// don't iterate more than MAX_WALK_COUNT vnodes to
5869 			// avoid keeping the vnode list lock held for too long.
5870 
5871 			if (walk_count++ > MAX_WALK_COUNT) {
5872 				vp = NULL;
5873 				break;
5874 			}
5875 		}
5876 	}
5877 
5878 	//
5879 	// if we don't have a vnode and the walk_count is >= MAX_WALK_COUNT
5880 	// then we're trying to create a vnode on behalf of a
5881 	// process like diskimages-helper that has file systems
5882 	// mounted on top of itself (and thus we can't reclaim
5883 	// vnodes in the file systems on top of us).  if we can't
5884 	// find a vnode to reclaim then we'll just have to force
5885 	// the allocation.
5886 	//
5887 	if (vp == NULL && walk_count >= MAX_WALK_COUNT) {
5888 		force_alloc = 1;
5889 		vnode_list_unlock();
5890 		goto retry;
5891 	}
5892 
5893 	if (vp == NULL) {
5894 		if (can_free && (vn_dealloc_level > DEALLOC_VNODE_NONE) &&
5895 		    (numvnodes >= force_alloc_min) && (numvnodes < numvnodes_max)) {
5896 			force_alloc_freeable = true;
5897 			vnode_list_unlock();
5898 			goto retry;
5899 		}
5900 		vnode_list_unlock();
5901 
5902 		/*
5903 		 * we've reached the system imposed maximum number of vnodes
5904 		 * but there isn't a single one available
5905 		 * wait a bit and then retry... if we can't get a vnode
5906 		 * after our target number of retries, than log a complaint
5907 		 */
5908 		if (++retries <= max_retries) {
5909 			delay_for_interval(1, 1000 * 1000);
5910 			goto retry;
5911 		}
5912 
5913 		tablefull("vnode");
5914 		log(LOG_EMERG, "%d desired, %ld numvnodes, "
5915 		    "%ld free, %ld dead, %ld async, %d rage\n",
5916 		    desiredvnodes, numvnodes, freevnodes, deadvnodes, async_work_vnodes, ragevnodes);
5917 
5918 #if CONFIG_JETSAM
5919 		/*
5920 		 * Running out of vnodes tends to make a system unusable. Start killing
5921 		 * processes that jetsam knows are killable.
5922 		 */
5923 		if (memorystatus_kill_on_vnode_limit() == FALSE
5924 #if DEVELOPMENT || DEBUG
5925 		    || bootarg_no_vnode_jetsam
5926 #endif
5927 		    ) {
5928 			/*
5929 			 * If jetsam can't find any more processes to kill and there
5930 			 * still aren't any free vnodes, panic. Hopefully we'll get a
5931 			 * panic log to tell us why we ran out.
5932 			 */
5933 			panic("vnode table is full");
5934 		}
5935 
5936 		/*
5937 		 * Now that we've killed someone, wait a bit and continue looking
5938 		 */
5939 		delay_for_interval(3, 1000 * 1000);
5940 		retries = 0;
5941 		goto retry;
5942 #endif
5943 
5944 		*vpp = NULL;
5945 		return ENFILE;
5946 	}
5947 	newvnode_nodead++;
5948 steal_this_vp:
5949 	if ((vp = process_vp(vp, 1, true, &deferred)) == NULLVP) {
5950 		if (deferred) {
5951 			int     elapsed_msecs;
5952 			struct timeval elapsed_tv;
5953 
5954 			if (initial_tv.tv_sec == 0) {
5955 				microuptime(&initial_tv);
5956 			}
5957 
5958 			vnode_list_lock();
5959 
5960 			dead_vnode_waited++;
5961 			dead_vnode_wanted++;
5962 
5963 			/*
5964 			 * note that we're only going to explicitly wait 10ms
5965 			 * for a dead vnode to become available, since even if one
5966 			 * isn't available, a reliable vnode might now be available
5967 			 * at the head of the VRAGE or free lists... if so, we
5968 			 * can satisfy the new_vnode request with less latency then waiting
5969 			 * for the full 100ms duration we're ultimately willing to tolerate
5970 			 */
5971 			assert_wait_timeout((caddr_t)&dead_vnode_wanted, (THREAD_INTERRUPTIBLE), 10000, NSEC_PER_USEC);
5972 
5973 			vnode_list_unlock();
5974 
5975 			thread_block(THREAD_CONTINUE_NULL);
5976 
5977 			microuptime(&elapsed_tv);
5978 
5979 			timevalsub(&elapsed_tv, &initial_tv);
5980 			elapsed_msecs = (int)(elapsed_tv.tv_sec * 1000 + elapsed_tv.tv_usec / 1000);
5981 
5982 			if (elapsed_msecs >= 100) {
5983 				/*
5984 				 * we've waited long enough... 100ms is
5985 				 * somewhat arbitrary for this case, but the
5986 				 * normal worst case latency used for UI
5987 				 * interaction is 100ms, so I've chosen to
5988 				 * go with that.
5989 				 *
5990 				 * setting need_reliable_vp to TRUE
5991 				 * forces us to find a reliable vnode
5992 				 * that we can process synchronously, or
5993 				 * to create a new one if the scan for
5994 				 * a reliable one hits the scan limit
5995 				 */
5996 				need_reliable_vp = TRUE;
5997 			}
5998 		}
5999 		goto retry;
6000 	}
6001 	OSAddAtomicLong(1, &num_reusedvnodes);
6002 
6003 
6004 #if CONFIG_MACF
6005 	/*
6006 	 * We should never see VL_LABELWAIT or VL_LABEL here.
6007 	 * as those operations hold a reference.
6008 	 */
6009 	assert((vp->v_lflag & VL_LABELWAIT) != VL_LABELWAIT);
6010 	assert((vp->v_lflag & VL_LABEL) != VL_LABEL);
6011 	if (vp->v_lflag & VL_LABELED || mac_vnode_label(vp) != NULL) {
6012 		vnode_lock_convert(vp);
6013 		mac_vnode_label_recycle(vp);
6014 	} else if (mac_vnode_label_init_needed(vp)) {
6015 		vnode_lock_convert(vp);
6016 		mac_vnode_label_init(vp);
6017 	}
6018 
6019 #endif /* MAC */
6020 
6021 	vp->v_iocount = 1;
6022 	vp->v_lflag = 0;
6023 	vp->v_writecount = 0;
6024 	vp->v_references = 0;
6025 	vp->v_iterblkflags = 0;
6026 	if (can_free && (vp->v_flag & VCANDEALLOC)) {
6027 		vp->v_flag = VSTANDARD | VCANDEALLOC;
6028 	} else {
6029 		vp->v_flag = VSTANDARD;
6030 	}
6031 
6032 	/* vbad vnodes can point to dead_mountp */
6033 	vp->v_mount = NULL;
6034 	vp->v_defer_reclaimlist = (vnode_t)0;
6035 
6036 	/* process_vp returns a locked vnode with a holdcount */
6037 	vnode_drop_and_unlock(vp);
6038 
6039 done:
6040 	*vpp = vp;
6041 
6042 	return 0;
6043 }
6044 
6045 void
vnode_lock(vnode_t vp)6046 vnode_lock(vnode_t vp)
6047 {
6048 	lck_mtx_lock(&vp->v_lock);
6049 }
6050 
6051 void
vnode_lock_spin(vnode_t vp)6052 vnode_lock_spin(vnode_t vp)
6053 {
6054 	lck_mtx_lock_spin(&vp->v_lock);
6055 }
6056 
6057 void
vnode_unlock(vnode_t vp)6058 vnode_unlock(vnode_t vp)
6059 {
6060 	lck_mtx_unlock(&vp->v_lock);
6061 }
6062 
6063 void
vnode_hold(vnode_t vp)6064 vnode_hold(vnode_t vp)
6065 {
6066 	int32_t old_holdcount = os_atomic_inc_orig(&vp->v_holdcount, relaxed);
6067 
6068 	if (old_holdcount == INT32_MAX) {
6069 		/*
6070 		 * Because we allow atomic ops on the holdcount it is
6071 		 * possible that when the vnode is examined, its holdcount
6072 		 * is different than what will be printed in this
6073 		 * panic message.
6074 		 */
6075 		panic("%s: vp %p holdcount overflow from : %d v_tag = %d, v_type = %d, v_flag = %x.",
6076 		    __FUNCTION__, vp, old_holdcount, vp->v_tag, vp->v_type, vp->v_flag);
6077 	}
6078 }
6079 
6080 #define VNODE_HOLD_NO_SMR    (1<<29) /* Disable vnode_hold_smr */
6081 
6082 /*
6083  * To be used when smr is the only protection (cache_lookup and cache_lookup_path)
6084  */
6085 bool
vnode_hold_smr(vnode_t vp)6086 vnode_hold_smr(vnode_t vp)
6087 {
6088 	int32_t holdcount;
6089 
6090 	/*
6091 	 * For "high traffic" vnodes like rootvnode, the atomic
6092 	 * cmpexcg loop below can turn into a infinite loop, no need
6093 	 * to do it for vnodes that won't be dealloc'ed
6094 	 */
6095 	if (!(os_atomic_load(&vp->v_flag, relaxed) & VCANDEALLOC)) {
6096 		vnode_hold(vp);
6097 		return true;
6098 	}
6099 
6100 	for (;;) {
6101 		holdcount = os_atomic_load(&vp->v_holdcount, relaxed);
6102 
6103 		if (holdcount & VNODE_HOLD_NO_SMR) {
6104 			return false;
6105 		}
6106 
6107 		if ((os_atomic_cmpxchg(&vp->v_holdcount, holdcount, holdcount + 1, relaxed) != 0)) {
6108 			return true;
6109 		}
6110 	}
6111 }
6112 
6113 /*
6114  * free callback from smr enabled zones
6115  */
6116 static void
vnode_smr_free(void * _vp,__unused size_t _size)6117 vnode_smr_free(void *_vp, __unused size_t _size)
6118 {
6119 	vnode_t vp = _vp;
6120 
6121 	bzero(vp, sizeof(*vp));
6122 }
6123 
6124 static vnode_t
vnode_drop_internal(vnode_t vp,bool locked)6125 vnode_drop_internal(vnode_t vp, bool locked)
6126 {
6127 	int32_t old_holdcount = os_atomic_dec_orig(&vp->v_holdcount, relaxed);
6128 
6129 	if (old_holdcount < 1) {
6130 		if (locked) {
6131 			vnode_unlock(vp);
6132 		}
6133 
6134 		/*
6135 		 * Because we allow atomic ops on the holdcount it is possible
6136 		 * that when the vnode is examined, its holdcount is different
6137 		 * than what will be printed in this panic message.
6138 		 */
6139 		panic("%s : vp %p holdcount -ve: %d.  v_tag = %d, v_type = %d, v_flag = %x.",
6140 		    __FUNCTION__, vp, old_holdcount - 1, vp->v_tag, vp->v_type, vp->v_flag);
6141 	}
6142 
6143 	if (vn_dealloc_level == DEALLOC_VNODE_NONE || old_holdcount > 1 ||
6144 	    !(vp->v_flag & VCANDEALLOC) || !(vp->v_lflag & VL_DEAD)) {
6145 		if (locked) {
6146 			vnode_unlock(vp);
6147 		}
6148 		return vp;
6149 	}
6150 
6151 	if (!locked) {
6152 		vnode_lock(vp);
6153 	}
6154 
6155 	if ((os_atomic_load(&vp->v_holdcount, relaxed) != 0) || vp->v_iocount ||
6156 	    vp->v_usecount || !(vp->v_flag & VCANDEALLOC) || !(vp->v_lflag & VL_DEAD)) {
6157 		vnode_unlock(vp);
6158 		return vp;
6159 	}
6160 
6161 	vnode_list_lock();
6162 
6163 	/*
6164 	 * the v_listflag field is protected by the vnode_list_lock
6165 	 */
6166 	if (VONLIST(vp) && (vp->v_listflag & VLIST_DEAD) &&
6167 	    (numvnodes > desiredvnodes || (vp->v_listflag & VLIST_NO_REUSE) ||
6168 	    vn_dealloc_level != DEALLOC_VNODE_ALL || deadvnodes >= deadvnodes_high) &&
6169 	    (os_atomic_cmpxchg(&vp->v_holdcount, 0, VNODE_HOLD_NO_SMR, relaxed) != 0)) {
6170 		VREMDEAD("vnode_list_remove", vp);
6171 		numvnodes--;
6172 		freeablevnodes--;
6173 		deallocedvnodes++;
6174 		vp->v_listflag = 0;
6175 
6176 		send_freeable_vnodes_telemetry();
6177 		vnode_list_unlock();
6178 
6179 #if CONFIG_MACF
6180 		struct label *tmpl = mac_vnode_label(vp);
6181 		vp->v_label = NULL;
6182 #endif /* CONFIG_MACF */
6183 
6184 		vnode_unlock(vp);
6185 
6186 #if CONFIG_MACF
6187 		if (tmpl) {
6188 			mac_vnode_label_free(tmpl);
6189 		}
6190 #endif /* CONFIG_MACF */
6191 
6192 		if (nc_smr_enabled) {
6193 			zfree_smr(vnode_zone, vp);
6194 		} else {
6195 			zfree(vnode_zone, vp);
6196 		}
6197 
6198 		vp = NULLVP;
6199 	} else {
6200 		vnode_list_unlock();
6201 		vnode_unlock(vp);
6202 	}
6203 
6204 	return vp;
6205 }
6206 
6207 vnode_t
vnode_drop_and_unlock(vnode_t vp)6208 vnode_drop_and_unlock(vnode_t vp)
6209 {
6210 	return vnode_drop_internal(vp, true);
6211 }
6212 
6213 vnode_t
vnode_drop(vnode_t vp)6214 vnode_drop(vnode_t vp)
6215 {
6216 	return vnode_drop_internal(vp, false);
6217 }
6218 
6219 SYSCTL_NODE(_vfs, OID_AUTO, vnstats, CTLFLAG_RD | CTLFLAG_LOCKED, NULL, "vfs vnode stats");
6220 
6221 SYSCTL_COMPAT_INT(_vfs_vnstats, OID_AUTO, vn_dealloc_level,
6222     CTLFLAG_RD | CTLFLAG_LOCKED,
6223     &vn_dealloc_level, 0, "");
6224 SYSCTL_COMPAT_INT(_vfs_vnstats, OID_AUTO, desired_vnodes,
6225     CTLFLAG_RD | CTLFLAG_LOCKED,
6226     &desiredvnodes, 0, "");
6227 SYSCTL_LONG(_vfs_vnstats, OID_AUTO, num_vnodes,
6228     CTLFLAG_RD | CTLFLAG_LOCKED,
6229     &numvnodes, "");
6230 SYSCTL_COMPAT_INT(_vfs_vnstats, OID_AUTO, num_vnodes_min,
6231     CTLFLAG_RD | CTLFLAG_LOCKED,
6232     &numvnodes_min, 0, "");
6233 SYSCTL_COMPAT_INT(_vfs_vnstats, OID_AUTO, num_vnodes_max,
6234     CTLFLAG_RD | CTLFLAG_LOCKED,
6235     &numvnodes_max, 0, "");
6236 SYSCTL_COMPAT_INT(_vfs_vnstats, OID_AUTO, num_deallocable_vnodes,
6237     CTLFLAG_RD | CTLFLAG_LOCKED,
6238     &freeablevnodes, 0, "");
6239 SYSCTL_LONG(_vfs_vnstats, OID_AUTO, num_deallocable_busy_vnodes,
6240     CTLFLAG_RD | CTLFLAG_LOCKED,
6241     &busyvnodes, "");
6242 SYSCTL_LONG(_vfs_vnstats, OID_AUTO, num_dead_vnodes,
6243     CTLFLAG_RD | CTLFLAG_LOCKED,
6244     &deadvnodes, "");
6245 SYSCTL_LONG(_vfs_vnstats, OID_AUTO, num_dead_vnodes_to_dealloc,
6246     CTLFLAG_RD | CTLFLAG_LOCKED,
6247     &deadvnodes_noreuse, "");
6248 SYSCTL_LONG(_vfs_vnstats, OID_AUTO, num_async_work_vnodes,
6249     CTLFLAG_RD | CTLFLAG_LOCKED,
6250     &async_work_vnodes, "");
6251 SYSCTL_COMPAT_INT(_vfs_vnstats, OID_AUTO, num_rapid_aging_vnodes,
6252     CTLFLAG_RD | CTLFLAG_LOCKED,
6253     &ragevnodes, 0, "");
6254 SYSCTL_LONG(_vfs_vnstats, OID_AUTO, num_free_vnodes,
6255     CTLFLAG_RD | CTLFLAG_LOCKED,
6256     &freevnodes, "");
6257 SYSCTL_LONG(_vfs_vnstats, OID_AUTO, num_recycledvnodes,
6258     CTLFLAG_RD | CTLFLAG_LOCKED,
6259     &num_recycledvnodes, "");
6260 SYSCTL_QUAD(_vfs_vnstats, OID_AUTO, num_allocedvnodes,
6261     CTLFLAG_RD | CTLFLAG_LOCKED,
6262     &allocedvnodes, "");
6263 SYSCTL_QUAD(_vfs_vnstats, OID_AUTO, num_deallocedvnodes,
6264     CTLFLAG_RD | CTLFLAG_LOCKED,
6265     &deallocedvnodes, "");
6266 SYSCTL_QUAD(_vfs_vnstats, OID_AUTO, num_newvnode_calls,
6267     CTLFLAG_RD | CTLFLAG_LOCKED,
6268     &newvnode, "");
6269 SYSCTL_QUAD(_vfs_vnstats, OID_AUTO, num_newvnode_calls_nodead,
6270     CTLFLAG_RD | CTLFLAG_LOCKED,
6271     &newvnode_nodead, "");
6272 
6273 int
vnode_get(struct vnode * vp)6274 vnode_get(struct vnode *vp)
6275 {
6276 	int retval;
6277 
6278 	vnode_lock_spin(vp);
6279 	retval = vnode_get_locked(vp);
6280 	vnode_unlock(vp);
6281 
6282 	return retval;
6283 }
6284 
6285 int
vnode_get_locked(struct vnode * vp)6286 vnode_get_locked(struct vnode *vp)
6287 {
6288 #if DIAGNOSTIC
6289 	lck_mtx_assert(&vp->v_lock, LCK_MTX_ASSERT_OWNED);
6290 #endif
6291 	if ((vp->v_iocount == 0) && (vp->v_lflag & (VL_TERMINATE | VL_DEAD))) {
6292 		return ENOENT;
6293 	}
6294 
6295 	if (os_add_overflow(vp->v_iocount, 1, &vp->v_iocount)) {
6296 		panic("v_iocount overflow");
6297 	}
6298 
6299 #ifdef CONFIG_IOCOUNT_TRACE
6300 	record_vp(vp, 1);
6301 #endif
6302 	return 0;
6303 }
6304 
6305 /*
6306  * vnode_getwithvid() cuts in line in front of a vnode drain (that is,
6307  * while the vnode is draining, but at no point after that) to prevent
6308  * deadlocks when getting vnodes from filesystem hashes while holding
6309  * resources that may prevent other iocounts from being released.
6310  */
6311 int
vnode_getwithvid(vnode_t vp,uint32_t vid)6312 vnode_getwithvid(vnode_t vp, uint32_t vid)
6313 {
6314 	return vget_internal(vp, vid, (VNODE_NODEAD | VNODE_WITHID | VNODE_DRAINO));
6315 }
6316 
6317 /*
6318  * vnode_getwithvid_drainok() is like vnode_getwithvid(), but *does* block behind a vnode
6319  * drain; it exists for use in the VFS name cache, where we really do want to block behind
6320  * vnode drain to prevent holding off an unmount.
6321  */
6322 int
vnode_getwithvid_drainok(vnode_t vp,uint32_t vid)6323 vnode_getwithvid_drainok(vnode_t vp, uint32_t vid)
6324 {
6325 	return vget_internal(vp, vid, (VNODE_NODEAD | VNODE_WITHID));
6326 }
6327 
6328 int
vnode_getwithref(vnode_t vp)6329 vnode_getwithref(vnode_t vp)
6330 {
6331 	return vget_internal(vp, 0, 0);
6332 }
6333 
6334 int
vnode_getwithref_noblock(vnode_t vp)6335 vnode_getwithref_noblock(vnode_t vp)
6336 {
6337 	return vget_internal(vp, 0, VNODE_NOBLOCK);
6338 }
6339 
6340 __private_extern__ int
vnode_getalways(vnode_t vp)6341 vnode_getalways(vnode_t vp)
6342 {
6343 	return vget_internal(vp, 0, VNODE_ALWAYS);
6344 }
6345 
6346 __private_extern__ int
vnode_getalways_from_pager(vnode_t vp)6347 vnode_getalways_from_pager(vnode_t vp)
6348 {
6349 	return vget_internal(vp, 0, VNODE_ALWAYS | VNODE_PAGER);
6350 }
6351 
6352 static inline void
vn_set_dead(vnode_t vp)6353 vn_set_dead(vnode_t vp)
6354 {
6355 	vp->v_mount = NULL;
6356 	vp->v_op = dead_vnodeop_p;
6357 	vp->v_tag = VT_NON;
6358 	vp->v_data = NULL;
6359 	vp->v_type = VBAD;
6360 	vp->v_lflag |= VL_DEAD;
6361 }
6362 
6363 static int
vnode_put_internal_locked(vnode_t vp,bool from_pager)6364 vnode_put_internal_locked(vnode_t vp, bool from_pager)
6365 {
6366 	vfs_context_t ctx = vfs_context_current();      /* hoist outside loop */
6367 
6368 #if DIAGNOSTIC
6369 	lck_mtx_assert(&vp->v_lock, LCK_MTX_ASSERT_OWNED);
6370 #endif
6371 retry:
6372 	if (vp->v_iocount < 1) {
6373 		panic("vnode_put(%p): iocount < 1", vp);
6374 	}
6375 
6376 	if ((vp->v_usecount > 0) || (vp->v_iocount > 1)) {
6377 		vnode_dropiocount(vp);
6378 		return 0;
6379 	}
6380 
6381 	if (((vp->v_lflag & (VL_DEAD | VL_NEEDINACTIVE)) == VL_NEEDINACTIVE)) {
6382 		vp->v_lflag &= ~VL_NEEDINACTIVE;
6383 
6384 		if (UBCINFOEXISTS(vp)) {
6385 			ubc_cs_free_and_vnode_unlock(vp);
6386 		} else {
6387 			vnode_unlock(vp);
6388 		}
6389 
6390 		VNOP_INACTIVE(vp, ctx);
6391 
6392 		vnode_lock_spin(vp);
6393 		/*
6394 		 * because we had to drop the vnode lock before calling
6395 		 * VNOP_INACTIVE, the state of this vnode may have changed...
6396 		 * we may pick up both VL_MARTERM and either
6397 		 * an iocount or a usecount while in the VNOP_INACTIVE call
6398 		 * we don't want to call vnode_reclaim_internal on a vnode
6399 		 * that has active references on it... so loop back around
6400 		 * and reevaluate the state
6401 		 */
6402 		goto retry;
6403 	}
6404 	vp->v_lflag &= ~VL_NEEDINACTIVE;
6405 
6406 	vnode_lock_convert(vp);
6407 	if ((vp->v_lflag & (VL_MARKTERM | VL_TERMINATE | VL_DEAD)) == VL_MARKTERM) {
6408 		if (from_pager) {
6409 			/*
6410 			 * We can't initiate reclaim when called from the pager
6411 			 * because it will deadlock with itself so we hand it
6412 			 * off to the async cleaner thread.
6413 			 */
6414 			vnode_async_list_add(vp);
6415 		} else {
6416 			vnode_reclaim_internal(vp, 1, 1, 0);
6417 		}
6418 	}
6419 	vnode_dropiocount(vp);
6420 	vnode_list_add(vp);
6421 
6422 	return 0;
6423 }
6424 
6425 int
vnode_put_locked(vnode_t vp)6426 vnode_put_locked(vnode_t vp)
6427 {
6428 	return vnode_put_internal_locked(vp, false);
6429 }
6430 
6431 int
vnode_put(vnode_t vp)6432 vnode_put(vnode_t vp)
6433 {
6434 	int retval;
6435 
6436 	vnode_lock_spin(vp);
6437 	vnode_hold(vp);
6438 	retval = vnode_put_internal_locked(vp, false);
6439 	vnode_drop_and_unlock(vp);
6440 
6441 	return retval;
6442 }
6443 
6444 int
vnode_put_from_pager(vnode_t vp)6445 vnode_put_from_pager(vnode_t vp)
6446 {
6447 	int retval;
6448 
6449 	vnode_lock_spin(vp);
6450 	vnode_hold(vp);
6451 	/* Cannot initiate reclaim while paging */
6452 	retval = vnode_put_internal_locked(vp, true);
6453 	vnode_drop_and_unlock(vp);
6454 
6455 	return retval;
6456 }
6457 
6458 int
vnode_writecount(vnode_t vp)6459 vnode_writecount(vnode_t vp)
6460 {
6461 	return vp->v_writecount;
6462 }
6463 
6464 /* is vnode_t in use by others?  */
6465 int
vnode_isinuse(vnode_t vp,int refcnt)6466 vnode_isinuse(vnode_t vp, int refcnt)
6467 {
6468 	return vnode_isinuse_locked(vp, refcnt, 0);
6469 }
6470 
6471 int
vnode_usecount(vnode_t vp)6472 vnode_usecount(vnode_t vp)
6473 {
6474 	return vp->v_usecount;
6475 }
6476 
6477 int
vnode_iocount(vnode_t vp)6478 vnode_iocount(vnode_t vp)
6479 {
6480 	return vp->v_iocount;
6481 }
6482 
6483 int
vnode_isinuse_locked(vnode_t vp,int refcnt,int locked)6484 vnode_isinuse_locked(vnode_t vp, int refcnt, int locked)
6485 {
6486 	int retval = 0;
6487 
6488 	if (!locked) {
6489 		vnode_lock_spin(vp);
6490 	}
6491 	if ((vp->v_type != VREG) && ((vp->v_usecount - vp->v_kusecount) > refcnt)) {
6492 		retval = 1;
6493 		goto out;
6494 	}
6495 	if (vp->v_type == VREG) {
6496 		retval = ubc_isinuse_locked(vp, refcnt, 1);
6497 	}
6498 
6499 out:
6500 	if (!locked) {
6501 		vnode_unlock(vp);
6502 	}
6503 	return retval;
6504 }
6505 
6506 kauth_cred_t
vnode_cred(vnode_t vp)6507 vnode_cred(vnode_t vp)
6508 {
6509 	if (vp->v_cred) {
6510 		return kauth_cred_require(vp->v_cred);
6511 	}
6512 
6513 	return NULL;
6514 }
6515 
6516 
6517 /* resume vnode_t */
6518 errno_t
vnode_resume(vnode_t vp)6519 vnode_resume(vnode_t vp)
6520 {
6521 	if ((vp->v_lflag & VL_SUSPENDED) && vp->v_owner == current_thread()) {
6522 		vnode_lock_spin(vp);
6523 		vp->v_lflag &= ~VL_SUSPENDED;
6524 		vp->v_owner = NULL;
6525 		vnode_unlock(vp);
6526 
6527 		wakeup(&vp->v_iocount);
6528 	}
6529 	return 0;
6530 }
6531 
6532 /* suspend vnode_t
6533  * Please do not use on more than one vnode at a time as it may
6534  * cause deadlocks.
6535  * xxx should we explicity prevent this from happening?
6536  */
6537 
6538 errno_t
vnode_suspend(vnode_t vp)6539 vnode_suspend(vnode_t vp)
6540 {
6541 	if (vp->v_lflag & VL_SUSPENDED) {
6542 		return EBUSY;
6543 	}
6544 
6545 	vnode_lock_spin(vp);
6546 
6547 	/*
6548 	 * xxx is this sufficient to check if a vnode_drain is
6549 	 * progress?
6550 	 */
6551 
6552 	if (vp->v_owner == NULL) {
6553 		vp->v_lflag |= VL_SUSPENDED;
6554 		vp->v_owner = current_thread();
6555 	}
6556 	vnode_unlock(vp);
6557 
6558 	return 0;
6559 }
6560 
6561 /*
6562  * Release any blocked locking requests on the vnode.
6563  * Used for forced-unmounts.
6564  *
6565  * XXX	What about network filesystems?
6566  */
6567 static void
vnode_abort_advlocks(vnode_t vp)6568 vnode_abort_advlocks(vnode_t vp)
6569 {
6570 	if (vp->v_flag & VLOCKLOCAL) {
6571 		lf_abort_advlocks(vp);
6572 	}
6573 }
6574 
6575 
6576 static errno_t
vnode_drain(vnode_t vp)6577 vnode_drain(vnode_t vp)
6578 {
6579 	if (vp->v_lflag & VL_DRAIN) {
6580 		panic("vnode_drain: recursive drain");
6581 		return ENOENT;
6582 	}
6583 	vp->v_lflag |= VL_DRAIN;
6584 	vp->v_owner = current_thread();
6585 
6586 	while (vp->v_iocount > 1) {
6587 		if (bootarg_no_vnode_drain) {
6588 			struct timespec ts = {.tv_sec = 10, .tv_nsec = 0};
6589 			int error;
6590 
6591 			if (vfs_unmountall_started) {
6592 				ts.tv_sec = 1;
6593 			}
6594 
6595 			error = msleep(&vp->v_iocount, &vp->v_lock, PVFS, "vnode_drain_with_timeout", &ts);
6596 
6597 			/* Try to deal with leaked iocounts under bootarg and shutting down */
6598 			if (vp->v_iocount > 1 && error == EWOULDBLOCK &&
6599 			    ts.tv_sec == 1 && vp->v_numoutput == 0) {
6600 				vp->v_iocount = 1;
6601 				break;
6602 			}
6603 		} else {
6604 			msleep(&vp->v_iocount, &vp->v_lock, PVFS, "vnode_drain", NULL);
6605 		}
6606 	}
6607 
6608 	vp->v_lflag &= ~VL_DRAIN;
6609 
6610 	return 0;
6611 }
6612 
6613 
6614 /*
6615  * if the number of recent references via vnode_getwithvid or vnode_getwithref
6616  * exceeds this threshold, than 'UN-AGE' the vnode by removing it from
6617  * the LRU list if it's currently on it... once the iocount and usecount both drop
6618  * to 0, it will get put back on the end of the list, effectively making it younger
6619  * this allows us to keep actively referenced vnodes in the list without having
6620  * to constantly remove and add to the list each time a vnode w/o a usecount is
6621  * referenced which costs us taking and dropping a global lock twice.
6622  * However, if the vnode is marked DIRTY, we want to pull it out much earlier
6623  */
6624 #define UNAGE_THRESHHOLD        25
6625 #define UNAGE_DIRTYTHRESHHOLD    6
6626 
6627 errno_t
vnode_getiocount(vnode_t vp,unsigned int vid,int vflags)6628 vnode_getiocount(vnode_t vp, unsigned int vid, int vflags)
6629 {
6630 	int nodead = vflags & VNODE_NODEAD;
6631 	int nosusp = vflags & VNODE_NOSUSPEND;
6632 	int always = vflags & VNODE_ALWAYS;
6633 	int beatdrain = vflags & VNODE_DRAINO;
6634 	int withvid = vflags & VNODE_WITHID;
6635 	int forpager = vflags & VNODE_PAGER;
6636 	int noblock = vflags & VNODE_NOBLOCK;
6637 
6638 	for (;;) {
6639 		int sleepflg = 0;
6640 
6641 		/*
6642 		 * if it is a dead vnode with deadfs
6643 		 */
6644 		if (nodead && (vp->v_lflag & VL_DEAD) && ((vp->v_type == VBAD) || (vp->v_data == 0))) {
6645 			return ENOENT;
6646 		}
6647 		/*
6648 		 * will return VL_DEAD ones
6649 		 */
6650 		if ((vp->v_lflag & (VL_SUSPENDED | VL_DRAIN | VL_TERMINATE)) == 0) {
6651 			break;
6652 		}
6653 		/*
6654 		 * if suspended vnodes are to be failed
6655 		 */
6656 		if (nosusp && (vp->v_lflag & VL_SUSPENDED)) {
6657 			return ENOENT;
6658 		}
6659 		/*
6660 		 * if you are the owner of drain/suspend/termination , can acquire iocount
6661 		 * check for VL_TERMINATE; it does not set owner
6662 		 */
6663 		if ((vp->v_lflag & (VL_DRAIN | VL_SUSPENDED | VL_TERMINATE)) &&
6664 		    (vp->v_owner == current_thread())) {
6665 			break;
6666 		}
6667 
6668 		if (always != 0) {
6669 			break;
6670 		}
6671 
6672 		if (noblock && (vp->v_lflag & (VL_DRAIN | VL_SUSPENDED | VL_TERMINATE))) {
6673 			return ENOENT;
6674 		}
6675 
6676 		/*
6677 		 * If this vnode is getting drained, there are some cases where
6678 		 * we can't block or, in case of tty vnodes, want to be
6679 		 * interruptible.
6680 		 */
6681 		if (vp->v_lflag & VL_DRAIN) {
6682 			/*
6683 			 * In some situations, we want to get an iocount
6684 			 * even if the vnode is draining to prevent deadlock,
6685 			 * e.g. if we're in the filesystem, potentially holding
6686 			 * resources that could prevent other iocounts from
6687 			 * being released.
6688 			 */
6689 			if (beatdrain) {
6690 				break;
6691 			}
6692 			/*
6693 			 * Don't block if the vnode's mount point is unmounting as
6694 			 * we may be the thread the unmount is itself waiting on
6695 			 * Only callers who pass in vids (at this point, we've already
6696 			 * handled nosusp and nodead) are expecting error returns
6697 			 * from this function, so only we can only return errors for
6698 			 * those. ENODEV is intended to inform callers that the call
6699 			 * failed because an unmount is in progress.
6700 			 */
6701 			if (withvid && (vp->v_mount) && vfs_isunmount(vp->v_mount)) {
6702 				return ENODEV;
6703 			}
6704 
6705 			if (vnode_istty(vp)) {
6706 				sleepflg = PCATCH;
6707 			}
6708 		}
6709 
6710 		vnode_lock_convert(vp);
6711 
6712 		if (vp->v_lflag & VL_TERMINATE) {
6713 			int error;
6714 
6715 			vp->v_lflag |= VL_TERMWANT;
6716 
6717 			error = msleep(&vp->v_lflag, &vp->v_lock,
6718 			    (PVFS | sleepflg), "vnode getiocount", NULL);
6719 			if (error) {
6720 				return error;
6721 			}
6722 		} else {
6723 			msleep(&vp->v_iocount, &vp->v_lock, PVFS, "vnode_getiocount", NULL);
6724 		}
6725 	}
6726 	if (withvid && vid != vp->v_id) {
6727 		return ENOENT;
6728 	}
6729 	if (!forpager && (++vp->v_references >= UNAGE_THRESHHOLD ||
6730 	    (vp->v_flag & VISDIRTY && vp->v_references >= UNAGE_DIRTYTHRESHHOLD))) {
6731 		vp->v_references = 0;
6732 		vnode_list_remove(vp);
6733 	}
6734 	vp->v_iocount++;
6735 #ifdef CONFIG_IOCOUNT_TRACE
6736 	record_vp(vp, 1);
6737 #endif
6738 	return 0;
6739 }
6740 
6741 static void
vnode_dropiocount(vnode_t vp)6742 vnode_dropiocount(vnode_t vp)
6743 {
6744 	if (vp->v_iocount < 1) {
6745 		panic("vnode_dropiocount(%p): v_iocount < 1", vp);
6746 	}
6747 
6748 	vp->v_iocount--;
6749 #ifdef CONFIG_IOCOUNT_TRACE
6750 	record_vp(vp, -1);
6751 #endif
6752 	if ((vp->v_lflag & (VL_DRAIN | VL_SUSPENDED)) && (vp->v_iocount <= 1)) {
6753 		wakeup(&vp->v_iocount);
6754 	}
6755 }
6756 
6757 
6758 void
vnode_reclaim(struct vnode * vp)6759 vnode_reclaim(struct vnode * vp)
6760 {
6761 	vnode_reclaim_internal(vp, 0, 0, 0);
6762 }
6763 
6764 __private_extern__
6765 void
vnode_reclaim_internal(struct vnode * vp,int locked,int reuse,int flags)6766 vnode_reclaim_internal(struct vnode * vp, int locked, int reuse, int flags)
6767 {
6768 	int isfifo = 0;
6769 	bool clear_tty_revoke = false;
6770 
6771 	if (!locked) {
6772 		vnode_lock(vp);
6773 	}
6774 
6775 	if (vp->v_lflag & VL_TERMINATE) {
6776 		panic("vnode reclaim in progress");
6777 	}
6778 	vp->v_lflag |= VL_TERMINATE;
6779 
6780 	vn_clearunionwait(vp, 1);
6781 
6782 	/*
6783 	 * We have to force any terminals in reads to return and give up
6784 	 * their iocounts. It's important to do this after VL_TERMINATE
6785 	 * has been set to ensure new reads are blocked while the
6786 	 * revoke is in progress.
6787 	 */
6788 	if (vnode_istty(vp) && (flags & REVOKEALL) && (vp->v_iocount > 1)) {
6789 		vnode_unlock(vp);
6790 		VNOP_IOCTL(vp, TIOCREVOKE, (caddr_t)NULL, 0, vfs_context_kernel());
6791 		clear_tty_revoke = true;
6792 		vnode_lock(vp);
6793 	}
6794 
6795 	vnode_drain(vp);
6796 
6797 	if (clear_tty_revoke) {
6798 		vnode_unlock(vp);
6799 		VNOP_IOCTL(vp, TIOCREVOKECLEAR, (caddr_t)NULL, 0, vfs_context_kernel());
6800 		vnode_lock(vp);
6801 	}
6802 
6803 #if CONFIG_FILE_LEASES
6804 	/*
6805 	 * Revoke all leases in place for this vnode as it is about to be reclaimed.
6806 	 * In normal case, there shouldn't be any leases in place by the time we
6807 	 * get here as there shouldn't be any opens on the vnode (usecount == 0).
6808 	 * However, in the case of force unmount or unmount of a volume that
6809 	 * contains file that was opened with O_EVTONLY then the vnode can be
6810 	 * reclaimed while the file is still opened.
6811 	 */
6812 	vnode_revokelease(vp, true);
6813 #endif
6814 
6815 	isfifo = (vp->v_type == VFIFO);
6816 
6817 	if (vp->v_type != VBAD) {
6818 		vgone(vp, flags);               /* clean and reclaim the vnode */
6819 	}
6820 	/*
6821 	 * give the vnode a new identity so that vnode_getwithvid will fail
6822 	 * on any stale cache accesses...
6823 	 * grab the list_lock so that if we're in "new_vnode"
6824 	 * behind the list_lock trying to steal this vnode, the v_id is stable...
6825 	 * once new_vnode drops the list_lock, it will block trying to take
6826 	 * the vnode lock until we release it... at that point it will evaluate
6827 	 * whether the v_vid has changed
6828 	 * also need to make sure that the vnode isn't on a list where "new_vnode"
6829 	 * can find it after the v_id has been bumped until we are completely done
6830 	 * with the vnode (i.e. putting it back on a list has to be the very last
6831 	 * thing we do to this vnode... many of the callers of vnode_reclaim_internal
6832 	 * are holding an io_count on the vnode... they need to drop the io_count
6833 	 * BEFORE doing a vnode_list_add or make sure to hold the vnode lock until
6834 	 * they are completely done with the vnode
6835 	 */
6836 	vnode_list_lock();
6837 
6838 	vnode_list_remove_locked(vp);
6839 	vp->v_id++;
6840 
6841 	vnode_list_unlock();
6842 
6843 	if (isfifo) {
6844 		struct fifoinfo * fip;
6845 
6846 		fip = vp->v_fifoinfo;
6847 		vp->v_fifoinfo = NULL;
6848 		kfree_type(struct fifoinfo, fip);
6849 	}
6850 	vp->v_type = VBAD;
6851 
6852 	if (vp->v_data) {
6853 		panic("vnode_reclaim_internal: cleaned vnode isn't");
6854 	}
6855 	if (vp->v_numoutput) {
6856 		panic("vnode_reclaim_internal: clean vnode has pending I/O's");
6857 	}
6858 	if (UBCINFOEXISTS(vp)) {
6859 		panic("vnode_reclaim_internal: ubcinfo not cleaned");
6860 	}
6861 	if (vp->v_parent) {
6862 		panic("vnode_reclaim_internal: vparent not removed");
6863 	}
6864 	if (vp->v_name) {
6865 		panic("vnode_reclaim_internal: vname not removed");
6866 	}
6867 
6868 #if CONFIG_FILE_LEASES
6869 	if (__improbable(!LIST_EMPTY(&vp->v_leases))) {
6870 		panic("vnode_reclaim_internal: vleases NOT empty");
6871 	}
6872 #endif
6873 
6874 	vp->v_socket = NULL;
6875 
6876 	vp->v_lflag &= ~VL_TERMINATE;
6877 	vp->v_owner = NULL;
6878 
6879 #if CONFIG_IOCOUNT_TRACE
6880 	if (__improbable(bootarg_vnode_iocount_trace)) {
6881 		bzero(vp->v_iocount_trace,
6882 		    IOCOUNT_TRACE_MAX_TYPES * sizeof(struct vnode_iocount_trace));
6883 	}
6884 #endif /* CONFIG_IOCOUNT_TRACE */
6885 
6886 	KNOTE(&vp->v_knotes, NOTE_REVOKE);
6887 
6888 	/* Make sure that when we reuse the vnode, no knotes left over */
6889 	klist_init(&vp->v_knotes);
6890 
6891 	if (vp->v_lflag & VL_TERMWANT) {
6892 		vp->v_lflag &= ~VL_TERMWANT;
6893 		wakeup(&vp->v_lflag);
6894 	}
6895 	if (!reuse) {
6896 		/*
6897 		 * make sure we get on the
6898 		 * dead list if appropriate
6899 		 */
6900 		vnode_list_add(vp);
6901 	}
6902 	if (!locked) {
6903 		vnode_unlock(vp);
6904 	}
6905 }
6906 
6907 static int
vnode_create_internal(uint32_t flavor,uint32_t size,void * data,vnode_t * vpp,vnode_create_options_t vc_options)6908 vnode_create_internal(uint32_t flavor, uint32_t size, void *data, vnode_t *vpp,
6909     vnode_create_options_t vc_options)
6910 {
6911 	int error;
6912 	int insert = 1;
6913 	vnode_t vp = NULLVP;
6914 	vnode_t nvp;
6915 	vnode_t dvp;
6916 	struct  uthread *ut;
6917 	struct componentname *cnp;
6918 	struct vnode_fsparam *param = (struct vnode_fsparam *)data;
6919 #if CONFIG_TRIGGERS
6920 	struct vnode_trigger_param *tinfo = NULL;
6921 #endif
6922 	bool existing_vnode;
6923 	bool init_vnode = !(vc_options & VNODE_CREATE_EMPTY);
6924 	bool is_bdevvp = false;
6925 
6926 	if (*vpp) {
6927 		vp = *vpp;
6928 		*vpp = NULLVP;
6929 		existing_vnode = true;
6930 	} else {
6931 		existing_vnode = false;
6932 	}
6933 
6934 	if (init_vnode) {
6935 		/* Do quick sanity check on the parameters. */
6936 		if ((param == NULL) || (param->vnfs_vtype == VBAD)) {
6937 			error = EINVAL;
6938 			goto error_out;
6939 		}
6940 
6941 #if CONFIG_TRIGGERS
6942 		if ((flavor == VNCREATE_TRIGGER) && (size == VNCREATE_TRIGGER_SIZE)) {
6943 			tinfo = (struct vnode_trigger_param *)data;
6944 
6945 			/* Validate trigger vnode input */
6946 			if ((param->vnfs_vtype != VDIR) ||
6947 			    (tinfo->vnt_resolve_func == NULL) ||
6948 			    (tinfo->vnt_flags & ~VNT_VALID_MASK)) {
6949 				error = EINVAL;
6950 				goto error_out;
6951 			}
6952 			/* Fall through a normal create (params will be the same) */
6953 			flavor = VNCREATE_FLAVOR;
6954 			size = VCREATESIZE;
6955 		}
6956 #endif
6957 		if ((flavor != VNCREATE_FLAVOR) || (size != VCREATESIZE)) {
6958 			error = EINVAL;
6959 			goto error_out;
6960 		}
6961 	}
6962 
6963 	if (!existing_vnode) {
6964 		if ((error = new_vnode(&vp, !(vc_options & VNODE_CREATE_NODEALLOC)))) {
6965 			return error;
6966 		}
6967 		if (!init_vnode) {
6968 			/* Make it so that it can be released by a vnode_put) */
6969 			vnode_lock(vp);
6970 			vn_set_dead(vp);
6971 			vnode_unlock(vp);
6972 			*vpp = vp;
6973 			return 0;
6974 		}
6975 	} else {
6976 		/*
6977 		 * A vnode obtained by vnode_create_empty has been passed to
6978 		 * vnode_initialize - Unset VL_DEAD set by vn_set_dead. After
6979 		 * this point, it is set back on any error.
6980 		 */
6981 		vnode_lock(vp);
6982 		vp->v_lflag &= ~VL_DEAD;
6983 		vnode_unlock(vp);
6984 	}
6985 
6986 	dvp = param->vnfs_dvp;
6987 	cnp = param->vnfs_cnp;
6988 
6989 	vp->v_op = param->vnfs_vops;
6990 	vp->v_type = (uint16_t)param->vnfs_vtype;
6991 	vp->v_data = param->vnfs_fsnode;
6992 
6993 	if (param->vnfs_markroot) {
6994 		vp->v_flag |= VROOT;
6995 	}
6996 	if (param->vnfs_marksystem) {
6997 		vp->v_flag |= VSYSTEM;
6998 	}
6999 	if (vp->v_type == VREG) {
7000 		error = ubc_info_init_withsize(vp, param->vnfs_filesize);
7001 		if (error) {
7002 #ifdef CONFIG_IOCOUNT_TRACE
7003 			record_vp(vp, 1);
7004 #endif
7005 			vnode_hold(vp);
7006 			vnode_lock(vp);
7007 			vn_set_dead(vp);
7008 
7009 			vnode_put_locked(vp);
7010 			vnode_drop_and_unlock(vp);
7011 			return error;
7012 		}
7013 		if (param->vnfs_mp->mnt_ioflags & MNT_IOFLAGS_IOSCHED_SUPPORTED) {
7014 			memory_object_mark_io_tracking(vp->v_ubcinfo->ui_control);
7015 		}
7016 	}
7017 #ifdef CONFIG_IOCOUNT_TRACE
7018 	record_vp(vp, 1);
7019 #endif
7020 
7021 #if CONFIG_FIRMLINKS
7022 	vp->v_fmlink = NULLVP;
7023 #endif
7024 	vp->v_flag &= ~VFMLINKTARGET;
7025 
7026 #if CONFIG_TRIGGERS
7027 	/*
7028 	 * For trigger vnodes, attach trigger info to vnode
7029 	 */
7030 	if ((vp->v_type == VDIR) && (tinfo != NULL)) {
7031 		/*
7032 		 * Note: has a side effect of incrementing trigger count on the
7033 		 * mount if successful, which we would need to undo on a
7034 		 * subsequent failure.
7035 		 */
7036 #ifdef CONFIG_IOCOUNT_TRACE
7037 		record_vp(vp, -1);
7038 #endif
7039 		error = vnode_resolver_create(param->vnfs_mp, vp, tinfo, FALSE);
7040 		if (error) {
7041 			printf("vnode_create: vnode_resolver_create() err %d\n", error);
7042 			vnode_hold(vp);
7043 			vnode_lock(vp);
7044 			vn_set_dead(vp);
7045 #ifdef CONFIG_IOCOUNT_TRACE
7046 			record_vp(vp, 1);
7047 #endif
7048 			vnode_put_locked(vp);
7049 			vnode_drop_and_unlock(vp);
7050 			return error;
7051 		}
7052 	}
7053 #endif
7054 	if (vp->v_type == VCHR || vp->v_type == VBLK) {
7055 		vp->v_tag = VT_DEVFS;           /* callers will reset if needed (bdevvp) */
7056 
7057 		if ((nvp = checkalias(vp, param->vnfs_rdev))) {
7058 			/*
7059 			 * if checkalias returns a vnode, it will be locked
7060 			 *
7061 			 * first get rid of the unneeded vnode we acquired
7062 			 */
7063 			vp->v_data = NULL;
7064 			vp->v_op = spec_vnodeop_p;
7065 			vp->v_type = VBAD;
7066 			vp->v_lflag = VL_DEAD;
7067 			vp->v_data = NULL;
7068 			vp->v_tag = VT_NON;
7069 			vnode_put(vp);
7070 
7071 			/*
7072 			 * switch to aliased vnode and finish
7073 			 * preparing it
7074 			 */
7075 			vp = nvp;
7076 
7077 			is_bdevvp = (vp->v_flag & VBDEVVP);
7078 
7079 			if (is_bdevvp) {
7080 				printf("%s: alias vnode (vid = %u) is in state of change (start) v_flags = 0x%x v_numoutput = %d\n",
7081 				    __func__, vp->v_id, vp->v_flag, vp->v_numoutput);
7082 			}
7083 
7084 			vnode_hold(vp);
7085 			vp->v_lflag |= VL_OPSCHANGE;
7086 			vclean(vp, 0);
7087 			vp->v_op = param->vnfs_vops;
7088 			vp->v_type = (uint16_t)param->vnfs_vtype;
7089 			vp->v_data = param->vnfs_fsnode;
7090 			vp->v_lflag = VL_OPSCHANGE;
7091 			vp->v_mount = NULL;
7092 			insmntque(vp, param->vnfs_mp);
7093 			insert = 0;
7094 
7095 			if (is_bdevvp) {
7096 				printf("%s: alias vnode (vid = %u), is in state of change (end) v_flags = 0x%x v_numoutput = %d\n",
7097 				    __func__, vp->v_id, vp->v_flag, vp->v_numoutput);
7098 			}
7099 
7100 			vnode_drop_and_unlock(vp);
7101 			wakeup(&vp->v_lflag); /* chkvnlock is waitng for VL_DEAD to get unset */
7102 		}
7103 
7104 		if (VCHR == vp->v_type) {
7105 			u_int maj = major(vp->v_rdev);
7106 
7107 			if (maj < (u_int)nchrdev && cdevsw[maj].d_type == D_TTY) {
7108 				vp->v_flag |= VISTTY;
7109 			}
7110 		}
7111 	}
7112 
7113 	if (vp->v_type == VFIFO) {
7114 		struct fifoinfo *fip;
7115 
7116 		fip = kalloc_type(struct fifoinfo, Z_WAITOK | Z_ZERO);
7117 		vp->v_fifoinfo = fip;
7118 	}
7119 	/* The file systems must pass the address of the location where
7120 	 * they store the vnode pointer. When we add the vnode into the mount
7121 	 * list and name cache they become discoverable. So the file system node
7122 	 * must have the connection to vnode setup by then
7123 	 */
7124 	*vpp = vp;
7125 
7126 	/* Add fs named reference. */
7127 	if (param->vnfs_flags & VNFS_ADDFSREF) {
7128 		vp->v_lflag |= VNAMED_FSHASH;
7129 	}
7130 	if (param->vnfs_mp) {
7131 		if (param->vnfs_mp->mnt_kern_flag & MNTK_LOCK_LOCAL) {
7132 			vp->v_flag |= VLOCKLOCAL;
7133 		}
7134 		if (insert) {
7135 			if ((vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb)) {
7136 				panic("insmntque: vp on the free list");
7137 			}
7138 
7139 			/*
7140 			 * enter in mount vnode list
7141 			 */
7142 			insmntque(vp, param->vnfs_mp);
7143 		}
7144 	}
7145 	if (dvp && vnode_ref(dvp) == 0) {
7146 		vp->v_parent = dvp;
7147 	}
7148 	if (cnp) {
7149 		if (dvp && ((param->vnfs_flags & (VNFS_NOCACHE | VNFS_CANTCACHE)) == 0)) {
7150 			/*
7151 			 * enter into name cache
7152 			 * we've got the info to enter it into the name cache now
7153 			 * cache_enter_create will pick up an extra reference on
7154 			 * the name entered into the string cache
7155 			 */
7156 			vp->v_name = cache_enter_create(dvp, vp, cnp);
7157 		} else {
7158 			vp->v_name = vfs_addname(cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_hash, 0);
7159 		}
7160 
7161 		if ((cnp->cn_flags & UNIONCREATED) == UNIONCREATED) {
7162 			vp->v_flag |= VISUNION;
7163 		}
7164 	}
7165 	if ((param->vnfs_flags & VNFS_CANTCACHE) == 0) {
7166 		/*
7167 		 * this vnode is being created as cacheable in the name cache
7168 		 * this allows us to re-enter it in the cache
7169 		 */
7170 		vp->v_flag |= VNCACHEABLE;
7171 	}
7172 	ut = current_uthread();
7173 
7174 	if ((current_proc()->p_lflag & P_LRAGE_VNODES) ||
7175 	    (ut->uu_flag & (UT_RAGE_VNODES | UT_KERN_RAGE_VNODES))) {
7176 		/*
7177 		 * process has indicated that it wants any
7178 		 * vnodes created on its behalf to be rapidly
7179 		 * aged to reduce the impact on the cached set
7180 		 * of vnodes
7181 		 *
7182 		 * if UT_KERN_RAGE_VNODES is set, then the
7183 		 * kernel internally wants vnodes to be rapidly
7184 		 * aged, even if the process hasn't requested
7185 		 * this
7186 		 */
7187 		vp->v_flag |= VRAGE;
7188 	}
7189 
7190 #if CONFIG_SECLUDED_MEMORY
7191 	switch (secluded_for_filecache) {
7192 	case SECLUDED_FILECACHE_NONE:
7193 		/*
7194 		 * secluded_for_filecache == 0:
7195 		 * + no file contents in secluded pool
7196 		 */
7197 		break;
7198 	case SECLUDED_FILECACHE_APPS:
7199 		/*
7200 		 * secluded_for_filecache == 1:
7201 		 * + no files from /
7202 		 * + files from /Applications/ are OK
7203 		 * + files from /Applications/Camera are not OK
7204 		 * + no files that are open for write
7205 		 */
7206 		if (vnode_vtype(vp) == VREG &&
7207 		    vnode_mount(vp) != NULL &&
7208 		    (!(vfs_flags(vnode_mount(vp)) & MNT_ROOTFS))) {
7209 			/* not from root filesystem: eligible for secluded pages */
7210 			memory_object_mark_eligible_for_secluded(
7211 				ubc_getobject(vp, UBC_FLAGS_NONE),
7212 				TRUE);
7213 		}
7214 		break;
7215 	case SECLUDED_FILECACHE_RDONLY:
7216 		/*
7217 		 * secluded_for_filecache == 2:
7218 		 * + all read-only files OK, except:
7219 		 *      + dyld_shared_cache_arm64*
7220 		 *      + Camera
7221 		 *      + mediaserverd
7222 		 *      + cameracaptured
7223 		 */
7224 		if (vnode_vtype(vp) == VREG) {
7225 			memory_object_mark_eligible_for_secluded(
7226 				ubc_getobject(vp, UBC_FLAGS_NONE),
7227 				TRUE);
7228 		}
7229 		break;
7230 	default:
7231 		break;
7232 	}
7233 #endif /* CONFIG_SECLUDED_MEMORY */
7234 
7235 	if (is_bdevvp) {
7236 		/*
7237 		 * The v_flags and v_lflags felds for the vndoe above are
7238 		 * manipulated without the vnode lock. This is fine for
7239 		 * everything because no other use  of this vnode is occurring.
7240 		 * However the case of the bdevvp alias vnode reuse is different
7241 		 * and the flags end up being modified while a thread may be in
7242 		 * vnode_waitforwrites which sets VTHROTTLED and any one of the
7243 		 * non atomic modifications of v_flag in this function can race
7244 		 * with the setting of that flag and cause VTHROTTLED on vflag
7245 		 * to get "lost".
7246 		 *
7247 		 * This should ideally be fixed by making sure all modifications
7248 		 * in this function to the vnode flags are done under the
7249 		 * vnode lock but at this time, a much smaller workaround is
7250 		 * being  employed and a the more correct (and potentially
7251 		 * much bigger) change will follow later.
7252 		 *
7253 		 * The effect of "losing" the VTHROTTLED flags would be a lost
7254 		 * wakeup so we just issue that wakeup here since this happens
7255 		 * only once per bdevvp vnode which are only one or two for a
7256 		 * given boot.
7257 		 */
7258 		wakeup(&vp->v_numoutput);
7259 
7260 		/*
7261 		 * now make sure the flags that we were suppossed to put aren't
7262 		 * lost.
7263 		 */
7264 		vnode_lock_spin(vp);
7265 		if (param->vnfs_flags & VNFS_ADDFSREF) {
7266 			vp->v_lflag |= VNAMED_FSHASH;
7267 		}
7268 		if (param->vnfs_mp && (param->vnfs_mp->mnt_kern_flag & MNTK_LOCK_LOCAL)) {
7269 			vp->v_flag |= VLOCKLOCAL;
7270 		}
7271 		if ((param->vnfs_flags & VNFS_CANTCACHE) == 0) {
7272 			vp->v_flag |= VNCACHEABLE;
7273 		}
7274 		vnode_unlock(vp);
7275 	}
7276 
7277 	return 0;
7278 
7279 error_out:
7280 	if (existing_vnode) {
7281 		vnode_put(vp);
7282 	}
7283 	return error;
7284 }
7285 
7286 int
vnode_create_ext(uint32_t flavor,uint32_t size,void * data,vnode_t * vpp,vnode_create_options_t vc_options)7287 vnode_create_ext(uint32_t flavor, uint32_t size, void *data, vnode_t *vpp, vnode_create_options_t vc_options)
7288 {
7289 	if (vc_options & ~(VNODE_CREATE_EMPTY | VNODE_CREATE_NODEALLOC)) {
7290 		return EINVAL;
7291 	}
7292 	*vpp = NULLVP;
7293 	return vnode_create_internal(flavor, size, data, vpp, vc_options);
7294 }
7295 
7296 /* USAGE:
7297  * The following api creates a vnode and associates all the parameter specified in vnode_fsparam
7298  * structure and returns a vnode handle with a reference. device aliasing is handled here so checkalias
7299  * is obsoleted by this.
7300  */
7301 int
vnode_create(uint32_t flavor,uint32_t size,void * data,vnode_t * vpp)7302 vnode_create(uint32_t flavor, uint32_t size, void *data, vnode_t *vpp)
7303 {
7304 	return vnode_create_ext(flavor, size, data, vpp, VNODE_CREATE_NODEALLOC);
7305 }
7306 
7307 int
vnode_create_empty(vnode_t * vpp)7308 vnode_create_empty(vnode_t *vpp)
7309 {
7310 	return vnode_create_ext(VNCREATE_FLAVOR, VCREATESIZE, NULL,
7311 	           vpp, VNODE_CREATE_EMPTY);
7312 }
7313 
7314 int
vnode_initialize(uint32_t __unused flavor,uint32_t size,void * data,vnode_t * vpp)7315 vnode_initialize(uint32_t __unused flavor, uint32_t size, void *data, vnode_t *vpp)
7316 {
7317 	if (*vpp == NULLVP) {
7318 		panic("NULL vnode passed to vnode_initialize");
7319 	}
7320 #if DEVELOPMENT || DEBUG
7321 	/*
7322 	 * We lock to check that vnode is fit for unlocked use in
7323 	 * vnode_create_internal.
7324 	 */
7325 	vnode_lock_spin(*vpp);
7326 	VNASSERT(((*vpp)->v_iocount == 1), *vpp,
7327 	    ("vnode_initialize : iocount not 1, is %d", (*vpp)->v_iocount));
7328 	VNASSERT(((*vpp)->v_usecount == 0), *vpp,
7329 	    ("vnode_initialize : usecount not 0, is %d", (*vpp)->v_usecount));
7330 	VNASSERT(((*vpp)->v_lflag & VL_DEAD), *vpp,
7331 	    ("vnode_initialize : v_lflag does not have VL_DEAD, is 0x%x",
7332 	    (*vpp)->v_lflag));
7333 	VNASSERT(((*vpp)->v_data == NULL), *vpp,
7334 	    ("vnode_initialize : v_data not NULL"));
7335 	vnode_unlock(*vpp);
7336 #endif
7337 	return vnode_create_internal(flavor, size, data, vpp, VNODE_CREATE_DEFAULT);
7338 }
7339 
7340 int
vnode_addfsref(vnode_t vp)7341 vnode_addfsref(vnode_t vp)
7342 {
7343 	vnode_lock_spin(vp);
7344 	if (vp->v_lflag & VNAMED_FSHASH) {
7345 		panic("add_fsref: vp already has named reference");
7346 	}
7347 	if ((vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb)) {
7348 		panic("addfsref: vp on the free list");
7349 	}
7350 	vp->v_lflag |= VNAMED_FSHASH;
7351 	vnode_unlock(vp);
7352 	return 0;
7353 }
7354 int
vnode_removefsref(vnode_t vp)7355 vnode_removefsref(vnode_t vp)
7356 {
7357 	vnode_lock_spin(vp);
7358 	if ((vp->v_lflag & VNAMED_FSHASH) == 0) {
7359 		panic("remove_fsref: no named reference");
7360 	}
7361 	vp->v_lflag &= ~VNAMED_FSHASH;
7362 	vnode_unlock(vp);
7363 	return 0;
7364 }
7365 
7366 
7367 int
vfs_iterate(int flags,int (* callout)(mount_t,void *),void * arg)7368 vfs_iterate(int flags, int (*callout)(mount_t, void *), void *arg)
7369 {
7370 	mount_t mp;
7371 	int ret = 0;
7372 	fsid_t * fsid_list;
7373 	int count, actualcount, i;
7374 	void * allocmem;
7375 	int indx_start, indx_stop, indx_incr;
7376 	int cb_dropref = (flags & VFS_ITERATE_CB_DROPREF);
7377 	int noskip_unmount = (flags & VFS_ITERATE_NOSKIP_UNMOUNT);
7378 
7379 	count = mount_getvfscnt();
7380 	count += 10;
7381 
7382 	fsid_list = kalloc_data(count * sizeof(fsid_t), Z_WAITOK);
7383 	allocmem = (void *)fsid_list;
7384 
7385 	actualcount = mount_fillfsids(fsid_list, count);
7386 
7387 	/*
7388 	 * Establish the iteration direction
7389 	 * VFS_ITERATE_TAIL_FIRST overrides default head first order (oldest first)
7390 	 */
7391 	if (flags & VFS_ITERATE_TAIL_FIRST) {
7392 		indx_start = actualcount - 1;
7393 		indx_stop = -1;
7394 		indx_incr = -1;
7395 	} else { /* Head first by default */
7396 		indx_start = 0;
7397 		indx_stop = actualcount;
7398 		indx_incr = 1;
7399 	}
7400 
7401 	for (i = indx_start; i != indx_stop; i += indx_incr) {
7402 		/* obtain the mount point with iteration reference */
7403 		mp = mount_list_lookupby_fsid(&fsid_list[i], 0, 1);
7404 
7405 		if (mp == (struct mount *)0) {
7406 			continue;
7407 		}
7408 		mount_lock(mp);
7409 		if ((mp->mnt_lflag & MNT_LDEAD) ||
7410 		    (!noskip_unmount && (mp->mnt_lflag & MNT_LUNMOUNT))) {
7411 			mount_unlock(mp);
7412 			mount_iterdrop(mp);
7413 			continue;
7414 		}
7415 		mount_unlock(mp);
7416 
7417 		/* iterate over all the vnodes */
7418 		ret = callout(mp, arg);
7419 
7420 		/*
7421 		 * Drop the iterref here if the callback didn't do it.
7422 		 * Note: If cb_dropref is set the mp may no longer exist.
7423 		 */
7424 		if (!cb_dropref) {
7425 			mount_iterdrop(mp);
7426 		}
7427 
7428 		switch (ret) {
7429 		case VFS_RETURNED:
7430 		case VFS_RETURNED_DONE:
7431 			if (ret == VFS_RETURNED_DONE) {
7432 				ret = 0;
7433 				goto out;
7434 			}
7435 			break;
7436 
7437 		case VFS_CLAIMED_DONE:
7438 			ret = 0;
7439 			goto out;
7440 		case VFS_CLAIMED:
7441 		default:
7442 			break;
7443 		}
7444 		ret = 0;
7445 	}
7446 
7447 out:
7448 	kfree_data(allocmem, count * sizeof(fsid_t));
7449 	return ret;
7450 }
7451 
7452 /*
7453  * Update the vfsstatfs structure in the mountpoint.
7454  * MAC: Parameter eventtype added, indicating whether the event that
7455  * triggered this update came from user space, via a system call
7456  * (VFS_USER_EVENT) or an internal kernel call (VFS_KERNEL_EVENT).
7457  */
7458 int
vfs_update_vfsstat(mount_t mp,vfs_context_t ctx,__unused int eventtype)7459 vfs_update_vfsstat(mount_t mp, vfs_context_t ctx, __unused int eventtype)
7460 {
7461 	struct vfs_attr va;
7462 	int             error;
7463 
7464 	/*
7465 	 * Request the attributes we want to propagate into
7466 	 * the per-mount vfsstat structure.
7467 	 */
7468 	VFSATTR_INIT(&va);
7469 	VFSATTR_WANTED(&va, f_iosize);
7470 	VFSATTR_WANTED(&va, f_blocks);
7471 	VFSATTR_WANTED(&va, f_bfree);
7472 	VFSATTR_WANTED(&va, f_bavail);
7473 	VFSATTR_WANTED(&va, f_bused);
7474 	VFSATTR_WANTED(&va, f_files);
7475 	VFSATTR_WANTED(&va, f_ffree);
7476 	VFSATTR_WANTED(&va, f_bsize);
7477 	VFSATTR_WANTED(&va, f_fssubtype);
7478 
7479 	if ((error = vfs_getattr(mp, &va, ctx)) != 0) {
7480 		KAUTH_DEBUG("STAT - filesystem returned error %d", error);
7481 		return error;
7482 	}
7483 #if CONFIG_MACF
7484 	if (eventtype == VFS_USER_EVENT) {
7485 		error = mac_mount_check_getattr(ctx, mp, &va);
7486 		if (error != 0) {
7487 			return error;
7488 		}
7489 	}
7490 #endif
7491 	/*
7492 	 * Unpack into the per-mount structure.
7493 	 *
7494 	 * We only overwrite these fields, which are likely to change:
7495 	 *	f_blocks
7496 	 *	f_bfree
7497 	 *	f_bavail
7498 	 *	f_bused
7499 	 *	f_files
7500 	 *	f_ffree
7501 	 *
7502 	 * And these which are not, but which the FS has no other way
7503 	 * of providing to us:
7504 	 *	f_bsize
7505 	 *	f_iosize
7506 	 *	f_fssubtype
7507 	 *
7508 	 */
7509 	if (VFSATTR_IS_SUPPORTED(&va, f_bsize)) {
7510 		/* 4822056 - protect against malformed server mount */
7511 		mp->mnt_vfsstat.f_bsize = (va.f_bsize > 0 ? va.f_bsize : 512);
7512 	} else {
7513 		mp->mnt_vfsstat.f_bsize = mp->mnt_devblocksize; /* default from the device block size */
7514 	}
7515 	if (VFSATTR_IS_SUPPORTED(&va, f_iosize)) {
7516 		mp->mnt_vfsstat.f_iosize = va.f_iosize;
7517 	} else {
7518 		mp->mnt_vfsstat.f_iosize = 1024 * 1024;         /* 1MB sensible I/O size */
7519 	}
7520 	if (VFSATTR_IS_SUPPORTED(&va, f_blocks)) {
7521 		mp->mnt_vfsstat.f_blocks = va.f_blocks;
7522 	}
7523 	if (VFSATTR_IS_SUPPORTED(&va, f_bfree)) {
7524 		mp->mnt_vfsstat.f_bfree = va.f_bfree;
7525 	}
7526 	if (VFSATTR_IS_SUPPORTED(&va, f_bavail)) {
7527 		mp->mnt_vfsstat.f_bavail = va.f_bavail;
7528 	}
7529 	if (VFSATTR_IS_SUPPORTED(&va, f_bused)) {
7530 		mp->mnt_vfsstat.f_bused = va.f_bused;
7531 	}
7532 	if (VFSATTR_IS_SUPPORTED(&va, f_files)) {
7533 		mp->mnt_vfsstat.f_files = va.f_files;
7534 	}
7535 	if (VFSATTR_IS_SUPPORTED(&va, f_ffree)) {
7536 		mp->mnt_vfsstat.f_ffree = va.f_ffree;
7537 	}
7538 
7539 	/* this is unlikely to change, but has to be queried for */
7540 	if (VFSATTR_IS_SUPPORTED(&va, f_fssubtype)) {
7541 		mp->mnt_vfsstat.f_fssubtype = va.f_fssubtype;
7542 	}
7543 
7544 	return 0;
7545 }
7546 
7547 int
mount_list_add(mount_t mp)7548 mount_list_add(mount_t mp)
7549 {
7550 	int res;
7551 
7552 	mount_list_lock();
7553 	if (get_system_inshutdown() != 0) {
7554 		res = -1;
7555 	} else {
7556 		TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
7557 		nummounts++;
7558 		res = 0;
7559 	}
7560 	mount_list_unlock();
7561 
7562 	return res;
7563 }
7564 
7565 void
mount_list_remove(mount_t mp)7566 mount_list_remove(mount_t mp)
7567 {
7568 	mount_list_lock();
7569 	TAILQ_REMOVE(&mountlist, mp, mnt_list);
7570 	nummounts--;
7571 	mp->mnt_list.tqe_next = NULL;
7572 	mp->mnt_list.tqe_prev = NULL;
7573 	mount_list_unlock();
7574 }
7575 
7576 mount_t
mount_lookupby_volfsid(int volfs_id,int withref)7577 mount_lookupby_volfsid(int volfs_id, int withref)
7578 {
7579 	mount_t cur_mount = (mount_t)0;
7580 	mount_t mp;
7581 
7582 	mount_list_lock();
7583 	TAILQ_FOREACH(mp, &mountlist, mnt_list) {
7584 		if (!(mp->mnt_kern_flag & MNTK_UNMOUNT) &&
7585 		    (mp->mnt_kern_flag & MNTK_PATH_FROM_ID) &&
7586 		    (mp->mnt_vfsstat.f_fsid.val[0] == volfs_id)) {
7587 			cur_mount = mp;
7588 			if (withref) {
7589 				if (mount_iterref(cur_mount, 1)) {
7590 					cur_mount = (mount_t)0;
7591 					mount_list_unlock();
7592 					goto out;
7593 				}
7594 			}
7595 			break;
7596 		}
7597 	}
7598 	mount_list_unlock();
7599 	if (withref && (cur_mount != (mount_t)0)) {
7600 		mp = cur_mount;
7601 		if (vfs_busy(mp, LK_NOWAIT) != 0) {
7602 			cur_mount = (mount_t)0;
7603 		}
7604 		mount_iterdrop(mp);
7605 	}
7606 out:
7607 	return cur_mount;
7608 }
7609 
7610 mount_t
mount_list_lookupby_fsid(fsid_t * fsid,int locked,int withref)7611 mount_list_lookupby_fsid(fsid_t *fsid, int locked, int withref)
7612 {
7613 	mount_t retmp = (mount_t)0;
7614 	mount_t mp;
7615 
7616 	if (!locked) {
7617 		mount_list_lock();
7618 	}
7619 	TAILQ_FOREACH(mp, &mountlist, mnt_list)
7620 	if (mp->mnt_vfsstat.f_fsid.val[0] == fsid->val[0] &&
7621 	    mp->mnt_vfsstat.f_fsid.val[1] == fsid->val[1]) {
7622 		retmp = mp;
7623 		if (withref) {
7624 			if (mount_iterref(retmp, 1)) {
7625 				retmp = (mount_t)0;
7626 			}
7627 		}
7628 		goto out;
7629 	}
7630 out:
7631 	if (!locked) {
7632 		mount_list_unlock();
7633 	}
7634 	return retmp;
7635 }
7636 
7637 errno_t
vnode_lookupat(const char * path,int flags,vnode_t * vpp,vfs_context_t ctx,vnode_t start_dvp)7638 vnode_lookupat(const char *path, int flags, vnode_t *vpp, vfs_context_t ctx,
7639     vnode_t start_dvp)
7640 {
7641 	struct nameidata *ndp;
7642 	int error = 0;
7643 	u_int32_t ndflags = 0;
7644 
7645 	if (ctx == NULL) {
7646 		return EINVAL;
7647 	}
7648 
7649 	ndp = kalloc_type(struct nameidata, Z_WAITOK | Z_NOFAIL);
7650 
7651 	if (flags & VNODE_LOOKUP_NOFOLLOW) {
7652 		ndflags = NOFOLLOW;
7653 	} else {
7654 		ndflags = FOLLOW;
7655 	}
7656 
7657 	if (flags & VNODE_LOOKUP_NOCROSSMOUNT) {
7658 		ndflags |= NOCROSSMOUNT;
7659 	}
7660 
7661 	if (flags & VNODE_LOOKUP_CROSSMOUNTNOWAIT) {
7662 		ndflags |= CN_NBMOUNTLOOK;
7663 	}
7664 
7665 	/* XXX AUDITVNPATH1 needed ? */
7666 	NDINIT(ndp, LOOKUP, OP_LOOKUP, ndflags, UIO_SYSSPACE,
7667 	    CAST_USER_ADDR_T(path), ctx);
7668 
7669 	if (flags & VNODE_LOOKUP_NOFOLLOW_ANY) {
7670 		ndp->ni_flag |= NAMEI_NOFOLLOW_ANY;
7671 	}
7672 
7673 	if (start_dvp && (path[0] != '/')) {
7674 		ndp->ni_dvp = start_dvp;
7675 		ndp->ni_cnd.cn_flags |= USEDVP;
7676 	}
7677 
7678 	if ((error = namei(ndp))) {
7679 		goto out_free;
7680 	}
7681 
7682 	ndp->ni_cnd.cn_flags &= ~USEDVP;
7683 
7684 	*vpp = ndp->ni_vp;
7685 	nameidone(ndp);
7686 
7687 out_free:
7688 	kfree_type(struct nameidata, ndp);
7689 	return error;
7690 }
7691 
7692 errno_t
vnode_lookup(const char * path,int flags,vnode_t * vpp,vfs_context_t ctx)7693 vnode_lookup(const char *path, int flags, vnode_t *vpp, vfs_context_t ctx)
7694 {
7695 	return vnode_lookupat(path, flags, vpp, ctx, NULLVP);
7696 }
7697 
7698 errno_t
vnode_open(const char * path,int fmode,int cmode,int flags,vnode_t * vpp,vfs_context_t ctx)7699 vnode_open(const char *path, int fmode, int cmode, int flags, vnode_t *vpp, vfs_context_t ctx)
7700 {
7701 	struct nameidata *ndp = NULL;
7702 	int error;
7703 	u_int32_t ndflags = 0;
7704 	int lflags = flags;
7705 
7706 	if (ctx == NULL) {              /* XXX technically an error */
7707 		ctx = vfs_context_current();
7708 	}
7709 
7710 	ndp = kalloc_type(struct nameidata, Z_WAITOK | Z_NOFAIL);
7711 
7712 	if (fmode & O_NOFOLLOW) {
7713 		lflags |= VNODE_LOOKUP_NOFOLLOW;
7714 	}
7715 
7716 	if (lflags & VNODE_LOOKUP_NOFOLLOW) {
7717 		ndflags = NOFOLLOW;
7718 	} else {
7719 		ndflags = FOLLOW;
7720 	}
7721 
7722 	if (lflags & VNODE_LOOKUP_NOFOLLOW_ANY) {
7723 		fmode |= O_NOFOLLOW_ANY;
7724 	}
7725 
7726 	if (lflags & VNODE_LOOKUP_NOCROSSMOUNT) {
7727 		ndflags |= NOCROSSMOUNT;
7728 	}
7729 
7730 	if (lflags & VNODE_LOOKUP_CROSSMOUNTNOWAIT) {
7731 		ndflags |= CN_NBMOUNTLOOK;
7732 	}
7733 
7734 	/* XXX AUDITVNPATH1 needed ? */
7735 	NDINIT(ndp, LOOKUP, OP_OPEN, ndflags, UIO_SYSSPACE,
7736 	    CAST_USER_ADDR_T(path), ctx);
7737 
7738 	if ((error = vn_open(ndp, fmode, cmode))) {
7739 		*vpp = NULL;
7740 	} else {
7741 		*vpp = ndp->ni_vp;
7742 	}
7743 
7744 	kfree_type(struct nameidata, ndp);
7745 	return error;
7746 }
7747 
7748 errno_t
vnode_close(vnode_t vp,int flags,vfs_context_t ctx)7749 vnode_close(vnode_t vp, int flags, vfs_context_t ctx)
7750 {
7751 	int error;
7752 
7753 	if (ctx == NULL) {
7754 		ctx = vfs_context_current();
7755 	}
7756 
7757 	error = vn_close(vp, flags, ctx);
7758 	vnode_put(vp);
7759 	return error;
7760 }
7761 
7762 errno_t
vnode_mtime(vnode_t vp,struct timespec * mtime,vfs_context_t ctx)7763 vnode_mtime(vnode_t vp, struct timespec *mtime, vfs_context_t ctx)
7764 {
7765 	struct vnode_attr       va;
7766 	int                     error;
7767 
7768 	VATTR_INIT(&va);
7769 	VATTR_WANTED(&va, va_modify_time);
7770 	error = vnode_getattr(vp, &va, ctx);
7771 	if (!error) {
7772 		*mtime = va.va_modify_time;
7773 	}
7774 	return error;
7775 }
7776 
7777 errno_t
vnode_flags(vnode_t vp,uint32_t * flags,vfs_context_t ctx)7778 vnode_flags(vnode_t vp, uint32_t *flags, vfs_context_t ctx)
7779 {
7780 	struct vnode_attr       va;
7781 	int                     error;
7782 
7783 	VATTR_INIT(&va);
7784 	VATTR_WANTED(&va, va_flags);
7785 	error = vnode_getattr(vp, &va, ctx);
7786 	if (!error) {
7787 		*flags = va.va_flags;
7788 	}
7789 	return error;
7790 }
7791 
7792 /*
7793  * Returns:	0			Success
7794  *	vnode_getattr:???
7795  */
7796 errno_t
vnode_size(vnode_t vp,off_t * sizep,vfs_context_t ctx)7797 vnode_size(vnode_t vp, off_t *sizep, vfs_context_t ctx)
7798 {
7799 	struct vnode_attr       va;
7800 	int                     error;
7801 
7802 	VATTR_INIT(&va);
7803 	VATTR_WANTED(&va, va_data_size);
7804 	error = vnode_getattr(vp, &va, ctx);
7805 	if (!error) {
7806 		*sizep = va.va_data_size;
7807 	}
7808 	return error;
7809 }
7810 
7811 errno_t
vnode_setsize(vnode_t vp,off_t size,int ioflag,vfs_context_t ctx)7812 vnode_setsize(vnode_t vp, off_t size, int ioflag, vfs_context_t ctx)
7813 {
7814 	struct vnode_attr       va;
7815 
7816 	VATTR_INIT(&va);
7817 	VATTR_SET(&va, va_data_size, size);
7818 	va.va_vaflags = ioflag & 0xffff;
7819 	return vnode_setattr(vp, &va, ctx);
7820 }
7821 
7822 int
vnode_setdirty(vnode_t vp)7823 vnode_setdirty(vnode_t vp)
7824 {
7825 	vnode_lock_spin(vp);
7826 	vp->v_flag |= VISDIRTY;
7827 	vnode_unlock(vp);
7828 	return 0;
7829 }
7830 
7831 int
vnode_cleardirty(vnode_t vp)7832 vnode_cleardirty(vnode_t vp)
7833 {
7834 	vnode_lock_spin(vp);
7835 	vp->v_flag &= ~VISDIRTY;
7836 	vnode_unlock(vp);
7837 	return 0;
7838 }
7839 
7840 int
vnode_isdirty(vnode_t vp)7841 vnode_isdirty(vnode_t vp)
7842 {
7843 	int dirty;
7844 
7845 	vnode_lock_spin(vp);
7846 	dirty = (vp->v_flag & VISDIRTY) ? 1 : 0;
7847 	vnode_unlock(vp);
7848 
7849 	return dirty;
7850 }
7851 
7852 static int
vn_create_reg(vnode_t dvp,vnode_t * vpp,struct nameidata * ndp,struct vnode_attr * vap,uint32_t flags,int fmode,uint32_t * statusp,vfs_context_t ctx)7853 vn_create_reg(vnode_t dvp, vnode_t *vpp, struct nameidata *ndp, struct vnode_attr *vap, uint32_t flags, int fmode, uint32_t *statusp, vfs_context_t ctx)
7854 {
7855 	/* Only use compound VNOP for compound operation */
7856 	if (vnode_compound_open_available(dvp) && ((flags & VN_CREATE_DOOPEN) != 0)) {
7857 		*vpp = NULLVP;
7858 		return VNOP_COMPOUND_OPEN(dvp, vpp, ndp, O_CREAT, fmode, statusp, vap, ctx);
7859 	} else {
7860 		return VNOP_CREATE(dvp, vpp, &ndp->ni_cnd, vap, ctx);
7861 	}
7862 }
7863 
7864 /*
7865  * Create a filesystem object of arbitrary type with arbitrary attributes in
7866  * the spevied directory with the specified name.
7867  *
7868  * Parameters:	dvp			Pointer to the vnode of the directory
7869  *					in which to create the object.
7870  *		vpp			Pointer to the area into which to
7871  *					return the vnode of the created object.
7872  *		cnp			Component name pointer from the namei
7873  *					data structure, containing the name to
7874  *					use for the create object.
7875  *		vap			Pointer to the vnode_attr structure
7876  *					describing the object to be created,
7877  *					including the type of object.
7878  *		flags			VN_* flags controlling ACL inheritance
7879  *					and whether or not authorization is to
7880  *					be required for the operation.
7881  *
7882  * Returns:	0			Success
7883  *		!0			errno value
7884  *
7885  * Implicit:	*vpp			Contains the vnode of the object that
7886  *					was created, if successful.
7887  *		*cnp			May be modified by the underlying VFS.
7888  *		*vap			May be modified by the underlying VFS.
7889  *					modified by either ACL inheritance or
7890  *
7891  *
7892  *					be modified, even if the operation is
7893  *
7894  *
7895  * Notes:	The kauth_filesec_t in 'vap', if any, is in host byte order.
7896  *
7897  *		Modification of '*cnp' and '*vap' by the underlying VFS is
7898  *		strongly discouraged.
7899  *
7900  * XXX:		This function is a 'vn_*' function; it belongs in vfs_vnops.c
7901  *
7902  * XXX:		We should enummerate the possible errno values here, and where
7903  *		in the code they originated.
7904  */
7905 errno_t
vn_create(vnode_t dvp,vnode_t * vpp,struct nameidata * ndp,struct vnode_attr * vap,uint32_t flags,int fmode,uint32_t * statusp,vfs_context_t ctx)7906 vn_create(vnode_t dvp, vnode_t *vpp, struct nameidata *ndp, struct vnode_attr *vap, uint32_t flags, int fmode, uint32_t *statusp, vfs_context_t ctx)
7907 {
7908 	errno_t error, old_error;
7909 	vnode_t vp = (vnode_t)0;
7910 	boolean_t batched;
7911 	struct componentname *cnp;
7912 	uint32_t defaulted;
7913 
7914 	cnp = &ndp->ni_cnd;
7915 	error = 0;
7916 	batched = namei_compound_available(dvp, ndp) ? TRUE : FALSE;
7917 
7918 	KAUTH_DEBUG("%p    CREATE - '%s'", dvp, cnp->cn_nameptr);
7919 
7920 	if (flags & VN_CREATE_NOINHERIT) {
7921 		vap->va_vaflags |= VA_NOINHERIT;
7922 	}
7923 	if (flags & VN_CREATE_NOAUTH) {
7924 		vap->va_vaflags |= VA_NOAUTH;
7925 	}
7926 	/*
7927 	 * Handle ACL inheritance, initialize vap.
7928 	 */
7929 	error = vn_attribute_prepare(dvp, vap, &defaulted, ctx);
7930 	if (error) {
7931 		return error;
7932 	}
7933 
7934 	if (vap->va_type != VREG && (fmode != 0 || (flags & VN_CREATE_DOOPEN) || statusp)) {
7935 		panic("Open parameters, but not a regular file.");
7936 	}
7937 	if ((fmode != 0) && ((flags & VN_CREATE_DOOPEN) == 0)) {
7938 		panic("Mode for open, but not trying to open...");
7939 	}
7940 
7941 
7942 	/*
7943 	 * Create the requested node.
7944 	 */
7945 	switch (vap->va_type) {
7946 	case VREG:
7947 		error = vn_create_reg(dvp, vpp, ndp, vap, flags, fmode, statusp, ctx);
7948 		break;
7949 	case VDIR:
7950 		error = vn_mkdir(dvp, vpp, ndp, vap, ctx);
7951 		break;
7952 	case VSOCK:
7953 	case VFIFO:
7954 	case VBLK:
7955 	case VCHR:
7956 		error = VNOP_MKNOD(dvp, vpp, cnp, vap, ctx);
7957 		break;
7958 	default:
7959 		panic("vnode_create: unknown vtype %d", vap->va_type);
7960 	}
7961 	if (error != 0) {
7962 		KAUTH_DEBUG("%p    CREATE - error %d returned by filesystem", dvp, error);
7963 		goto out;
7964 	}
7965 
7966 	vp = *vpp;
7967 	old_error = error;
7968 
7969 	/*
7970 	 * If some of the requested attributes weren't handled by the VNOP,
7971 	 * use our fallback code.
7972 	 */
7973 	if ((error == 0) && !VATTR_ALL_SUPPORTED(vap) && *vpp) {
7974 		KAUTH_DEBUG("     CREATE - doing fallback with ACL %p", vap->va_acl);
7975 		error = vnode_setattr_fallback(*vpp, vap, ctx);
7976 	}
7977 
7978 #if CONFIG_MACF
7979 	if ((error == 0) && !(flags & VN_CREATE_NOLABEL)) {
7980 		error = vnode_label(vnode_mount(vp), dvp, vp, cnp, VNODE_LABEL_CREATE, ctx);
7981 	}
7982 #endif
7983 
7984 	if ((error != 0) && (vp != (vnode_t)0)) {
7985 		/* If we've done a compound open, close */
7986 		if (batched && (old_error == 0) && (vap->va_type == VREG)) {
7987 			VNOP_CLOSE(vp, fmode, ctx);
7988 		}
7989 
7990 		/* Need to provide notifications if a create succeeded */
7991 		if (!batched) {
7992 			*vpp = (vnode_t) 0;
7993 			vnode_put(vp);
7994 			vp = NULLVP;
7995 		}
7996 	}
7997 
7998 	/*
7999 	 * For creation VNOPs, this is the equivalent of
8000 	 * lookup_handle_found_vnode.
8001 	 */
8002 	if (kdebug_enable && *vpp) {
8003 		kdebug_lookup(*vpp, cnp);
8004 	}
8005 
8006 out:
8007 	vn_attribute_cleanup(vap, defaulted);
8008 
8009 	return error;
8010 }
8011 
8012 static kauth_scope_t    vnode_scope;
8013 static int      vnode_authorize_callback(kauth_cred_t credential, void *idata, kauth_action_t action,
8014     uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
8015 static int vnode_authorize_callback_int(kauth_action_t action, vfs_context_t ctx,
8016     vnode_t vp, vnode_t dvp, int *errorp);
8017 
8018 typedef struct _vnode_authorize_context {
8019 	vnode_t         vp;
8020 	struct vnode_attr *vap;
8021 	vnode_t         dvp;
8022 	struct vnode_attr *dvap;
8023 	vfs_context_t   ctx;
8024 	int             flags;
8025 	int             flags_valid;
8026 #define _VAC_IS_OWNER           (1<<0)
8027 #define _VAC_IN_GROUP           (1<<1)
8028 #define _VAC_IS_DIR_OWNER       (1<<2)
8029 #define _VAC_IN_DIR_GROUP       (1<<3)
8030 #define _VAC_NO_VNODE_POINTERS  (1<<4)
8031 } *vauth_ctx;
8032 
8033 void
vnode_authorize_init(void)8034 vnode_authorize_init(void)
8035 {
8036 	vnode_scope = kauth_register_scope(KAUTH_SCOPE_VNODE, vnode_authorize_callback, NULL);
8037 }
8038 
8039 #define VATTR_PREPARE_DEFAULTED_UID             0x1
8040 #define VATTR_PREPARE_DEFAULTED_GID             0x2
8041 #define VATTR_PREPARE_DEFAULTED_MODE            0x4
8042 
8043 int
vn_attribute_prepare(vnode_t dvp,struct vnode_attr * vap,uint32_t * defaulted_fieldsp,vfs_context_t ctx)8044 vn_attribute_prepare(vnode_t dvp, struct vnode_attr *vap, uint32_t *defaulted_fieldsp, vfs_context_t ctx)
8045 {
8046 	kauth_acl_t nacl = NULL, oacl = NULL;
8047 	int error;
8048 
8049 	/*
8050 	 * Handle ACL inheritance.
8051 	 */
8052 	if (!(vap->va_vaflags & VA_NOINHERIT) && vfs_extendedsecurity(dvp->v_mount)) {
8053 		/* save the original filesec */
8054 		if (VATTR_IS_ACTIVE(vap, va_acl)) {
8055 			oacl = vap->va_acl;
8056 		}
8057 
8058 		vap->va_acl = NULL;
8059 		if ((error = kauth_acl_inherit(dvp,
8060 		    oacl,
8061 		    &nacl,
8062 		    vap->va_type == VDIR,
8063 		    ctx)) != 0) {
8064 			KAUTH_DEBUG("%p    CREATE - error %d processing inheritance", dvp, error);
8065 			return error;
8066 		}
8067 
8068 		/*
8069 		 * If the generated ACL is NULL, then we can save ourselves some effort
8070 		 * by clearing the active bit.
8071 		 */
8072 		if (nacl == NULL) {
8073 			VATTR_CLEAR_ACTIVE(vap, va_acl);
8074 		} else {
8075 			vap->va_base_acl = oacl;
8076 			VATTR_SET(vap, va_acl, nacl);
8077 		}
8078 	}
8079 
8080 	error = vnode_authattr_new_internal(dvp, vap, (vap->va_vaflags & VA_NOAUTH), defaulted_fieldsp, ctx);
8081 	if (error) {
8082 		vn_attribute_cleanup(vap, *defaulted_fieldsp);
8083 	}
8084 
8085 	return error;
8086 }
8087 
8088 void
vn_attribute_cleanup(struct vnode_attr * vap,uint32_t defaulted_fields)8089 vn_attribute_cleanup(struct vnode_attr *vap, uint32_t defaulted_fields)
8090 {
8091 	/*
8092 	 * If the caller supplied a filesec in vap, it has been replaced
8093 	 * now by the post-inheritance copy.  We need to put the original back
8094 	 * and free the inherited product.
8095 	 */
8096 	kauth_acl_t nacl, oacl;
8097 
8098 	if (VATTR_IS_ACTIVE(vap, va_acl)) {
8099 		nacl = vap->va_acl;
8100 		oacl = vap->va_base_acl;
8101 
8102 		if (oacl) {
8103 			VATTR_SET(vap, va_acl, oacl);
8104 			vap->va_base_acl = NULL;
8105 		} else {
8106 			VATTR_CLEAR_ACTIVE(vap, va_acl);
8107 		}
8108 
8109 		if (nacl != NULL) {
8110 			/*
8111 			 * Only free the ACL buffer if 'VA_FILESEC_ACL' is not set as it
8112 			 * should be freed by the caller or it is a post-inheritance copy.
8113 			 */
8114 			if (!(vap->va_vaflags & VA_FILESEC_ACL) ||
8115 			    (oacl != NULL && nacl != oacl)) {
8116 				kauth_acl_free(nacl);
8117 			}
8118 		}
8119 	}
8120 
8121 	if ((defaulted_fields & VATTR_PREPARE_DEFAULTED_MODE) != 0) {
8122 		VATTR_CLEAR_ACTIVE(vap, va_mode);
8123 	}
8124 	if ((defaulted_fields & VATTR_PREPARE_DEFAULTED_GID) != 0) {
8125 		VATTR_CLEAR_ACTIVE(vap, va_gid);
8126 	}
8127 	if ((defaulted_fields & VATTR_PREPARE_DEFAULTED_UID) != 0) {
8128 		VATTR_CLEAR_ACTIVE(vap, va_uid);
8129 	}
8130 
8131 	return;
8132 }
8133 
8134 int
vn_authorize_unlink(vnode_t dvp,vnode_t vp,struct componentname * cnp,vfs_context_t ctx,__unused void * reserved)8135 vn_authorize_unlink(vnode_t dvp, vnode_t vp, struct componentname *cnp, vfs_context_t ctx, __unused void *reserved)
8136 {
8137 #if !CONFIG_MACF
8138 #pragma unused(cnp)
8139 #endif
8140 	int error = 0;
8141 
8142 	/*
8143 	 * Normally, unlinking of directories is not supported.
8144 	 * However, some file systems may have limited support.
8145 	 */
8146 	if ((vp->v_type == VDIR) &&
8147 	    !(vp->v_mount->mnt_kern_flag & MNTK_DIR_HARDLINKS)) {
8148 		return EPERM; /* POSIX */
8149 	}
8150 
8151 	/* authorize the delete operation */
8152 #if CONFIG_MACF
8153 	if (!error) {
8154 		error = mac_vnode_check_unlink(ctx, dvp, vp, cnp);
8155 	}
8156 #endif /* MAC */
8157 	if (!error) {
8158 		error = vnode_authorize(vp, dvp, KAUTH_VNODE_DELETE, ctx);
8159 	}
8160 
8161 	return error;
8162 }
8163 
8164 int
vn_authorize_open_existing(vnode_t vp,struct componentname * cnp,int fmode,vfs_context_t ctx,void * reserved)8165 vn_authorize_open_existing(vnode_t vp, struct componentname *cnp, int fmode, vfs_context_t ctx, void *reserved)
8166 {
8167 	/* Open of existing case */
8168 	kauth_action_t action;
8169 	int error = 0;
8170 	if (cnp->cn_ndp == NULL) {
8171 		panic("NULL ndp");
8172 	}
8173 	if (reserved != NULL) {
8174 		panic("reserved not NULL.");
8175 	}
8176 
8177 #if CONFIG_MACF
8178 	/* XXX may do duplicate work here, but ignore that for now (idempotent) */
8179 	if (vfs_flags(vnode_mount(vp)) & MNT_MULTILABEL) {
8180 		error = vnode_label(vnode_mount(vp), NULL, vp, NULL, 0, ctx);
8181 		if (error) {
8182 			return error;
8183 		}
8184 	}
8185 #endif
8186 
8187 	if (vnode_isdir(vp)) {
8188 		if ((fmode & (FWRITE | O_TRUNC)) || /* disallow write operations on directories */
8189 		    ((fmode & FSEARCH) && !(fmode & O_DIRECTORY))) {
8190 			return EISDIR;
8191 		}
8192 	} else {
8193 		if (fmode & O_DIRECTORY) {
8194 			return ENOTDIR;
8195 		}
8196 
8197 		if (vp->v_type == VSOCK && vp->v_tag != VT_FDESC) {
8198 			return EOPNOTSUPP;    /* Operation not supported on socket */
8199 		}
8200 
8201 		if (vp->v_type == VLNK && (fmode & O_NOFOLLOW) != 0) {
8202 			return ELOOP;         /* O_NOFOLLOW was specified and the target is a symbolic link */
8203 		}
8204 
8205 		if (cnp->cn_ndp->ni_flag & NAMEI_TRAILINGSLASH) {
8206 			return ENOTDIR;
8207 		}
8208 
8209 		if (!vnode_isreg(vp) && (fmode & FEXEC)) {
8210 			return EACCES;
8211 		}
8212 	}
8213 
8214 #if CONFIG_MACF
8215 	/* If a file being opened is a shadow file containing
8216 	 * namedstream data, ignore the macf checks because it
8217 	 * is a kernel internal file and access should always
8218 	 * be allowed.
8219 	 */
8220 	if (!(vnode_isshadow(vp) && vnode_isnamedstream(vp))) {
8221 		error = mac_vnode_check_open(ctx, vp, fmode);
8222 		if (error) {
8223 			return error;
8224 		}
8225 	}
8226 #endif
8227 
8228 	/* compute action to be authorized */
8229 	action = 0;
8230 	if (fmode & FREAD) {
8231 		action |= KAUTH_VNODE_READ_DATA;
8232 	}
8233 	if (fmode & (FWRITE | O_TRUNC)) {
8234 		/*
8235 		 * If we are writing, appending, and not truncating,
8236 		 * indicate that we are appending so that if the
8237 		 * UF_APPEND or SF_APPEND bits are set, we do not deny
8238 		 * the open.
8239 		 */
8240 		if ((fmode & O_APPEND) && !(fmode & O_TRUNC)) {
8241 			action |= KAUTH_VNODE_APPEND_DATA;
8242 		} else {
8243 			action |= KAUTH_VNODE_WRITE_DATA;
8244 		}
8245 	}
8246 	if (fmode & (FSEARCH | FEXEC)) {
8247 		if (vnode_isdir(vp)) {
8248 			action |= KAUTH_VNODE_SEARCH;
8249 		} else {
8250 			action |= KAUTH_VNODE_EXECUTE;
8251 		}
8252 	}
8253 	error = vnode_authorize(vp, NULL, action, ctx);
8254 #if NAMEDSTREAMS
8255 	if (error == EACCES) {
8256 		/*
8257 		 * Shadow files may exist on-disk with a different UID/GID
8258 		 * than that of the current context.  Verify that this file
8259 		 * is really a shadow file.  If it was created successfully
8260 		 * then it should be authorized.
8261 		 */
8262 		if (vnode_isshadow(vp) && vnode_isnamedstream(vp)) {
8263 			error = vnode_verifynamedstream(vp);
8264 		}
8265 	}
8266 #endif
8267 
8268 	return error;
8269 }
8270 
8271 int
vn_authorize_create(vnode_t dvp,struct componentname * cnp,struct vnode_attr * vap,vfs_context_t ctx,void * reserved)8272 vn_authorize_create(vnode_t dvp, struct componentname *cnp, struct vnode_attr *vap, vfs_context_t ctx, void *reserved)
8273 {
8274 #if !CONFIG_MACF
8275 #pragma unused(vap)
8276 #endif
8277 	/* Creation case */
8278 	int error;
8279 
8280 	if (cnp->cn_ndp == NULL) {
8281 		panic("NULL cn_ndp");
8282 	}
8283 	if (reserved != NULL) {
8284 		panic("reserved not NULL.");
8285 	}
8286 
8287 	/* Only validate path for creation if we didn't do a complete lookup */
8288 	if (cnp->cn_ndp->ni_flag & NAMEI_UNFINISHED) {
8289 		error = lookup_validate_creation_path(cnp->cn_ndp);
8290 		if (error) {
8291 			return error;
8292 		}
8293 	}
8294 
8295 #if CONFIG_MACF
8296 	error = mac_vnode_check_create(ctx, dvp, cnp, vap);
8297 	if (error) {
8298 		return error;
8299 	}
8300 #endif /* CONFIG_MACF */
8301 
8302 	return vnode_authorize(dvp, NULL, KAUTH_VNODE_ADD_FILE, ctx);
8303 }
8304 
8305 int
vn_authorize_rename(struct vnode * fdvp,struct vnode * fvp,struct componentname * fcnp,struct vnode * tdvp,struct vnode * tvp,struct componentname * tcnp,vfs_context_t ctx,void * reserved)8306 vn_authorize_rename(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp,
8307     struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp,
8308     vfs_context_t ctx, void *reserved)
8309 {
8310 	return vn_authorize_renamex(fdvp, fvp, fcnp, tdvp, tvp, tcnp, ctx, 0, reserved);
8311 }
8312 
8313 int
vn_authorize_renamex(struct vnode * fdvp,struct vnode * fvp,struct componentname * fcnp,struct vnode * tdvp,struct vnode * tvp,struct componentname * tcnp,vfs_context_t ctx,vfs_rename_flags_t flags,void * reserved)8314 vn_authorize_renamex(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp,
8315     struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp,
8316     vfs_context_t ctx, vfs_rename_flags_t flags, void *reserved)
8317 {
8318 	return vn_authorize_renamex_with_paths(fdvp, fvp, fcnp, NULL, tdvp, tvp, tcnp, NULL, ctx, flags, reserved);
8319 }
8320 
8321 int
vn_authorize_renamex_with_paths(struct vnode * fdvp,struct vnode * fvp,struct componentname * fcnp,const char * from_path,struct vnode * tdvp,struct vnode * tvp,struct componentname * tcnp,const char * to_path,vfs_context_t ctx,vfs_rename_flags_t flags,void * reserved)8322 vn_authorize_renamex_with_paths(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp, const char *from_path,
8323     struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp, const char *to_path,
8324     vfs_context_t ctx, vfs_rename_flags_t flags, void *reserved)
8325 {
8326 	int error = 0;
8327 	int moving = 0;
8328 	bool swap = flags & VFS_RENAME_SWAP;
8329 
8330 	if (reserved != NULL) {
8331 		panic("Passed something other than NULL as reserved field!");
8332 	}
8333 
8334 	/*
8335 	 * Avoid renaming "." and "..".
8336 	 *
8337 	 * XXX No need to check for this in the FS.  We should always have the leaves
8338 	 * in VFS in this case.
8339 	 */
8340 	if (fvp->v_type == VDIR &&
8341 	    ((fdvp == fvp) ||
8342 	    (fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
8343 	    ((fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT))) {
8344 		error = EINVAL;
8345 		goto out;
8346 	}
8347 
8348 	if (tvp == NULLVP && vnode_compound_rename_available(tdvp)) {
8349 		error = lookup_validate_creation_path(tcnp->cn_ndp);
8350 		if (error) {
8351 			goto out;
8352 		}
8353 	}
8354 
8355 	/***** <MACF> *****/
8356 #if CONFIG_MACF
8357 	if (swap) {
8358 		error = mac_vnode_check_rename_swap(ctx, fdvp, fvp, fcnp, tdvp, tvp, tcnp);
8359 	} else {
8360 		error = mac_vnode_check_rename(ctx, fdvp, fvp, fcnp, tdvp, tvp, tcnp);
8361 	}
8362 	if (error) {
8363 		goto out;
8364 	}
8365 #endif
8366 	/***** </MACF> *****/
8367 
8368 	/***** <MiscChecks> *****/
8369 	if (tvp != NULL) {
8370 		if (!swap) {
8371 			if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
8372 				error = ENOTDIR;
8373 				goto out;
8374 			} else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
8375 				error = EISDIR;
8376 				goto out;
8377 			}
8378 		}
8379 	} else if (swap) {
8380 		/*
8381 		 * Caller should have already checked this and returned
8382 		 * ENOENT.  If we send back ENOENT here, caller will retry
8383 		 * which isn't what we want so we send back EINVAL here
8384 		 * instead.
8385 		 */
8386 		error = EINVAL;
8387 		goto out;
8388 	}
8389 
8390 	if (fvp == tdvp) {
8391 		error = EINVAL;
8392 		goto out;
8393 	}
8394 
8395 	/*
8396 	 * The following edge case is caught here:
8397 	 * (to cannot be a descendent of from)
8398 	 *
8399 	 *       o fdvp
8400 	 *      /
8401 	 *     /
8402 	 *    o fvp
8403 	 *     \
8404 	 *      \
8405 	 *       o tdvp
8406 	 *      /
8407 	 *     /
8408 	 *    o tvp
8409 	 */
8410 	if (tdvp->v_parent == fvp) {
8411 		error = EINVAL;
8412 		goto out;
8413 	}
8414 
8415 	if (swap && fdvp->v_parent == tvp) {
8416 		error = EINVAL;
8417 		goto out;
8418 	}
8419 	/***** </MiscChecks> *****/
8420 
8421 	/***** <Kauth> *****/
8422 
8423 	/*
8424 	 * As part of the Kauth step, we call out to allow 3rd-party
8425 	 * fileop notification of "about to rename".  This is needed
8426 	 * in the event that 3rd-parties need to know that the DELETE
8427 	 * authorization is actually part of a rename.  It's important
8428 	 * that we guarantee that the DELETE call-out will always be
8429 	 * made if the WILL_RENAME call-out is made.  Another fileop
8430 	 * call-out will be performed once the operation is completed.
8431 	 * We can ignore the result of kauth_authorize_fileop().
8432 	 *
8433 	 * N.B. We are passing the vnode and *both* paths to each
8434 	 * call; kauth_authorize_fileop() extracts the "from" path
8435 	 * when posting a KAUTH_FILEOP_WILL_RENAME notification.
8436 	 * As such, we only post these notifications if all of the
8437 	 * information we need is provided.
8438 	 */
8439 
8440 	if (swap) {
8441 		kauth_action_t f = 0, t = 0;
8442 
8443 		/*
8444 		 * Directories changing parents need ...ADD_SUBDIR...  to
8445 		 * permit changing ".."
8446 		 */
8447 		if (fdvp != tdvp) {
8448 			if (vnode_isdir(fvp)) {
8449 				f = KAUTH_VNODE_ADD_SUBDIRECTORY;
8450 			}
8451 			if (vnode_isdir(tvp)) {
8452 				t = KAUTH_VNODE_ADD_SUBDIRECTORY;
8453 			}
8454 		}
8455 		if (to_path != NULL) {
8456 			kauth_authorize_fileop(vfs_context_ucred(ctx),
8457 			    KAUTH_FILEOP_WILL_RENAME,
8458 			    (uintptr_t)fvp,
8459 			    (uintptr_t)to_path);
8460 		}
8461 		error = vnode_authorize(fvp, fdvp, KAUTH_VNODE_DELETE | f, ctx);
8462 		if (error) {
8463 			goto out;
8464 		}
8465 		if (from_path != NULL) {
8466 			kauth_authorize_fileop(vfs_context_ucred(ctx),
8467 			    KAUTH_FILEOP_WILL_RENAME,
8468 			    (uintptr_t)tvp,
8469 			    (uintptr_t)from_path);
8470 		}
8471 		error = vnode_authorize(tvp, tdvp, KAUTH_VNODE_DELETE | t, ctx);
8472 		if (error) {
8473 			goto out;
8474 		}
8475 		f = vnode_isdir(fvp) ? KAUTH_VNODE_ADD_SUBDIRECTORY : KAUTH_VNODE_ADD_FILE;
8476 		t = vnode_isdir(tvp) ? KAUTH_VNODE_ADD_SUBDIRECTORY : KAUTH_VNODE_ADD_FILE;
8477 		if (fdvp == tdvp) {
8478 			error = vnode_authorize(fdvp, NULL, f | t, ctx);
8479 		} else {
8480 			error = vnode_authorize(fdvp, NULL, t, ctx);
8481 			if (error) {
8482 				goto out;
8483 			}
8484 			error = vnode_authorize(tdvp, NULL, f, ctx);
8485 		}
8486 		if (error) {
8487 			goto out;
8488 		}
8489 	} else {
8490 		error = 0;
8491 		if ((tvp != NULL) && vnode_isdir(tvp)) {
8492 			if (tvp != fdvp) {
8493 				moving = 1;
8494 			}
8495 		} else if (tdvp != fdvp) {
8496 			moving = 1;
8497 		}
8498 
8499 		/*
8500 		 * must have delete rights to remove the old name even in
8501 		 * the simple case of fdvp == tdvp.
8502 		 *
8503 		 * If fvp is a directory, and we are changing it's parent,
8504 		 * then we also need rights to rewrite its ".." entry as well.
8505 		 */
8506 		if (to_path != NULL) {
8507 			kauth_authorize_fileop(vfs_context_ucred(ctx),
8508 			    KAUTH_FILEOP_WILL_RENAME,
8509 			    (uintptr_t)fvp,
8510 			    (uintptr_t)to_path);
8511 		}
8512 		if (vnode_isdir(fvp)) {
8513 			if ((error = vnode_authorize(fvp, fdvp, KAUTH_VNODE_DELETE | KAUTH_VNODE_ADD_SUBDIRECTORY, ctx)) != 0) {
8514 				goto out;
8515 			}
8516 		} else {
8517 			if ((error = vnode_authorize(fvp, fdvp, KAUTH_VNODE_DELETE, ctx)) != 0) {
8518 				goto out;
8519 			}
8520 		}
8521 		if (moving) {
8522 			/* moving into tdvp or tvp, must have rights to add */
8523 			if ((error = vnode_authorize(((tvp != NULL) && vnode_isdir(tvp)) ? tvp : tdvp,
8524 			    NULL,
8525 			    vnode_isdir(fvp) ? KAUTH_VNODE_ADD_SUBDIRECTORY : KAUTH_VNODE_ADD_FILE,
8526 			    ctx)) != 0) {
8527 				goto out;
8528 			}
8529 		} else {
8530 			/* node staying in same directory, must be allowed to add new name */
8531 			if ((error = vnode_authorize(fdvp, NULL,
8532 			    vnode_isdir(fvp) ? KAUTH_VNODE_ADD_SUBDIRECTORY : KAUTH_VNODE_ADD_FILE, ctx)) != 0) {
8533 				goto out;
8534 			}
8535 		}
8536 		/* overwriting tvp */
8537 		if ((tvp != NULL) && !vnode_isdir(tvp) &&
8538 		    ((error = vnode_authorize(tvp, tdvp, KAUTH_VNODE_DELETE, ctx)) != 0)) {
8539 			goto out;
8540 		}
8541 	}
8542 
8543 	/***** </Kauth> *****/
8544 
8545 	/* XXX more checks? */
8546 out:
8547 	return error;
8548 }
8549 
8550 int
vn_authorize_mkdir(vnode_t dvp,struct componentname * cnp,struct vnode_attr * vap,vfs_context_t ctx,void * reserved)8551 vn_authorize_mkdir(vnode_t dvp, struct componentname *cnp, struct vnode_attr *vap, vfs_context_t ctx, void *reserved)
8552 {
8553 #if !CONFIG_MACF
8554 #pragma unused(vap)
8555 #endif
8556 	int error;
8557 
8558 	if (reserved != NULL) {
8559 		panic("reserved not NULL in vn_authorize_mkdir()");
8560 	}
8561 
8562 	/* XXX A hack for now, to make shadow files work */
8563 	if (cnp->cn_ndp == NULL) {
8564 		return 0;
8565 	}
8566 
8567 	if (vnode_compound_mkdir_available(dvp)) {
8568 		error = lookup_validate_creation_path(cnp->cn_ndp);
8569 		if (error) {
8570 			goto out;
8571 		}
8572 	}
8573 
8574 #if CONFIG_MACF
8575 	error = mac_vnode_check_create(ctx,
8576 	    dvp, cnp, vap);
8577 	if (error) {
8578 		goto out;
8579 	}
8580 #endif
8581 
8582 	/* authorize addition of a directory to the parent */
8583 	if ((error = vnode_authorize(dvp, NULL, KAUTH_VNODE_ADD_SUBDIRECTORY, ctx)) != 0) {
8584 		goto out;
8585 	}
8586 
8587 out:
8588 	return error;
8589 }
8590 
8591 int
vn_authorize_rmdir(vnode_t dvp,vnode_t vp,struct componentname * cnp,vfs_context_t ctx,void * reserved)8592 vn_authorize_rmdir(vnode_t dvp, vnode_t vp, struct componentname *cnp, vfs_context_t ctx, void *reserved)
8593 {
8594 #if CONFIG_MACF
8595 	int error;
8596 #else
8597 #pragma unused(cnp)
8598 #endif
8599 	if (reserved != NULL) {
8600 		panic("Non-NULL reserved argument to vn_authorize_rmdir()");
8601 	}
8602 
8603 	if (vp->v_type != VDIR) {
8604 		/*
8605 		 * rmdir only deals with directories
8606 		 */
8607 		return ENOTDIR;
8608 	}
8609 
8610 	if (dvp == vp) {
8611 		/*
8612 		 * No rmdir "." please.
8613 		 */
8614 		return EINVAL;
8615 	}
8616 
8617 #if CONFIG_MACF
8618 	error = mac_vnode_check_unlink(ctx, dvp,
8619 	    vp, cnp);
8620 	if (error) {
8621 		return error;
8622 	}
8623 #endif
8624 
8625 	return vnode_authorize(vp, dvp, KAUTH_VNODE_DELETE, ctx);
8626 }
8627 
8628 /*
8629  * Authorizer for directory cloning. This does not use vnodes but instead
8630  * uses prefilled vnode attributes from the filesystem.
8631  *
8632  * The same function is called to set up the attributes required, perform the
8633  * authorization and cleanup (if required)
8634  */
8635 int
vnode_attr_authorize_dir_clone(struct vnode_attr * vap,kauth_action_t action,struct vnode_attr * dvap,__unused vnode_t sdvp,mount_t mp,dir_clone_authorizer_op_t vattr_op,uint32_t flags,vfs_context_t ctx,__unused void * reserved)8636 vnode_attr_authorize_dir_clone(struct vnode_attr *vap, kauth_action_t action,
8637     struct vnode_attr *dvap, __unused vnode_t sdvp, mount_t mp,
8638     dir_clone_authorizer_op_t vattr_op, uint32_t flags, vfs_context_t ctx,
8639     __unused void *reserved)
8640 {
8641 	int error;
8642 	int is_suser = vfs_context_issuser(ctx);
8643 
8644 	if (vattr_op == OP_VATTR_SETUP) {
8645 		VATTR_INIT(vap);
8646 
8647 		/*
8648 		 * When ACL inheritence is implemented, both vap->va_acl and
8649 		 * dvap->va_acl will be required (even as superuser).
8650 		 */
8651 		VATTR_WANTED(vap, va_type);
8652 		VATTR_WANTED(vap, va_mode);
8653 		VATTR_WANTED(vap, va_flags);
8654 		VATTR_WANTED(vap, va_uid);
8655 		VATTR_WANTED(vap, va_gid);
8656 		if (dvap) {
8657 			VATTR_INIT(dvap);
8658 			VATTR_WANTED(dvap, va_flags);
8659 		}
8660 
8661 		if (!is_suser) {
8662 			/*
8663 			 * If not superuser, we have to evaluate ACLs and
8664 			 * need the target directory gid to set the initial
8665 			 * gid of the new object.
8666 			 */
8667 			VATTR_WANTED(vap, va_acl);
8668 			if (dvap) {
8669 				VATTR_WANTED(dvap, va_gid);
8670 			}
8671 		} else if (dvap && (flags & VNODE_CLONEFILE_NOOWNERCOPY)) {
8672 			VATTR_WANTED(dvap, va_gid);
8673 		}
8674 		return 0;
8675 	} else if (vattr_op == OP_VATTR_CLEANUP) {
8676 		return 0; /* Nothing to do for now */
8677 	}
8678 
8679 	/* dvap isn't used for authorization */
8680 	error = vnode_attr_authorize(vap, NULL, mp, action, ctx);
8681 
8682 	if (error) {
8683 		return error;
8684 	}
8685 
8686 	/*
8687 	 * vn_attribute_prepare should be able to accept attributes as well as
8688 	 * vnodes but for now we do this inline.
8689 	 */
8690 	if (!is_suser || (flags & VNODE_CLONEFILE_NOOWNERCOPY)) {
8691 		/*
8692 		 * If the filesystem is mounted IGNORE_OWNERSHIP and an explicit
8693 		 * owner is set, that owner takes ownership of all new files.
8694 		 */
8695 		if ((mp->mnt_flag & MNT_IGNORE_OWNERSHIP) &&
8696 		    (mp->mnt_fsowner != KAUTH_UID_NONE)) {
8697 			VATTR_SET(vap, va_uid, mp->mnt_fsowner);
8698 		} else {
8699 			/* default owner is current user */
8700 			VATTR_SET(vap, va_uid,
8701 			    kauth_cred_getuid(vfs_context_ucred(ctx)));
8702 		}
8703 
8704 		if ((mp->mnt_flag & MNT_IGNORE_OWNERSHIP) &&
8705 		    (mp->mnt_fsgroup != KAUTH_GID_NONE)) {
8706 			VATTR_SET(vap, va_gid, mp->mnt_fsgroup);
8707 		} else {
8708 			/*
8709 			 * default group comes from parent object,
8710 			 * fallback to current user
8711 			 */
8712 			if (VATTR_IS_SUPPORTED(dvap, va_gid)) {
8713 				VATTR_SET(vap, va_gid, dvap->va_gid);
8714 			} else {
8715 				VATTR_SET(vap, va_gid,
8716 				    kauth_cred_getgid(vfs_context_ucred(ctx)));
8717 			}
8718 		}
8719 	}
8720 
8721 	/* Inherit SF_RESTRICTED bit from destination directory only */
8722 	if (VATTR_IS_ACTIVE(vap, va_flags)) {
8723 		VATTR_SET(vap, va_flags,
8724 		    ((vap->va_flags & ~(UF_DATAVAULT | SF_RESTRICTED)))); /* Turn off from source */
8725 		if (VATTR_IS_ACTIVE(dvap, va_flags)) {
8726 			VATTR_SET(vap, va_flags,
8727 			    vap->va_flags | (dvap->va_flags & (UF_DATAVAULT | SF_RESTRICTED)));
8728 		}
8729 	} else if (VATTR_IS_ACTIVE(dvap, va_flags)) {
8730 		VATTR_SET(vap, va_flags, (dvap->va_flags & (UF_DATAVAULT | SF_RESTRICTED)));
8731 	}
8732 
8733 	return 0;
8734 }
8735 
8736 
8737 /*
8738  * Authorize an operation on a vnode.
8739  *
8740  * This is KPI, but here because it needs vnode_scope.
8741  *
8742  * Returns:	0			Success
8743  *	kauth_authorize_action:EPERM	...
8744  *	xlate => EACCES			Permission denied
8745  *	kauth_authorize_action:0	Success
8746  *	kauth_authorize_action:		Depends on callback return; this is
8747  *					usually only vnode_authorize_callback(),
8748  *					but may include other listerners, if any
8749  *					exist.
8750  *		EROFS
8751  *		EACCES
8752  *		EPERM
8753  *		???
8754  */
8755 int
vnode_authorize(vnode_t vp,vnode_t dvp,kauth_action_t action,vfs_context_t ctx)8756 vnode_authorize(vnode_t vp, vnode_t dvp, kauth_action_t action, vfs_context_t ctx)
8757 {
8758 	int     error, result;
8759 
8760 	/*
8761 	 * We can't authorize against a dead vnode; allow all operations through so that
8762 	 * the correct error can be returned.
8763 	 */
8764 	if (vp->v_type == VBAD) {
8765 		return 0;
8766 	}
8767 
8768 	error = 0;
8769 	result = kauth_authorize_action(vnode_scope, vfs_context_ucred(ctx), action,
8770 	    (uintptr_t)ctx, (uintptr_t)vp, (uintptr_t)dvp, (uintptr_t)&error);
8771 	if (result == EPERM) {          /* traditional behaviour */
8772 		result = EACCES;
8773 	}
8774 	/* did the lower layers give a better error return? */
8775 	if ((result != 0) && (error != 0)) {
8776 		return error;
8777 	}
8778 	return result;
8779 }
8780 
8781 /*
8782  * Test for vnode immutability.
8783  *
8784  * The 'append' flag is set when the authorization request is constrained
8785  * to operations which only request the right to append to a file.
8786  *
8787  * The 'ignore' flag is set when an operation modifying the immutability flags
8788  * is being authorized.  We check the system securelevel to determine which
8789  * immutability flags we can ignore.
8790  */
8791 static int
vnode_immutable(struct vnode_attr * vap,int append,int ignore)8792 vnode_immutable(struct vnode_attr *vap, int append, int ignore)
8793 {
8794 	int     mask;
8795 
8796 	/* start with all bits precluding the operation */
8797 	mask = IMMUTABLE | APPEND;
8798 
8799 	/* if appending only, remove the append-only bits */
8800 	if (append) {
8801 		mask &= ~APPEND;
8802 	}
8803 
8804 	/* ignore only set when authorizing flags changes */
8805 	if (ignore) {
8806 		if (securelevel <= 0) {
8807 			/* in insecure state, flags do not inhibit changes */
8808 			mask = 0;
8809 		} else {
8810 			/* in secure state, user flags don't inhibit */
8811 			mask &= ~(UF_IMMUTABLE | UF_APPEND);
8812 		}
8813 	}
8814 	KAUTH_DEBUG("IMMUTABLE - file flags 0x%x mask 0x%x append = %d ignore = %d", vap->va_flags, mask, append, ignore);
8815 	if ((vap->va_flags & mask) != 0) {
8816 		return EPERM;
8817 	}
8818 	return 0;
8819 }
8820 
8821 static int
vauth_node_owner(struct vnode_attr * vap,kauth_cred_t cred)8822 vauth_node_owner(struct vnode_attr *vap, kauth_cred_t cred)
8823 {
8824 	int result;
8825 
8826 	/* default assumption is not-owner */
8827 	result = 0;
8828 
8829 	/*
8830 	 * If the filesystem has given us a UID, we treat this as authoritative.
8831 	 */
8832 	if (vap && VATTR_IS_SUPPORTED(vap, va_uid)) {
8833 		result = (vap->va_uid == kauth_cred_getuid(cred)) ? 1 : 0;
8834 	}
8835 	/* we could test the owner UUID here if we had a policy for it */
8836 
8837 	return result;
8838 }
8839 
8840 /*
8841  * vauth_node_group
8842  *
8843  * Description:	Ask if a cred is a member of the group owning the vnode object
8844  *
8845  * Parameters:		vap		vnode attribute
8846  *				vap->va_gid	group owner of vnode object
8847  *			cred		credential to check
8848  *			ismember	pointer to where to put the answer
8849  *			idontknow	Return this if we can't get an answer
8850  *
8851  * Returns:		0		Success
8852  *			idontknow	Can't get information
8853  *	kauth_cred_ismember_gid:?	Error from kauth subsystem
8854  *	kauth_cred_ismember_gid:?	Error from kauth subsystem
8855  */
8856 static int
vauth_node_group(struct vnode_attr * vap,kauth_cred_t cred,int * ismember,int idontknow)8857 vauth_node_group(struct vnode_attr *vap, kauth_cred_t cred, int *ismember, int idontknow)
8858 {
8859 	int     error;
8860 	int     result;
8861 
8862 	error = 0;
8863 	result = 0;
8864 
8865 	/*
8866 	 * The caller is expected to have asked the filesystem for a group
8867 	 * at some point prior to calling this function.  The answer may
8868 	 * have been that there is no group ownership supported for the
8869 	 * vnode object, in which case we return
8870 	 */
8871 	if (vap && VATTR_IS_SUPPORTED(vap, va_gid)) {
8872 		error = kauth_cred_ismember_gid(cred, vap->va_gid, &result);
8873 		/*
8874 		 * Credentials which are opted into external group membership
8875 		 * resolution which are not known to the external resolver
8876 		 * will result in an ENOENT error.  We translate this into
8877 		 * the appropriate 'idontknow' response for our caller.
8878 		 *
8879 		 * XXX We do not make a distinction here between an ENOENT
8880 		 * XXX arising from a response from the external resolver,
8881 		 * XXX and an ENOENT which is internally generated.  This is
8882 		 * XXX a deficiency of the published kauth_cred_ismember_gid()
8883 		 * XXX KPI which can not be overcome without new KPI.  For
8884 		 * XXX all currently known cases, however, this wil result
8885 		 * XXX in correct behaviour.
8886 		 */
8887 		if (error == ENOENT) {
8888 			error = idontknow;
8889 		}
8890 	}
8891 	/*
8892 	 * XXX We could test the group UUID here if we had a policy for it,
8893 	 * XXX but this is problematic from the perspective of synchronizing
8894 	 * XXX group UUID and POSIX GID ownership of a file and keeping the
8895 	 * XXX values coherent over time.  The problem is that the local
8896 	 * XXX system will vend transient group UUIDs for unknown POSIX GID
8897 	 * XXX values, and these are not persistent, whereas storage of values
8898 	 * XXX is persistent.  One potential solution to this is a local
8899 	 * XXX (persistent) replica of remote directory entries and vended
8900 	 * XXX local ids in a local directory server (think in terms of a
8901 	 * XXX caching DNS server).
8902 	 */
8903 
8904 	if (!error) {
8905 		*ismember = result;
8906 	}
8907 	return error;
8908 }
8909 
8910 static int
vauth_file_owner(vauth_ctx vcp)8911 vauth_file_owner(vauth_ctx vcp)
8912 {
8913 	int result;
8914 
8915 	if (vcp->flags_valid & _VAC_IS_OWNER) {
8916 		result = (vcp->flags & _VAC_IS_OWNER) ? 1 : 0;
8917 	} else {
8918 		result = vauth_node_owner(vcp->vap, vcp->ctx->vc_ucred);
8919 
8920 		/* cache our result */
8921 		vcp->flags_valid |= _VAC_IS_OWNER;
8922 		if (result) {
8923 			vcp->flags |= _VAC_IS_OWNER;
8924 		} else {
8925 			vcp->flags &= ~_VAC_IS_OWNER;
8926 		}
8927 	}
8928 	return result;
8929 }
8930 
8931 
8932 /*
8933  * vauth_file_ingroup
8934  *
8935  * Description:	Ask if a user is a member of the group owning the directory
8936  *
8937  * Parameters:		vcp		The vnode authorization context that
8938  *					contains the user and directory info
8939  *				vcp->flags_valid	Valid flags
8940  *				vcp->flags		Flags values
8941  *				vcp->vap		File vnode attributes
8942  *				vcp->ctx		VFS Context (for user)
8943  *			ismember	pointer to where to put the answer
8944  *			idontknow	Return this if we can't get an answer
8945  *
8946  * Returns:		0		Success
8947  *		vauth_node_group:?	Error from vauth_node_group()
8948  *
8949  * Implicit returns:	*ismember	0	The user is not a group member
8950  *					1	The user is a group member
8951  */
8952 static int
vauth_file_ingroup(vauth_ctx vcp,int * ismember,int idontknow)8953 vauth_file_ingroup(vauth_ctx vcp, int *ismember, int idontknow)
8954 {
8955 	int     error;
8956 
8957 	/* Check for a cached answer first, to avoid the check if possible */
8958 	if (vcp->flags_valid & _VAC_IN_GROUP) {
8959 		*ismember = (vcp->flags & _VAC_IN_GROUP) ? 1 : 0;
8960 		error = 0;
8961 	} else {
8962 		/* Otherwise, go look for it */
8963 		error = vauth_node_group(vcp->vap, vcp->ctx->vc_ucred, ismember, idontknow);
8964 
8965 		if (!error) {
8966 			/* cache our result */
8967 			vcp->flags_valid |= _VAC_IN_GROUP;
8968 			if (*ismember) {
8969 				vcp->flags |= _VAC_IN_GROUP;
8970 			} else {
8971 				vcp->flags &= ~_VAC_IN_GROUP;
8972 			}
8973 		}
8974 	}
8975 	return error;
8976 }
8977 
8978 static int
vauth_dir_owner(vauth_ctx vcp)8979 vauth_dir_owner(vauth_ctx vcp)
8980 {
8981 	int result;
8982 
8983 	if (vcp->flags_valid & _VAC_IS_DIR_OWNER) {
8984 		result = (vcp->flags & _VAC_IS_DIR_OWNER) ? 1 : 0;
8985 	} else {
8986 		result = vauth_node_owner(vcp->dvap, vcp->ctx->vc_ucred);
8987 
8988 		/* cache our result */
8989 		vcp->flags_valid |= _VAC_IS_DIR_OWNER;
8990 		if (result) {
8991 			vcp->flags |= _VAC_IS_DIR_OWNER;
8992 		} else {
8993 			vcp->flags &= ~_VAC_IS_DIR_OWNER;
8994 		}
8995 	}
8996 	return result;
8997 }
8998 
8999 /*
9000  * vauth_dir_ingroup
9001  *
9002  * Description:	Ask if a user is a member of the group owning the directory
9003  *
9004  * Parameters:		vcp		The vnode authorization context that
9005  *					contains the user and directory info
9006  *				vcp->flags_valid	Valid flags
9007  *				vcp->flags		Flags values
9008  *				vcp->dvap		Dir vnode attributes
9009  *				vcp->ctx		VFS Context (for user)
9010  *			ismember	pointer to where to put the answer
9011  *			idontknow	Return this if we can't get an answer
9012  *
9013  * Returns:		0		Success
9014  *		vauth_node_group:?	Error from vauth_node_group()
9015  *
9016  * Implicit returns:	*ismember	0	The user is not a group member
9017  *					1	The user is a group member
9018  */
9019 static int
vauth_dir_ingroup(vauth_ctx vcp,int * ismember,int idontknow)9020 vauth_dir_ingroup(vauth_ctx vcp, int *ismember, int idontknow)
9021 {
9022 	int     error;
9023 
9024 	/* Check for a cached answer first, to avoid the check if possible */
9025 	if (vcp->flags_valid & _VAC_IN_DIR_GROUP) {
9026 		*ismember = (vcp->flags & _VAC_IN_DIR_GROUP) ? 1 : 0;
9027 		error = 0;
9028 	} else {
9029 		/* Otherwise, go look for it */
9030 		error = vauth_node_group(vcp->dvap, vcp->ctx->vc_ucred, ismember, idontknow);
9031 
9032 		if (!error) {
9033 			/* cache our result */
9034 			vcp->flags_valid |= _VAC_IN_DIR_GROUP;
9035 			if (*ismember) {
9036 				vcp->flags |= _VAC_IN_DIR_GROUP;
9037 			} else {
9038 				vcp->flags &= ~_VAC_IN_DIR_GROUP;
9039 			}
9040 		}
9041 	}
9042 	return error;
9043 }
9044 
9045 /*
9046  * Test the posix permissions in (vap) to determine whether (credential)
9047  * may perform (action)
9048  */
9049 static int
vnode_authorize_posix(vauth_ctx vcp,int action,int on_dir)9050 vnode_authorize_posix(vauth_ctx vcp, int action, int on_dir)
9051 {
9052 	struct vnode_attr *vap;
9053 	int needed, error, owner_ok, group_ok, world_ok, ismember;
9054 #ifdef KAUTH_DEBUG_ENABLE
9055 	const char *where = "uninitialized";
9056 # define _SETWHERE(c)   where = c;
9057 #else
9058 # define _SETWHERE(c)
9059 #endif
9060 
9061 	/* checking file or directory? */
9062 	if (on_dir) {
9063 		vap = vcp->dvap;
9064 	} else {
9065 		vap = vcp->vap;
9066 	}
9067 
9068 	error = 0;
9069 
9070 	/*
9071 	 * We want to do as little work here as possible.  So first we check
9072 	 * which sets of permissions grant us the access we need, and avoid checking
9073 	 * whether specific permissions grant access when more generic ones would.
9074 	 */
9075 
9076 	/* owner permissions */
9077 	needed = 0;
9078 	if (action & VREAD) {
9079 		needed |= S_IRUSR;
9080 	}
9081 	if (action & VWRITE) {
9082 		needed |= S_IWUSR;
9083 	}
9084 	if (action & VEXEC) {
9085 		needed |= S_IXUSR;
9086 	}
9087 	owner_ok = (needed & vap->va_mode) == needed;
9088 
9089 	/*
9090 	 * Processes with the appropriate entitlement can marked themselves as
9091 	 * ignoring file/directory permissions if they own it.
9092 	 */
9093 	if (!owner_ok && proc_ignores_node_permissions(vfs_context_proc(vcp->ctx))) {
9094 		owner_ok = 1;
9095 	}
9096 
9097 	/* group permissions */
9098 	needed = 0;
9099 	if (action & VREAD) {
9100 		needed |= S_IRGRP;
9101 	}
9102 	if (action & VWRITE) {
9103 		needed |= S_IWGRP;
9104 	}
9105 	if (action & VEXEC) {
9106 		needed |= S_IXGRP;
9107 	}
9108 	group_ok = (needed & vap->va_mode) == needed;
9109 
9110 	/* world permissions */
9111 	needed = 0;
9112 	if (action & VREAD) {
9113 		needed |= S_IROTH;
9114 	}
9115 	if (action & VWRITE) {
9116 		needed |= S_IWOTH;
9117 	}
9118 	if (action & VEXEC) {
9119 		needed |= S_IXOTH;
9120 	}
9121 	world_ok = (needed & vap->va_mode) == needed;
9122 
9123 	/* If granted/denied by all three, we're done */
9124 	if (owner_ok && group_ok && world_ok) {
9125 		_SETWHERE("all");
9126 		goto out;
9127 	}
9128 
9129 	if (!owner_ok && !group_ok && !world_ok) {
9130 		_SETWHERE("all");
9131 		error = EACCES;
9132 		goto out;
9133 	}
9134 
9135 	/* Check ownership (relatively cheap) */
9136 	if ((on_dir && vauth_dir_owner(vcp)) ||
9137 	    (!on_dir && vauth_file_owner(vcp))) {
9138 		_SETWHERE("user");
9139 		if (!owner_ok) {
9140 			error = EACCES;
9141 		}
9142 		goto out;
9143 	}
9144 
9145 	/* Not owner; if group and world both grant it we're done */
9146 	if (group_ok && world_ok) {
9147 		_SETWHERE("group/world");
9148 		goto out;
9149 	}
9150 	if (!group_ok && !world_ok) {
9151 		_SETWHERE("group/world");
9152 		error = EACCES;
9153 		goto out;
9154 	}
9155 
9156 	/* Check group membership (most expensive) */
9157 	ismember = 0;   /* Default to allow, if the target has no group owner */
9158 
9159 	/*
9160 	 * In the case we can't get an answer about the user from the call to
9161 	 * vauth_dir_ingroup() or vauth_file_ingroup(), we want to fail on
9162 	 * the side of caution, rather than simply granting access, or we will
9163 	 * fail to correctly implement exclusion groups, so we set the third
9164 	 * parameter on the basis of the state of 'group_ok'.
9165 	 */
9166 	if (on_dir) {
9167 		error = vauth_dir_ingroup(vcp, &ismember, (!group_ok ? EACCES : 0));
9168 	} else {
9169 		error = vauth_file_ingroup(vcp, &ismember, (!group_ok ? EACCES : 0));
9170 	}
9171 	if (error) {
9172 		if (!group_ok) {
9173 			ismember = 1;
9174 		}
9175 		error = 0;
9176 	}
9177 	if (ismember) {
9178 		_SETWHERE("group");
9179 		if (!group_ok) {
9180 			error = EACCES;
9181 		}
9182 		goto out;
9183 	}
9184 
9185 	/* Not owner, not in group, use world result */
9186 	_SETWHERE("world");
9187 	if (!world_ok) {
9188 		error = EACCES;
9189 	}
9190 
9191 	/* FALLTHROUGH */
9192 
9193 out:
9194 	KAUTH_DEBUG("%p    %s - posix %s permissions : need %s%s%s %x have %s%s%s%s%s%s%s%s%s UID = %d file = %d,%d",
9195 	    vcp->vp, (error == 0) ? "ALLOWED" : "DENIED", where,
9196 	    (action & VREAD)  ? "r" : "-",
9197 	    (action & VWRITE) ? "w" : "-",
9198 	    (action & VEXEC)  ? "x" : "-",
9199 	    needed,
9200 	    (vap->va_mode & S_IRUSR) ? "r" : "-",
9201 	    (vap->va_mode & S_IWUSR) ? "w" : "-",
9202 	    (vap->va_mode & S_IXUSR) ? "x" : "-",
9203 	    (vap->va_mode & S_IRGRP) ? "r" : "-",
9204 	    (vap->va_mode & S_IWGRP) ? "w" : "-",
9205 	    (vap->va_mode & S_IXGRP) ? "x" : "-",
9206 	    (vap->va_mode & S_IROTH) ? "r" : "-",
9207 	    (vap->va_mode & S_IWOTH) ? "w" : "-",
9208 	    (vap->va_mode & S_IXOTH) ? "x" : "-",
9209 	    kauth_cred_getuid(vcp->ctx->vc_ucred),
9210 	    on_dir ? vcp->dvap->va_uid : vcp->vap->va_uid,
9211 	    on_dir ? vcp->dvap->va_gid : vcp->vap->va_gid);
9212 	return error;
9213 }
9214 
9215 /*
9216  * Authorize the deletion of the node vp from the directory dvp.
9217  *
9218  * We assume that:
9219  * - Neither the node nor the directory are immutable.
9220  * - The user is not the superuser.
9221  *
9222  * The precedence of factors for authorizing or denying delete for a credential
9223  *
9224  * 1) Explicit ACE on the node. (allow or deny DELETE)
9225  * 2) Explicit ACE on the directory (allow or deny DELETE_CHILD).
9226  *
9227  *    If there are conflicting ACEs on the node and the directory, the node
9228  *    ACE wins.
9229  *
9230  * 3) Sticky bit on the directory.
9231  *    Deletion is not permitted if the directory is sticky and the caller is
9232  *    not owner of the node or directory. The sticky bit rules are like a deny
9233  *    delete ACE except lower in priority than ACL's either allowing or denying
9234  *    delete.
9235  *
9236  * 4) POSIX permisions on the directory.
9237  *
9238  * As an optimization, we cache whether or not delete child is permitted
9239  * on directories. This enables us to skip directory ACL and POSIX checks
9240  * as we already have the result from those checks. However, we always check the
9241  * node ACL and, if the directory has the sticky bit set, we always check its
9242  * ACL (even for a directory with an authorized delete child). Furthermore,
9243  * caching the delete child authorization is independent of the sticky bit
9244  * being set as it is only applicable in determining whether the node can be
9245  * deleted or not.
9246  */
9247 static int
vnode_authorize_delete(vauth_ctx vcp,boolean_t cached_delete_child)9248 vnode_authorize_delete(vauth_ctx vcp, boolean_t cached_delete_child)
9249 {
9250 	struct vnode_attr       *vap = vcp->vap;
9251 	struct vnode_attr       *dvap = vcp->dvap;
9252 	kauth_cred_t            cred = vcp->ctx->vc_ucred;
9253 	struct kauth_acl_eval   eval;
9254 	int                     error, ismember;
9255 
9256 	/* Check the ACL on the node first */
9257 	if (VATTR_IS_NOT(vap, va_acl, NULL)) {
9258 		eval.ae_requested = KAUTH_VNODE_DELETE;
9259 		eval.ae_acl = &vap->va_acl->acl_ace[0];
9260 		eval.ae_count = vap->va_acl->acl_entrycount;
9261 		eval.ae_options = 0;
9262 		if (vauth_file_owner(vcp)) {
9263 			eval.ae_options |= KAUTH_AEVAL_IS_OWNER;
9264 		}
9265 		/*
9266 		 * We use ENOENT as a marker to indicate we could not get
9267 		 * information in order to delay evaluation until after we
9268 		 * have the ACL evaluation answer.  Previously, we would
9269 		 * always deny the operation at this point.
9270 		 */
9271 		if ((error = vauth_file_ingroup(vcp, &ismember, ENOENT)) != 0 && error != ENOENT) {
9272 			return error;
9273 		}
9274 		if (error == ENOENT) {
9275 			eval.ae_options |= KAUTH_AEVAL_IN_GROUP_UNKNOWN;
9276 		} else if (ismember) {
9277 			eval.ae_options |= KAUTH_AEVAL_IN_GROUP;
9278 		}
9279 		eval.ae_exp_gall = KAUTH_VNODE_GENERIC_ALL_BITS;
9280 		eval.ae_exp_gread = KAUTH_VNODE_GENERIC_READ_BITS;
9281 		eval.ae_exp_gwrite = KAUTH_VNODE_GENERIC_WRITE_BITS;
9282 		eval.ae_exp_gexec = KAUTH_VNODE_GENERIC_EXECUTE_BITS;
9283 
9284 		if ((error = kauth_acl_evaluate(cred, &eval)) != 0) {
9285 			KAUTH_DEBUG("%p    ERROR during ACL processing - %d", vcp->vp, error);
9286 			return error;
9287 		}
9288 
9289 		switch (eval.ae_result) {
9290 		case KAUTH_RESULT_DENY:
9291 			if (vauth_file_owner(vcp) && proc_ignores_node_permissions(vfs_context_proc(vcp->ctx))) {
9292 				KAUTH_DEBUG("%p    Override DENY due to entitlement", vcp->vp);
9293 				return 0;
9294 			}
9295 			KAUTH_DEBUG("%p    DENIED - denied by ACL", vcp->vp);
9296 			return EACCES;
9297 		case KAUTH_RESULT_ALLOW:
9298 			KAUTH_DEBUG("%p    ALLOWED - granted by ACL", vcp->vp);
9299 			return 0;
9300 		case KAUTH_RESULT_DEFER:
9301 		default:
9302 			/* Defer to directory */
9303 			KAUTH_DEBUG("%p    DEFERRED - by file ACL", vcp->vp);
9304 			break;
9305 		}
9306 	}
9307 
9308 	/*
9309 	 * Without a sticky bit, a previously authorized delete child is
9310 	 * sufficient to authorize this delete.
9311 	 *
9312 	 * If the sticky bit is set, a directory ACL which allows delete child
9313 	 * overrides a (potential) sticky bit deny. The authorized delete child
9314 	 * cannot tell us if it was authorized because of an explicit delete
9315 	 * child allow ACE or because of POSIX permisions so we have to check
9316 	 * the directory ACL everytime if the directory has a sticky bit.
9317 	 */
9318 	if (!(dvap->va_mode & S_ISTXT) && cached_delete_child) {
9319 		KAUTH_DEBUG("%p    ALLOWED - granted by directory ACL or POSIX permissions and no sticky bit on directory", vcp->vp);
9320 		return 0;
9321 	}
9322 
9323 	/* check the ACL on the directory */
9324 	if (VATTR_IS_NOT(dvap, va_acl, NULL)) {
9325 		eval.ae_requested = KAUTH_VNODE_DELETE_CHILD;
9326 		eval.ae_acl = &dvap->va_acl->acl_ace[0];
9327 		eval.ae_count = dvap->va_acl->acl_entrycount;
9328 		eval.ae_options = 0;
9329 		if (vauth_dir_owner(vcp)) {
9330 			eval.ae_options |= KAUTH_AEVAL_IS_OWNER;
9331 		}
9332 		/*
9333 		 * We use ENOENT as a marker to indicate we could not get
9334 		 * information in order to delay evaluation until after we
9335 		 * have the ACL evaluation answer.  Previously, we would
9336 		 * always deny the operation at this point.
9337 		 */
9338 		if ((error = vauth_dir_ingroup(vcp, &ismember, ENOENT)) != 0 && error != ENOENT) {
9339 			return error;
9340 		}
9341 		if (error == ENOENT) {
9342 			eval.ae_options |= KAUTH_AEVAL_IN_GROUP_UNKNOWN;
9343 		} else if (ismember) {
9344 			eval.ae_options |= KAUTH_AEVAL_IN_GROUP;
9345 		}
9346 		eval.ae_exp_gall = KAUTH_VNODE_GENERIC_ALL_BITS;
9347 		eval.ae_exp_gread = KAUTH_VNODE_GENERIC_READ_BITS;
9348 		eval.ae_exp_gwrite = KAUTH_VNODE_GENERIC_WRITE_BITS;
9349 		eval.ae_exp_gexec = KAUTH_VNODE_GENERIC_EXECUTE_BITS;
9350 
9351 		/*
9352 		 * If there is no entry, we are going to defer to other
9353 		 * authorization mechanisms.
9354 		 */
9355 		error = kauth_acl_evaluate(cred, &eval);
9356 
9357 		if (error != 0) {
9358 			KAUTH_DEBUG("%p    ERROR during ACL processing - %d", vcp->vp, error);
9359 			return error;
9360 		}
9361 		switch (eval.ae_result) {
9362 		case KAUTH_RESULT_DENY:
9363 			if (vauth_dir_owner(vcp) && proc_ignores_node_permissions(vfs_context_proc(vcp->ctx))) {
9364 				KAUTH_DEBUG("%p    Override DENY due to entitlement", vcp->vp);
9365 				return 0;
9366 			}
9367 			KAUTH_DEBUG("%p    DENIED - denied by directory ACL", vcp->vp);
9368 			return EACCES;
9369 		case KAUTH_RESULT_ALLOW:
9370 			KAUTH_DEBUG("%p    ALLOWED - granted by directory ACL", vcp->vp);
9371 			if (!cached_delete_child && vcp->dvp) {
9372 				vnode_cache_authorized_action(vcp->dvp,
9373 				    vcp->ctx, KAUTH_VNODE_DELETE_CHILD);
9374 			}
9375 			return 0;
9376 		case KAUTH_RESULT_DEFER:
9377 		default:
9378 			/* Deferred by directory ACL */
9379 			KAUTH_DEBUG("%p    DEFERRED - directory ACL", vcp->vp);
9380 			break;
9381 		}
9382 	}
9383 
9384 	/*
9385 	 * From this point, we can't explicitly allow and if we reach the end
9386 	 * of the function without a denial, then the delete is authorized.
9387 	 */
9388 	if (!cached_delete_child) {
9389 		if (vnode_authorize_posix(vcp, VWRITE, 1 /* on_dir */) != 0) {
9390 			KAUTH_DEBUG("%p    DENIED - denied by posix permisssions", vcp->vp);
9391 			return EACCES;
9392 		}
9393 		/*
9394 		 * Cache the authorized action on the vnode if allowed by the
9395 		 * directory ACL or POSIX permissions. It is correct to cache
9396 		 * this action even if sticky bit would deny deleting the node.
9397 		 */
9398 		if (vcp->dvp) {
9399 			vnode_cache_authorized_action(vcp->dvp, vcp->ctx,
9400 			    KAUTH_VNODE_DELETE_CHILD);
9401 		}
9402 	}
9403 
9404 	/* enforce sticky bit behaviour */
9405 	if ((dvap->va_mode & S_ISTXT) && !vauth_file_owner(vcp) && !vauth_dir_owner(vcp)) {
9406 		KAUTH_DEBUG("%p    DENIED - sticky bit rules (user %d  file %d  dir %d)",
9407 		    vcp->vp, cred->cr_posix.cr_uid, vap->va_uid, dvap->va_uid);
9408 		return EACCES;
9409 	}
9410 
9411 	/* not denied, must be OK */
9412 	return 0;
9413 }
9414 
9415 
9416 /*
9417  * Authorize an operation based on the node's attributes.
9418  */
9419 static int
vnode_authorize_simple(vauth_ctx vcp,kauth_ace_rights_t acl_rights,kauth_ace_rights_t preauth_rights,boolean_t * found_deny)9420 vnode_authorize_simple(vauth_ctx vcp, kauth_ace_rights_t acl_rights, kauth_ace_rights_t preauth_rights, boolean_t *found_deny)
9421 {
9422 	struct vnode_attr       *vap = vcp->vap;
9423 	kauth_cred_t            cred = vcp->ctx->vc_ucred;
9424 	struct kauth_acl_eval   eval;
9425 	int                     error, ismember;
9426 	mode_t                  posix_action;
9427 
9428 	/*
9429 	 * If we are the file owner, we automatically have some rights.
9430 	 *
9431 	 * Do we need to expand this to support group ownership?
9432 	 */
9433 	if (vauth_file_owner(vcp)) {
9434 		acl_rights &= ~(KAUTH_VNODE_WRITE_SECURITY);
9435 	}
9436 
9437 	/*
9438 	 * If we are checking both TAKE_OWNERSHIP and WRITE_SECURITY, we can
9439 	 * mask the latter.  If TAKE_OWNERSHIP is requested the caller is about to
9440 	 * change ownership to themselves, and WRITE_SECURITY is implicitly
9441 	 * granted to the owner.  We need to do this because at this point
9442 	 * WRITE_SECURITY may not be granted as the caller is not currently
9443 	 * the owner.
9444 	 */
9445 	if ((acl_rights & KAUTH_VNODE_TAKE_OWNERSHIP) &&
9446 	    (acl_rights & KAUTH_VNODE_WRITE_SECURITY)) {
9447 		acl_rights &= ~KAUTH_VNODE_WRITE_SECURITY;
9448 	}
9449 
9450 	if (acl_rights == 0) {
9451 		KAUTH_DEBUG("%p    ALLOWED - implicit or no rights required", vcp->vp);
9452 		return 0;
9453 	}
9454 
9455 	/* if we have an ACL, evaluate it */
9456 	if (VATTR_IS_NOT(vap, va_acl, NULL)) {
9457 		eval.ae_requested = acl_rights;
9458 		eval.ae_acl = &vap->va_acl->acl_ace[0];
9459 		eval.ae_count = vap->va_acl->acl_entrycount;
9460 		eval.ae_options = 0;
9461 		if (vauth_file_owner(vcp)) {
9462 			eval.ae_options |= KAUTH_AEVAL_IS_OWNER;
9463 		}
9464 		/*
9465 		 * We use ENOENT as a marker to indicate we could not get
9466 		 * information in order to delay evaluation until after we
9467 		 * have the ACL evaluation answer.  Previously, we would
9468 		 * always deny the operation at this point.
9469 		 */
9470 		if ((error = vauth_file_ingroup(vcp, &ismember, ENOENT)) != 0 && error != ENOENT) {
9471 			return error;
9472 		}
9473 		if (error == ENOENT) {
9474 			eval.ae_options |= KAUTH_AEVAL_IN_GROUP_UNKNOWN;
9475 		} else if (ismember) {
9476 			eval.ae_options |= KAUTH_AEVAL_IN_GROUP;
9477 		}
9478 		eval.ae_exp_gall = KAUTH_VNODE_GENERIC_ALL_BITS;
9479 		eval.ae_exp_gread = KAUTH_VNODE_GENERIC_READ_BITS;
9480 		eval.ae_exp_gwrite = KAUTH_VNODE_GENERIC_WRITE_BITS;
9481 		eval.ae_exp_gexec = KAUTH_VNODE_GENERIC_EXECUTE_BITS;
9482 
9483 		if ((error = kauth_acl_evaluate(cred, &eval)) != 0) {
9484 			KAUTH_DEBUG("%p    ERROR during ACL processing - %d", vcp->vp, error);
9485 			return error;
9486 		}
9487 
9488 		switch (eval.ae_result) {
9489 		case KAUTH_RESULT_DENY:
9490 			if (vauth_file_owner(vcp) && proc_ignores_node_permissions(vfs_context_proc(vcp->ctx))) {
9491 				KAUTH_DEBUG("%p    Override DENY due to entitlement", vcp->vp);
9492 				return 0;
9493 			}
9494 			KAUTH_DEBUG("%p    DENIED - by ACL", vcp->vp);
9495 			return EACCES;         /* deny, deny, counter-allege */
9496 		case KAUTH_RESULT_ALLOW:
9497 			KAUTH_DEBUG("%p    ALLOWED - all rights granted by ACL", vcp->vp);
9498 			return 0;
9499 		case KAUTH_RESULT_DEFER:
9500 		default:
9501 			/* Effectively the same as !delete_child_denied */
9502 			KAUTH_DEBUG("%p    DEFERRED - directory ACL", vcp->vp);
9503 			break;
9504 		}
9505 
9506 		*found_deny = eval.ae_found_deny;
9507 
9508 		/* fall through and evaluate residual rights */
9509 	} else {
9510 		/* no ACL, everything is residual */
9511 		eval.ae_residual = acl_rights;
9512 	}
9513 
9514 	/*
9515 	 * Grant residual rights that have been pre-authorized.
9516 	 */
9517 	eval.ae_residual &= ~preauth_rights;
9518 
9519 	/*
9520 	 * We grant WRITE_ATTRIBUTES to the owner if it hasn't been denied.
9521 	 */
9522 	if (vauth_file_owner(vcp)) {
9523 		eval.ae_residual &= ~KAUTH_VNODE_WRITE_ATTRIBUTES;
9524 	}
9525 
9526 	if (eval.ae_residual == 0) {
9527 		KAUTH_DEBUG("%p    ALLOWED - rights already authorized", vcp->vp);
9528 		return 0;
9529 	}
9530 
9531 	/*
9532 	 * Bail if we have residual rights that can't be granted by posix permissions,
9533 	 * or aren't presumed granted at this point.
9534 	 *
9535 	 * XXX these can be collapsed for performance
9536 	 */
9537 	if (eval.ae_residual & KAUTH_VNODE_CHANGE_OWNER) {
9538 		KAUTH_DEBUG("%p    DENIED - CHANGE_OWNER not permitted", vcp->vp);
9539 		return EACCES;
9540 	}
9541 	if (eval.ae_residual & KAUTH_VNODE_WRITE_SECURITY) {
9542 		KAUTH_DEBUG("%p    DENIED - WRITE_SECURITY not permitted", vcp->vp);
9543 		return EACCES;
9544 	}
9545 
9546 #if DIAGNOSTIC
9547 	if (eval.ae_residual & KAUTH_VNODE_DELETE) {
9548 		panic("vnode_authorize: can't be checking delete permission here");
9549 	}
9550 #endif
9551 
9552 	/*
9553 	 * Compute the fallback posix permissions that will satisfy the remaining
9554 	 * rights.
9555 	 */
9556 	posix_action = 0;
9557 	if (eval.ae_residual & (KAUTH_VNODE_READ_DATA |
9558 	    KAUTH_VNODE_LIST_DIRECTORY |
9559 	    KAUTH_VNODE_READ_EXTATTRIBUTES)) {
9560 		posix_action |= VREAD;
9561 	}
9562 	if (eval.ae_residual & (KAUTH_VNODE_WRITE_DATA |
9563 	    KAUTH_VNODE_ADD_FILE |
9564 	    KAUTH_VNODE_ADD_SUBDIRECTORY |
9565 	    KAUTH_VNODE_DELETE_CHILD |
9566 	    KAUTH_VNODE_WRITE_ATTRIBUTES |
9567 	    KAUTH_VNODE_WRITE_EXTATTRIBUTES)) {
9568 		posix_action |= VWRITE;
9569 	}
9570 	if (eval.ae_residual & (KAUTH_VNODE_EXECUTE |
9571 	    KAUTH_VNODE_SEARCH)) {
9572 		posix_action |= VEXEC;
9573 	}
9574 
9575 	if (posix_action != 0) {
9576 		return vnode_authorize_posix(vcp, posix_action, 0 /* !on_dir */);
9577 	} else {
9578 		KAUTH_DEBUG("%p    ALLOWED - residual rights %s%s%s%s%s%s%s%s%s%s%s%s%s%s granted due to no posix mapping",
9579 		    vcp->vp,
9580 		    (eval.ae_residual & KAUTH_VNODE_READ_DATA)
9581 		    ? vnode_isdir(vcp->vp) ? " LIST_DIRECTORY" : " READ_DATA" : "",
9582 		    (eval.ae_residual & KAUTH_VNODE_WRITE_DATA)
9583 		    ? vnode_isdir(vcp->vp) ? " ADD_FILE" : " WRITE_DATA" : "",
9584 		    (eval.ae_residual & KAUTH_VNODE_EXECUTE)
9585 		    ? vnode_isdir(vcp->vp) ? " SEARCH" : " EXECUTE" : "",
9586 		    (eval.ae_residual & KAUTH_VNODE_DELETE)
9587 		    ? " DELETE" : "",
9588 		    (eval.ae_residual & KAUTH_VNODE_APPEND_DATA)
9589 		    ? vnode_isdir(vcp->vp) ? " ADD_SUBDIRECTORY" : " APPEND_DATA" : "",
9590 		    (eval.ae_residual & KAUTH_VNODE_DELETE_CHILD)
9591 		    ? " DELETE_CHILD" : "",
9592 		    (eval.ae_residual & KAUTH_VNODE_READ_ATTRIBUTES)
9593 		    ? " READ_ATTRIBUTES" : "",
9594 		    (eval.ae_residual & KAUTH_VNODE_WRITE_ATTRIBUTES)
9595 		    ? " WRITE_ATTRIBUTES" : "",
9596 		    (eval.ae_residual & KAUTH_VNODE_READ_EXTATTRIBUTES)
9597 		    ? " READ_EXTATTRIBUTES" : "",
9598 		    (eval.ae_residual & KAUTH_VNODE_WRITE_EXTATTRIBUTES)
9599 		    ? " WRITE_EXTATTRIBUTES" : "",
9600 		    (eval.ae_residual & KAUTH_VNODE_READ_SECURITY)
9601 		    ? " READ_SECURITY" : "",
9602 		    (eval.ae_residual & KAUTH_VNODE_WRITE_SECURITY)
9603 		    ? " WRITE_SECURITY" : "",
9604 		    (eval.ae_residual & KAUTH_VNODE_CHECKIMMUTABLE)
9605 		    ? " CHECKIMMUTABLE" : "",
9606 		    (eval.ae_residual & KAUTH_VNODE_CHANGE_OWNER)
9607 		    ? " CHANGE_OWNER" : "");
9608 	}
9609 
9610 	/*
9611 	 * Lack of required Posix permissions implies no reason to deny access.
9612 	 */
9613 	return 0;
9614 }
9615 
9616 /*
9617  * Check for file immutability.
9618  */
9619 static int
vnode_authorize_checkimmutable(mount_t mp,vauth_ctx vcp,struct vnode_attr * vap,int rights,int ignore)9620 vnode_authorize_checkimmutable(mount_t mp, vauth_ctx vcp,
9621     struct vnode_attr *vap, int rights, int ignore)
9622 {
9623 	int error;
9624 	int append;
9625 
9626 	/*
9627 	 * Perform immutability checks for operations that change data.
9628 	 *
9629 	 * Sockets, fifos and devices require special handling.
9630 	 */
9631 	switch (vap->va_type) {
9632 	case VSOCK:
9633 	case VFIFO:
9634 	case VBLK:
9635 	case VCHR:
9636 		/*
9637 		 * Writing to these nodes does not change the filesystem data,
9638 		 * so forget that it's being tried.
9639 		 */
9640 		rights &= ~KAUTH_VNODE_WRITE_DATA;
9641 		break;
9642 	default:
9643 		break;
9644 	}
9645 
9646 	error = 0;
9647 	if (rights & KAUTH_VNODE_WRITE_RIGHTS) {
9648 		/* check per-filesystem options if possible */
9649 		if (mp != NULL) {
9650 			/* check for no-EA filesystems */
9651 			if ((rights & KAUTH_VNODE_WRITE_EXTATTRIBUTES) &&
9652 			    (vfs_flags(mp) & MNT_NOUSERXATTR)) {
9653 				KAUTH_DEBUG("%p    DENIED - filesystem disallowed extended attributes", vap);
9654 				error = EACCES;  /* User attributes disabled */
9655 				goto out;
9656 			}
9657 		}
9658 
9659 		/*
9660 		 * check for file immutability. first, check if the requested rights are
9661 		 * allowable for a UF_APPEND file.
9662 		 */
9663 		append = 0;
9664 		if (vap->va_type == VDIR) {
9665 			if ((rights & (KAUTH_VNODE_ADD_FILE | KAUTH_VNODE_ADD_SUBDIRECTORY | KAUTH_VNODE_WRITE_EXTATTRIBUTES | ~KAUTH_VNODE_WRITE_RIGHTS)) == rights) {
9666 				append = 1;
9667 			}
9668 		} else {
9669 			if ((rights & (KAUTH_VNODE_APPEND_DATA | KAUTH_VNODE_WRITE_EXTATTRIBUTES | ~KAUTH_VNODE_WRITE_RIGHTS)) == rights) {
9670 				append = 1;
9671 			}
9672 		}
9673 		if ((error = vnode_immutable(vap, append, ignore)) != 0) {
9674 			if (error && !ignore) {
9675 				/*
9676 				 * In case of a rename, we want to check ownership for dvp as well.
9677 				 */
9678 				int owner = 0;
9679 				if (rights & KAUTH_VNODE_DELETE_CHILD && vcp->dvp != NULL) {
9680 					owner = vauth_file_owner(vcp) && vauth_dir_owner(vcp);
9681 				} else {
9682 					owner = vauth_file_owner(vcp);
9683 				}
9684 				if (owner && proc_ignores_node_permissions(vfs_context_proc(vcp->ctx))) {
9685 					error = vnode_immutable(vap, append, 1);
9686 				}
9687 			}
9688 		}
9689 		if (error) {
9690 			KAUTH_DEBUG("%p    DENIED - file is immutable", vap);
9691 			goto out;
9692 		}
9693 	}
9694 out:
9695 	return error;
9696 }
9697 
9698 /*
9699  * Handle authorization actions for filesystems that advertise that the
9700  * server will be enforcing.
9701  *
9702  * Returns:	0			Authorization should be handled locally
9703  *		1			Authorization was handled by the FS
9704  *
9705  * Note:	Imputed returns will only occur if the authorization request
9706  *		was handled by the FS.
9707  *
9708  * Imputed:	*resultp, modified	Return code from FS when the request is
9709  *					handled by the FS.
9710  *		VNOP_ACCESS:???
9711  *		VNOP_OPEN:???
9712  */
9713 static int
vnode_authorize_opaque(vnode_t vp,int * resultp,kauth_action_t action,vfs_context_t ctx)9714 vnode_authorize_opaque(vnode_t vp, int *resultp, kauth_action_t action, vfs_context_t ctx)
9715 {
9716 	int     error;
9717 
9718 	/*
9719 	 * If the vp is a device node, socket or FIFO it actually represents a local
9720 	 * endpoint, so we need to handle it locally.
9721 	 */
9722 	switch (vp->v_type) {
9723 	case VBLK:
9724 	case VCHR:
9725 	case VSOCK:
9726 	case VFIFO:
9727 		return 0;
9728 	default:
9729 		break;
9730 	}
9731 
9732 	/*
9733 	 * In the advisory request case, if the filesystem doesn't think it's reliable
9734 	 * we will attempt to formulate a result ourselves based on VNOP_GETATTR data.
9735 	 */
9736 	if ((action & KAUTH_VNODE_ACCESS) && !vfs_authopaqueaccess(vp->v_mount)) {
9737 		return 0;
9738 	}
9739 
9740 	/*
9741 	 * Let the filesystem have a say in the matter.  It's OK for it to not implemnent
9742 	 * VNOP_ACCESS, as most will authorise inline with the actual request.
9743 	 */
9744 	if ((error = VNOP_ACCESS(vp, action, ctx)) != ENOTSUP) {
9745 		*resultp = error;
9746 		KAUTH_DEBUG("%p    DENIED - opaque filesystem VNOP_ACCESS denied access", vp);
9747 		return 1;
9748 	}
9749 
9750 	/*
9751 	 * Typically opaque filesystems do authorisation in-line, but exec is a special case.  In
9752 	 * order to be reasonably sure that exec will be permitted, we try a bit harder here.
9753 	 */
9754 	if ((action & KAUTH_VNODE_EXECUTE) && (vp->v_type == VREG)) {
9755 		/* try a VNOP_OPEN for readonly access */
9756 		if ((error = VNOP_OPEN(vp, FREAD, ctx)) != 0) {
9757 			*resultp = error;
9758 			KAUTH_DEBUG("%p    DENIED - EXECUTE denied because file could not be opened readonly", vp);
9759 			return 1;
9760 		}
9761 		VNOP_CLOSE(vp, FREAD, ctx);
9762 	}
9763 
9764 	/*
9765 	 * We don't have any reason to believe that the request has to be denied at this point,
9766 	 * so go ahead and allow it.
9767 	 */
9768 	*resultp = 0;
9769 	KAUTH_DEBUG("%p    ALLOWED - bypassing access check for non-local filesystem", vp);
9770 	return 1;
9771 }
9772 
9773 
9774 
9775 
9776 /*
9777  * Returns:	KAUTH_RESULT_ALLOW
9778  *		KAUTH_RESULT_DENY
9779  *
9780  * Imputed:	*arg3, modified		Error code in the deny case
9781  *		EROFS			Read-only file system
9782  *		EACCES			Permission denied
9783  *		EPERM			Operation not permitted [no execute]
9784  *	vnode_getattr:ENOMEM		Not enough space [only if has filesec]
9785  *	vnode_getattr:???
9786  *	vnode_authorize_opaque:*arg2	???
9787  *	vnode_authorize_checkimmutable:???
9788  *	vnode_authorize_delete:???
9789  *	vnode_authorize_simple:???
9790  */
9791 
9792 
9793 static int
vnode_authorize_callback(__unused kauth_cred_t cred,__unused void * idata,kauth_action_t action,uintptr_t arg0,uintptr_t arg1,uintptr_t arg2,uintptr_t arg3)9794 vnode_authorize_callback(__unused kauth_cred_t cred, __unused void *idata,
9795     kauth_action_t action, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2,
9796     uintptr_t arg3)
9797 {
9798 	vfs_context_t   ctx;
9799 	vnode_t         cvp = NULLVP;
9800 	vnode_t         vp, dvp;
9801 	int             result = KAUTH_RESULT_DENY;
9802 	int             parent_iocount = 0;
9803 	int             parent_action = 0; /* In case we need to use namedstream's data fork for cached rights*/
9804 
9805 	ctx = (vfs_context_t)arg0;
9806 	vp = (vnode_t)arg1;
9807 	dvp = (vnode_t)arg2;
9808 
9809 	/*
9810 	 * if there are 2 vnodes passed in, we don't know at
9811 	 * this point which rights to look at based on the
9812 	 * combined action being passed in... defer until later...
9813 	 * otherwise check the kauth 'rights' cache hung
9814 	 * off of the vnode we're interested in... if we've already
9815 	 * been granted the right we're currently interested in,
9816 	 * we can just return success... otherwise we'll go through
9817 	 * the process of authorizing the requested right(s)... if that
9818 	 * succeeds, we'll add the right(s) to the cache.
9819 	 * VNOP_SETATTR and VNOP_SETXATTR will invalidate this cache
9820 	 */
9821 	if (dvp && vp) {
9822 		goto defer;
9823 	}
9824 	if (dvp) {
9825 		cvp = dvp;
9826 	} else {
9827 		/*
9828 		 * For named streams on local-authorization volumes, rights are cached on the parent;
9829 		 * authorization is determined by looking at the parent's properties anyway, so storing
9830 		 * on the parent means that we don't recompute for the named stream and that if
9831 		 * we need to flush rights (e.g. on VNOP_SETATTR()) we don't need to track down the
9832 		 * stream to flush its cache separately.  If we miss in the cache, then we authorize
9833 		 * as if there were no cached rights (passing the named stream vnode and desired rights to
9834 		 * vnode_authorize_callback_int()).
9835 		 *
9836 		 * On an opaquely authorized volume, we don't know the relationship between the
9837 		 * data fork's properties and the rights granted on a stream.  Thus, named stream vnodes
9838 		 * on such a volume are authorized directly (rather than using the parent) and have their
9839 		 * own caches.  When a named stream vnode is created, we mark the parent as having a named
9840 		 * stream. On a VNOP_SETATTR() for the parent that may invalidate cached authorization, we
9841 		 * find the stream and flush its cache.
9842 		 */
9843 		if (vnode_isnamedstream(vp) && (!vfs_authopaque(vp->v_mount))) {
9844 			cvp = vnode_getparent(vp);
9845 			if (cvp != NULLVP) {
9846 				parent_iocount = 1;
9847 			} else {
9848 				cvp = NULL;
9849 				goto defer; /* If we can't use the parent, take the slow path */
9850 			}
9851 
9852 			/* Have to translate some actions */
9853 			parent_action = action;
9854 			if (parent_action & KAUTH_VNODE_READ_DATA) {
9855 				parent_action &= ~KAUTH_VNODE_READ_DATA;
9856 				parent_action |= KAUTH_VNODE_READ_EXTATTRIBUTES;
9857 			}
9858 			if (parent_action & KAUTH_VNODE_WRITE_DATA) {
9859 				parent_action &= ~KAUTH_VNODE_WRITE_DATA;
9860 				parent_action |= KAUTH_VNODE_WRITE_EXTATTRIBUTES;
9861 			}
9862 		} else {
9863 			cvp = vp;
9864 		}
9865 	}
9866 
9867 	if (vnode_cache_is_authorized(cvp, ctx, parent_iocount ? parent_action : action) == TRUE) {
9868 		result = KAUTH_RESULT_ALLOW;
9869 		goto out;
9870 	}
9871 defer:
9872 	result = vnode_authorize_callback_int(action, ctx, vp, dvp, (int *)arg3);
9873 
9874 	if (result == KAUTH_RESULT_ALLOW && cvp != NULLVP) {
9875 		KAUTH_DEBUG("%p - caching action = %x", cvp, action);
9876 		vnode_cache_authorized_action(cvp, ctx, action);
9877 	}
9878 
9879 out:
9880 	if (parent_iocount) {
9881 		vnode_put(cvp);
9882 	}
9883 
9884 	return result;
9885 }
9886 
9887 static int
vnode_attr_authorize_internal(vauth_ctx vcp,mount_t mp,kauth_ace_rights_t rights,int is_suser,boolean_t * found_deny,int noimmutable,int parent_authorized_for_delete_child)9888 vnode_attr_authorize_internal(vauth_ctx vcp, mount_t mp,
9889     kauth_ace_rights_t rights, int is_suser, boolean_t *found_deny,
9890     int noimmutable, int parent_authorized_for_delete_child)
9891 {
9892 	int result;
9893 
9894 	/*
9895 	 * Check for immutability.
9896 	 *
9897 	 * In the deletion case, parent directory immutability vetoes specific
9898 	 * file rights.
9899 	 */
9900 	if ((result = vnode_authorize_checkimmutable(mp, vcp, vcp->vap, rights,
9901 	    noimmutable)) != 0) {
9902 		goto out;
9903 	}
9904 
9905 	if ((rights & KAUTH_VNODE_DELETE) &&
9906 	    !parent_authorized_for_delete_child) {
9907 		result = vnode_authorize_checkimmutable(mp, vcp, vcp->dvap,
9908 		    KAUTH_VNODE_DELETE_CHILD, 0);
9909 		if (result) {
9910 			goto out;
9911 		}
9912 	}
9913 
9914 	/*
9915 	 * Clear rights that have been authorized by reaching this point, bail if nothing left to
9916 	 * check.
9917 	 */
9918 	rights &= ~(KAUTH_VNODE_LINKTARGET | KAUTH_VNODE_CHECKIMMUTABLE);
9919 	if (rights == 0) {
9920 		goto out;
9921 	}
9922 
9923 	/*
9924 	 * If we're not the superuser, authorize based on file properties;
9925 	 * note that even if parent_authorized_for_delete_child is TRUE, we
9926 	 * need to check on the node itself.
9927 	 */
9928 	if (!is_suser) {
9929 		/* process delete rights */
9930 		if ((rights & KAUTH_VNODE_DELETE) &&
9931 		    ((result = vnode_authorize_delete(vcp, parent_authorized_for_delete_child)) != 0)) {
9932 			goto out;
9933 		}
9934 
9935 		/* process remaining rights */
9936 		if ((rights & ~KAUTH_VNODE_DELETE) &&
9937 		    (result = vnode_authorize_simple(vcp, rights, rights & KAUTH_VNODE_DELETE, found_deny)) != 0) {
9938 			goto out;
9939 		}
9940 	} else {
9941 		/*
9942 		 * Execute is only granted to root if one of the x bits is set.  This check only
9943 		 * makes sense if the posix mode bits are actually supported.
9944 		 */
9945 		if ((rights & KAUTH_VNODE_EXECUTE) &&
9946 		    (vcp->vap->va_type == VREG) &&
9947 		    VATTR_IS_SUPPORTED(vcp->vap, va_mode) &&
9948 		    !(vcp->vap->va_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
9949 			result = EPERM;
9950 			KAUTH_DEBUG("%p    DENIED - root execute requires at least one x bit in 0x%x", vcp, vcp->vap->va_mode);
9951 			goto out;
9952 		}
9953 
9954 		/* Assume that there were DENYs so we don't wrongly cache KAUTH_VNODE_SEARCHBYANYONE */
9955 		*found_deny = TRUE;
9956 
9957 		KAUTH_DEBUG("%p    ALLOWED - caller is superuser", vcp);
9958 	}
9959 out:
9960 	return result;
9961 }
9962 
9963 static int
vnode_authorize_callback_int(kauth_action_t action,vfs_context_t ctx,vnode_t vp,vnode_t dvp,int * errorp)9964 vnode_authorize_callback_int(kauth_action_t action, vfs_context_t ctx,
9965     vnode_t vp, vnode_t dvp, int *errorp)
9966 {
9967 	struct _vnode_authorize_context auth_context;
9968 	vauth_ctx               vcp;
9969 	kauth_cred_t            cred;
9970 	kauth_ace_rights_t      rights;
9971 	struct vnode_attr       va, dva;
9972 	int                     result;
9973 	int                     noimmutable;
9974 	boolean_t               parent_authorized_for_delete_child = FALSE;
9975 	boolean_t               found_deny = FALSE;
9976 	boolean_t               parent_ref = FALSE;
9977 	boolean_t               is_suser = FALSE;
9978 
9979 	vcp = &auth_context;
9980 	vcp->ctx = ctx;
9981 	vcp->vp = vp;
9982 	vcp->dvp = dvp;
9983 	/*
9984 	 * Note that we authorize against the context, not the passed cred
9985 	 * (the same thing anyway)
9986 	 */
9987 	cred = ctx->vc_ucred;
9988 
9989 	VATTR_INIT(&va);
9990 	vcp->vap = &va;
9991 	VATTR_INIT(&dva);
9992 	vcp->dvap = &dva;
9993 
9994 	vcp->flags = vcp->flags_valid = 0;
9995 
9996 #if DIAGNOSTIC
9997 	if ((ctx == NULL) || (vp == NULL) || (cred == NULL)) {
9998 		panic("vnode_authorize: bad arguments (context %p  vp %p  cred %p)", ctx, vp, cred);
9999 	}
10000 #endif
10001 
10002 	KAUTH_DEBUG("%p  AUTH - %s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s on %s '%s' (0x%x:%p/%p)",
10003 	    vp, vfs_context_proc(ctx)->p_comm,
10004 	    (action & KAUTH_VNODE_ACCESS)               ? "access" : "auth",
10005 	    (action & KAUTH_VNODE_READ_DATA)            ? vnode_isdir(vp) ? " LIST_DIRECTORY" : " READ_DATA" : "",
10006 	    (action & KAUTH_VNODE_WRITE_DATA)           ? vnode_isdir(vp) ? " ADD_FILE" : " WRITE_DATA" : "",
10007 	    (action & KAUTH_VNODE_EXECUTE)              ? vnode_isdir(vp) ? " SEARCH" : " EXECUTE" : "",
10008 	    (action & KAUTH_VNODE_DELETE)               ? " DELETE" : "",
10009 	    (action & KAUTH_VNODE_APPEND_DATA)          ? vnode_isdir(vp) ? " ADD_SUBDIRECTORY" : " APPEND_DATA" : "",
10010 	    (action & KAUTH_VNODE_DELETE_CHILD)         ? " DELETE_CHILD" : "",
10011 	    (action & KAUTH_VNODE_READ_ATTRIBUTES)      ? " READ_ATTRIBUTES" : "",
10012 	    (action & KAUTH_VNODE_WRITE_ATTRIBUTES)     ? " WRITE_ATTRIBUTES" : "",
10013 	    (action & KAUTH_VNODE_READ_EXTATTRIBUTES)   ? " READ_EXTATTRIBUTES" : "",
10014 	    (action & KAUTH_VNODE_WRITE_EXTATTRIBUTES)  ? " WRITE_EXTATTRIBUTES" : "",
10015 	    (action & KAUTH_VNODE_READ_SECURITY)        ? " READ_SECURITY" : "",
10016 	    (action & KAUTH_VNODE_WRITE_SECURITY)       ? " WRITE_SECURITY" : "",
10017 	    (action & KAUTH_VNODE_CHANGE_OWNER)         ? " CHANGE_OWNER" : "",
10018 	    (action & KAUTH_VNODE_NOIMMUTABLE)          ? " (noimmutable)" : "",
10019 	    vnode_isdir(vp) ? "directory" : "file",
10020 	    vp->v_name ? vp->v_name : "<NULL>", action, vp, dvp);
10021 
10022 	/*
10023 	 * Extract the control bits from the action, everything else is
10024 	 * requested rights.
10025 	 */
10026 	noimmutable = (action & KAUTH_VNODE_NOIMMUTABLE) ? 1 : 0;
10027 	rights = action & ~(KAUTH_VNODE_ACCESS | KAUTH_VNODE_NOIMMUTABLE);
10028 
10029 	if (rights & KAUTH_VNODE_DELETE) {
10030 #if DIAGNOSTIC
10031 		if (dvp == NULL) {
10032 			panic("vnode_authorize: KAUTH_VNODE_DELETE test requires a directory");
10033 		}
10034 #endif
10035 		/*
10036 		 * check to see if we've already authorized the parent
10037 		 * directory for deletion of its children... if so, we
10038 		 * can skip a whole bunch of work... we will still have to
10039 		 * authorize that this specific child can be removed
10040 		 */
10041 		if (vnode_cache_is_authorized(dvp, ctx, KAUTH_VNODE_DELETE_CHILD) == TRUE) {
10042 			parent_authorized_for_delete_child = TRUE;
10043 		}
10044 	} else {
10045 		vcp->dvp = NULLVP;
10046 		vcp->dvap = NULL;
10047 	}
10048 
10049 	/*
10050 	 * Check for read-only filesystems.
10051 	 */
10052 	if ((rights & KAUTH_VNODE_WRITE_RIGHTS) &&
10053 	    (vp->v_mount->mnt_flag & MNT_RDONLY) &&
10054 	    ((vp->v_type == VREG) || (vp->v_type == VDIR) ||
10055 	    (vp->v_type == VLNK) || (vp->v_type == VCPLX) ||
10056 	    (rights & KAUTH_VNODE_DELETE) || (rights & KAUTH_VNODE_DELETE_CHILD))) {
10057 		result = EROFS;
10058 		goto out;
10059 	}
10060 
10061 	/*
10062 	 * Check for noexec filesystems.
10063 	 */
10064 	if ((rights & KAUTH_VNODE_EXECUTE) && (vp->v_type == VREG) && (vp->v_mount->mnt_flag & MNT_NOEXEC)) {
10065 		result = EACCES;
10066 		goto out;
10067 	}
10068 
10069 	/*
10070 	 * Handle cases related to filesystems with non-local enforcement.
10071 	 * This call can return 0, in which case we will fall through to perform a
10072 	 * check based on VNOP_GETATTR data.  Otherwise it returns 1 and sets
10073 	 * an appropriate result, at which point we can return immediately.
10074 	 */
10075 	if ((vp->v_mount->mnt_kern_flag & MNTK_AUTH_OPAQUE) && vnode_authorize_opaque(vp, &result, action, ctx)) {
10076 		goto out;
10077 	}
10078 
10079 	/*
10080 	 * If the vnode is a namedstream (extended attribute) data vnode (eg.
10081 	 * a resource fork), *_DATA becomes *_EXTATTRIBUTES.
10082 	 */
10083 	if (vnode_isnamedstream(vp)) {
10084 		if (rights & KAUTH_VNODE_READ_DATA) {
10085 			rights &= ~KAUTH_VNODE_READ_DATA;
10086 			rights |= KAUTH_VNODE_READ_EXTATTRIBUTES;
10087 		}
10088 		if (rights & KAUTH_VNODE_WRITE_DATA) {
10089 			rights &= ~KAUTH_VNODE_WRITE_DATA;
10090 			rights |= KAUTH_VNODE_WRITE_EXTATTRIBUTES;
10091 		}
10092 
10093 		/*
10094 		 * Point 'vp' to the namedstream's parent for ACL checking
10095 		 */
10096 		if ((vp->v_parent != NULL) &&
10097 		    (vget_internal(vp->v_parent, 0, VNODE_NODEAD | VNODE_DRAINO) == 0)) {
10098 			parent_ref = TRUE;
10099 			vcp->vp = vp = vp->v_parent;
10100 		}
10101 	}
10102 
10103 	if (vfs_context_issuser(ctx)) {
10104 		/*
10105 		 * if we're not asking for execute permissions or modifications,
10106 		 * then we're done, this action is authorized.
10107 		 */
10108 		if (!(rights & (KAUTH_VNODE_EXECUTE | KAUTH_VNODE_WRITE_RIGHTS))) {
10109 			goto success;
10110 		}
10111 
10112 		is_suser = TRUE;
10113 	}
10114 
10115 	/*
10116 	 * Get vnode attributes and extended security information for the vnode
10117 	 * and directory if required.
10118 	 *
10119 	 * If we're root we only want mode bits and flags for checking
10120 	 * execute and immutability.
10121 	 */
10122 	VATTR_WANTED(&va, va_mode);
10123 	VATTR_WANTED(&va, va_flags);
10124 	if (!is_suser) {
10125 		VATTR_WANTED(&va, va_uid);
10126 		VATTR_WANTED(&va, va_gid);
10127 		VATTR_WANTED(&va, va_acl);
10128 	}
10129 	if ((result = vnode_getattr(vp, &va, ctx)) != 0) {
10130 		KAUTH_DEBUG("%p    ERROR - failed to get vnode attributes - %d", vp, result);
10131 		goto out;
10132 	}
10133 	VATTR_WANTED(&va, va_type);
10134 	VATTR_RETURN(&va, va_type, vnode_vtype(vp));
10135 
10136 	if (vcp->dvp) {
10137 		VATTR_WANTED(&dva, va_mode);
10138 		VATTR_WANTED(&dva, va_flags);
10139 		if (!is_suser) {
10140 			VATTR_WANTED(&dva, va_uid);
10141 			VATTR_WANTED(&dva, va_gid);
10142 			VATTR_WANTED(&dva, va_acl);
10143 		}
10144 		if ((result = vnode_getattr(vcp->dvp, &dva, ctx)) != 0) {
10145 			KAUTH_DEBUG("%p    ERROR - failed to get directory vnode attributes - %d", vp, result);
10146 			goto out;
10147 		}
10148 		VATTR_WANTED(&dva, va_type);
10149 		VATTR_RETURN(&dva, va_type, vnode_vtype(vcp->dvp));
10150 	}
10151 
10152 	result = vnode_attr_authorize_internal(vcp, vp->v_mount, rights, is_suser,
10153 	    &found_deny, noimmutable, parent_authorized_for_delete_child);
10154 out:
10155 	if (VATTR_IS_SUPPORTED(&va, va_acl) && (va.va_acl != NULL)) {
10156 		kauth_acl_free(va.va_acl);
10157 	}
10158 	if (VATTR_IS_SUPPORTED(&dva, va_acl) && (dva.va_acl != NULL)) {
10159 		kauth_acl_free(dva.va_acl);
10160 	}
10161 
10162 	if (result) {
10163 		if (parent_ref) {
10164 			vnode_put(vp);
10165 		}
10166 		*errorp = result;
10167 		KAUTH_DEBUG("%p    DENIED - auth denied", vp);
10168 		return KAUTH_RESULT_DENY;
10169 	}
10170 	if ((rights & KAUTH_VNODE_SEARCH) && found_deny == FALSE && vp->v_type == VDIR) {
10171 		/*
10172 		 * if we were successfully granted the right to search this directory
10173 		 * and there were NO ACL DENYs for search and the posix permissions also don't
10174 		 * deny execute, we can synthesize a global right that allows anyone to
10175 		 * traverse this directory during a pathname lookup without having to
10176 		 * match the credential associated with this cache of rights.
10177 		 *
10178 		 * Note that we can correctly cache KAUTH_VNODE_SEARCHBYANYONE
10179 		 * only if we actually check ACLs which we don't for root. As
10180 		 * a workaround, the lookup fast path checks for root.
10181 		 */
10182 		if (!VATTR_IS_SUPPORTED(&va, va_mode) ||
10183 		    ((va.va_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) ==
10184 		    (S_IXUSR | S_IXGRP | S_IXOTH))) {
10185 			vnode_cache_authorized_action(vp, ctx, KAUTH_VNODE_SEARCHBYANYONE);
10186 		}
10187 	}
10188 success:
10189 	if (parent_ref) {
10190 		vnode_put(vp);
10191 	}
10192 
10193 	/*
10194 	 * Note that this implies that we will allow requests for no rights, as well as
10195 	 * for rights that we do not recognise.  There should be none of these.
10196 	 */
10197 	KAUTH_DEBUG("%p    ALLOWED - auth granted", vp);
10198 	return KAUTH_RESULT_ALLOW;
10199 }
10200 
10201 int
vnode_attr_authorize_init(struct vnode_attr * vap,struct vnode_attr * dvap,kauth_action_t action,vfs_context_t ctx)10202 vnode_attr_authorize_init(struct vnode_attr *vap, struct vnode_attr *dvap,
10203     kauth_action_t action, vfs_context_t ctx)
10204 {
10205 	VATTR_INIT(vap);
10206 	VATTR_WANTED(vap, va_type);
10207 	VATTR_WANTED(vap, va_mode);
10208 	VATTR_WANTED(vap, va_flags);
10209 	if (dvap) {
10210 		VATTR_INIT(dvap);
10211 		if (action & KAUTH_VNODE_DELETE) {
10212 			VATTR_WANTED(dvap, va_type);
10213 			VATTR_WANTED(dvap, va_mode);
10214 			VATTR_WANTED(dvap, va_flags);
10215 		}
10216 	} else if (action & KAUTH_VNODE_DELETE) {
10217 		return EINVAL;
10218 	}
10219 
10220 	if (!vfs_context_issuser(ctx)) {
10221 		VATTR_WANTED(vap, va_uid);
10222 		VATTR_WANTED(vap, va_gid);
10223 		VATTR_WANTED(vap, va_acl);
10224 		if (dvap && (action & KAUTH_VNODE_DELETE)) {
10225 			VATTR_WANTED(dvap, va_uid);
10226 			VATTR_WANTED(dvap, va_gid);
10227 			VATTR_WANTED(dvap, va_acl);
10228 		}
10229 	}
10230 
10231 	return 0;
10232 }
10233 
10234 #define VNODE_SEC_ATTRS_NO_ACL (VNODE_ATTR_va_uid | VNODE_ATTR_va_gid | VNODE_ATTR_va_mode | VNODE_ATTR_va_flags | VNODE_ATTR_va_type)
10235 
10236 int
vnode_attr_authorize(struct vnode_attr * vap,struct vnode_attr * dvap,mount_t mp,kauth_action_t action,vfs_context_t ctx)10237 vnode_attr_authorize(struct vnode_attr *vap, struct vnode_attr *dvap, mount_t mp,
10238     kauth_action_t action, vfs_context_t ctx)
10239 {
10240 	struct _vnode_authorize_context auth_context;
10241 	vauth_ctx vcp;
10242 	kauth_ace_rights_t rights;
10243 	int noimmutable;
10244 	boolean_t found_deny;
10245 	boolean_t is_suser = FALSE;
10246 	int result = 0;
10247 	uid_t ouid = vap->va_uid;
10248 	gid_t ogid = vap->va_gid;
10249 
10250 	vcp = &auth_context;
10251 	vcp->ctx = ctx;
10252 	vcp->vp = NULLVP;
10253 	vcp->vap = vap;
10254 	vcp->dvp = NULLVP;
10255 	vcp->dvap = dvap;
10256 	vcp->flags = vcp->flags_valid = 0;
10257 
10258 	noimmutable = (action & KAUTH_VNODE_NOIMMUTABLE) ? 1 : 0;
10259 	rights = action & ~(KAUTH_VNODE_ACCESS | KAUTH_VNODE_NOIMMUTABLE);
10260 
10261 	/*
10262 	 * Check for read-only filesystems.
10263 	 */
10264 	if ((rights & KAUTH_VNODE_WRITE_RIGHTS) &&
10265 	    mp && (mp->mnt_flag & MNT_RDONLY) &&
10266 	    ((vap->va_type == VREG) || (vap->va_type == VDIR) ||
10267 	    (vap->va_type == VLNK) || (rights & KAUTH_VNODE_DELETE) ||
10268 	    (rights & KAUTH_VNODE_DELETE_CHILD))) {
10269 		result = EROFS;
10270 		goto out;
10271 	}
10272 
10273 	/*
10274 	 * Check for noexec filesystems.
10275 	 */
10276 	if ((rights & KAUTH_VNODE_EXECUTE) &&
10277 	    (vap->va_type == VREG) && mp && (mp->mnt_flag & MNT_NOEXEC)) {
10278 		result = EACCES;
10279 		goto out;
10280 	}
10281 
10282 	if (vfs_context_issuser(ctx)) {
10283 		/*
10284 		 * if we're not asking for execute permissions or modifications,
10285 		 * then we're done, this action is authorized.
10286 		 */
10287 		if (!(rights & (KAUTH_VNODE_EXECUTE | KAUTH_VNODE_WRITE_RIGHTS))) {
10288 			goto out;
10289 		}
10290 		is_suser = TRUE;
10291 	}
10292 
10293 	if (mp) {
10294 		if (vfs_extendedsecurity(mp) && VATTR_IS_ACTIVE(vap, va_acl) && !VATTR_IS_SUPPORTED(vap, va_acl)) {
10295 			panic("(1) vnode attrs not complete for vnode_attr_authorize");
10296 		}
10297 		vnode_attr_handle_uid_and_gid(vap, mp, ctx);
10298 	}
10299 
10300 	if ((vap->va_active & VNODE_SEC_ATTRS_NO_ACL) != (vap->va_supported & VNODE_SEC_ATTRS_NO_ACL)) {
10301 		panic("(2) vnode attrs not complete for vnode_attr_authorize (2) vap->va_active = 0x%llx , vap->va_supported = 0x%llx",
10302 		    vap->va_active, vap->va_supported);
10303 	}
10304 
10305 	result = vnode_attr_authorize_internal(vcp, mp, rights, is_suser,
10306 	    &found_deny, noimmutable, FALSE);
10307 
10308 	if (mp) {
10309 		vap->va_uid = ouid;
10310 		vap->va_gid = ogid;
10311 	}
10312 
10313 	if (result == EPERM) {
10314 		result = EACCES;
10315 	}
10316 out:
10317 	return result;
10318 }
10319 
10320 
10321 int
vnode_authattr_new(vnode_t dvp,struct vnode_attr * vap,int noauth,vfs_context_t ctx)10322 vnode_authattr_new(vnode_t dvp, struct vnode_attr *vap, int noauth, vfs_context_t ctx)
10323 {
10324 	return vnode_authattr_new_internal(dvp, vap, noauth, NULL, ctx);
10325 }
10326 
10327 /*
10328  * Check that the attribute information in vattr can be legally applied to
10329  * a new file by the context.
10330  */
10331 static int
vnode_authattr_new_internal(vnode_t dvp,struct vnode_attr * vap,int noauth,uint32_t * defaulted_fieldsp,vfs_context_t ctx)10332 vnode_authattr_new_internal(vnode_t dvp, struct vnode_attr *vap, int noauth, uint32_t *defaulted_fieldsp, vfs_context_t ctx)
10333 {
10334 	int             error;
10335 	int             has_priv_suser, ismember, defaulted_owner, defaulted_group, defaulted_mode;
10336 	uint32_t        inherit_flags;
10337 	kauth_cred_t    cred;
10338 	guid_t          changer;
10339 	mount_t         dmp;
10340 	struct vnode_attr dva;
10341 
10342 	error = 0;
10343 
10344 	if (defaulted_fieldsp) {
10345 		*defaulted_fieldsp = 0;
10346 	}
10347 
10348 	defaulted_owner = defaulted_group = defaulted_mode = 0;
10349 
10350 	inherit_flags = 0;
10351 
10352 	/*
10353 	 * Require that the filesystem support extended security to apply any.
10354 	 */
10355 	if (!vfs_extendedsecurity(dvp->v_mount) &&
10356 	    (VATTR_IS_ACTIVE(vap, va_acl) || VATTR_IS_ACTIVE(vap, va_uuuid) || VATTR_IS_ACTIVE(vap, va_guuid))) {
10357 		error = EINVAL;
10358 		goto out;
10359 	}
10360 
10361 	/*
10362 	 * Default some fields.
10363 	 */
10364 	dmp = dvp->v_mount;
10365 
10366 	/*
10367 	 * If the filesystem is mounted IGNORE_OWNERSHIP and an explicit owner is set, that
10368 	 * owner takes ownership of all new files.
10369 	 */
10370 	if ((dmp->mnt_flag & MNT_IGNORE_OWNERSHIP) && (dmp->mnt_fsowner != KAUTH_UID_NONE)) {
10371 		VATTR_SET(vap, va_uid, dmp->mnt_fsowner);
10372 		defaulted_owner = 1;
10373 	} else {
10374 		if (!VATTR_IS_ACTIVE(vap, va_uid)) {
10375 			/* default owner is current user */
10376 			VATTR_SET(vap, va_uid, kauth_cred_getuid(vfs_context_ucred(ctx)));
10377 			defaulted_owner = 1;
10378 		}
10379 	}
10380 
10381 	/*
10382 	 * We need the dvp's va_flags and *may* need the gid of the directory,
10383 	 * we ask for both here.
10384 	 */
10385 	VATTR_INIT(&dva);
10386 	VATTR_WANTED(&dva, va_gid);
10387 	VATTR_WANTED(&dva, va_flags);
10388 	if ((error = vnode_getattr(dvp, &dva, ctx)) != 0) {
10389 		goto out;
10390 	}
10391 
10392 	/*
10393 	 * If the filesystem is mounted IGNORE_OWNERSHIP and an explicit grouo is set, that
10394 	 * group takes ownership of all new files.
10395 	 */
10396 	if ((dmp->mnt_flag & MNT_IGNORE_OWNERSHIP) && (dmp->mnt_fsgroup != KAUTH_GID_NONE)) {
10397 		VATTR_SET(vap, va_gid, dmp->mnt_fsgroup);
10398 		defaulted_group = 1;
10399 	} else {
10400 		if (!VATTR_IS_ACTIVE(vap, va_gid)) {
10401 			/* default group comes from parent object, fallback to current user */
10402 			if (VATTR_IS_SUPPORTED(&dva, va_gid)) {
10403 				VATTR_SET(vap, va_gid, dva.va_gid);
10404 			} else {
10405 				VATTR_SET(vap, va_gid, kauth_cred_getgid(vfs_context_ucred(ctx)));
10406 			}
10407 			defaulted_group = 1;
10408 		}
10409 	}
10410 
10411 	if (!VATTR_IS_ACTIVE(vap, va_flags)) {
10412 		VATTR_SET(vap, va_flags, 0);
10413 	}
10414 
10415 	/* Determine if SF_RESTRICTED should be inherited from the parent
10416 	 * directory. */
10417 	if (VATTR_IS_SUPPORTED(&dva, va_flags)) {
10418 		inherit_flags = dva.va_flags & (UF_DATAVAULT | SF_RESTRICTED);
10419 	}
10420 
10421 	/* default mode is everything, masked with current umask */
10422 	if (!VATTR_IS_ACTIVE(vap, va_mode)) {
10423 		VATTR_SET(vap, va_mode, ACCESSPERMS & ~vfs_context_proc(ctx)->p_fd.fd_cmask);
10424 		KAUTH_DEBUG("ATTR - defaulting new file mode to %o from umask %o",
10425 		    vap->va_mode, vfs_context_proc(ctx)->p_fd.fd_cmask);
10426 		defaulted_mode = 1;
10427 	}
10428 	/* set timestamps to now */
10429 	if (!VATTR_IS_ACTIVE(vap, va_create_time)) {
10430 		nanotime(&vap->va_create_time);
10431 		VATTR_SET_ACTIVE(vap, va_create_time);
10432 	}
10433 
10434 	/*
10435 	 * Check for attempts to set nonsensical fields.
10436 	 */
10437 	if (vap->va_active & ~VNODE_ATTR_NEWOBJ) {
10438 		error = EINVAL;
10439 		KAUTH_DEBUG("ATTR - ERROR - attempt to set unsupported new-file attributes %llx",
10440 		    vap->va_active & ~VNODE_ATTR_NEWOBJ);
10441 		goto out;
10442 	}
10443 
10444 	/*
10445 	 * Quickly check for the applicability of any enforcement here.
10446 	 * Tests below maintain the integrity of the local security model.
10447 	 */
10448 	if (vfs_authopaque(dvp->v_mount)) {
10449 		goto out;
10450 	}
10451 
10452 	/*
10453 	 * We need to know if the caller is the superuser, or if the work is
10454 	 * otherwise already authorised.
10455 	 */
10456 	cred = vfs_context_ucred(ctx);
10457 	if (noauth) {
10458 		/* doing work for the kernel */
10459 		has_priv_suser = 1;
10460 	} else {
10461 		has_priv_suser = vfs_context_issuser(ctx);
10462 	}
10463 
10464 
10465 	if (VATTR_IS_ACTIVE(vap, va_flags)) {
10466 		vap->va_flags &= ~SF_SYNTHETIC;
10467 		if (has_priv_suser) {
10468 			if ((vap->va_flags & (UF_SETTABLE | SF_SETTABLE)) != vap->va_flags) {
10469 				error = EPERM;
10470 				KAUTH_DEBUG("  DENIED - superuser attempt to set illegal flag(s)");
10471 				goto out;
10472 			}
10473 		} else {
10474 			if ((vap->va_flags & UF_SETTABLE) != vap->va_flags) {
10475 				error = EPERM;
10476 				KAUTH_DEBUG("  DENIED - user attempt to set illegal flag(s)");
10477 				goto out;
10478 			}
10479 		}
10480 	}
10481 
10482 	/* if not superuser, validate legality of new-item attributes */
10483 	if (!has_priv_suser) {
10484 		if (!defaulted_mode && VATTR_IS_ACTIVE(vap, va_mode)) {
10485 			/* setgid? */
10486 			if (vap->va_mode & S_ISGID) {
10487 				if ((error = kauth_cred_ismember_gid(cred, vap->va_gid, &ismember)) != 0) {
10488 					KAUTH_DEBUG("ATTR - ERROR: got %d checking for membership in %d", error, vap->va_gid);
10489 					goto out;
10490 				}
10491 				if (!ismember) {
10492 					KAUTH_DEBUG("  DENIED - can't set SGID bit, not a member of %d", vap->va_gid);
10493 					error = EPERM;
10494 					goto out;
10495 				}
10496 			}
10497 
10498 			/* setuid? */
10499 			if ((vap->va_mode & S_ISUID) && (vap->va_uid != kauth_cred_getuid(cred))) {
10500 				KAUTH_DEBUG("ATTR - ERROR: illegal attempt to set the setuid bit");
10501 				error = EPERM;
10502 				goto out;
10503 			}
10504 		}
10505 		if (!defaulted_owner && (vap->va_uid != kauth_cred_getuid(cred))) {
10506 			KAUTH_DEBUG("  DENIED - cannot create new item owned by %d", vap->va_uid);
10507 			error = EPERM;
10508 			goto out;
10509 		}
10510 		if (!defaulted_group) {
10511 			if ((error = kauth_cred_ismember_gid(cred, vap->va_gid, &ismember)) != 0) {
10512 				KAUTH_DEBUG("  ERROR - got %d checking for membership in %d", error, vap->va_gid);
10513 				goto out;
10514 			}
10515 			if (!ismember) {
10516 				KAUTH_DEBUG("  DENIED - cannot create new item with group %d - not a member", vap->va_gid);
10517 				error = EPERM;
10518 				goto out;
10519 			}
10520 		}
10521 
10522 		/* initialising owner/group UUID */
10523 		if (VATTR_IS_ACTIVE(vap, va_uuuid)) {
10524 			if ((error = kauth_cred_getguid(cred, &changer)) != 0) {
10525 				KAUTH_DEBUG("  ERROR - got %d trying to get caller UUID", error);
10526 				/* XXX ENOENT here - no GUID - should perhaps become EPERM */
10527 				goto out;
10528 			}
10529 			if (!kauth_guid_equal(&vap->va_uuuid, &changer)) {
10530 				KAUTH_DEBUG("  ERROR - cannot create item with supplied owner UUID - not us");
10531 				error = EPERM;
10532 				goto out;
10533 			}
10534 		}
10535 		if (VATTR_IS_ACTIVE(vap, va_guuid)) {
10536 			if ((error = kauth_cred_ismember_guid(cred, &vap->va_guuid, &ismember)) != 0) {
10537 				KAUTH_DEBUG("  ERROR - got %d trying to check group membership", error);
10538 				goto out;
10539 			}
10540 			if (!ismember) {
10541 				KAUTH_DEBUG("  ERROR - cannot create item with supplied group UUID - not a member");
10542 				error = EPERM;
10543 				goto out;
10544 			}
10545 		}
10546 	}
10547 out:
10548 	if (inherit_flags) {
10549 		/* Apply SF_RESTRICTED to the file if its parent directory was
10550 		 * restricted.  This is done at the end so that root is not
10551 		 * required if this flag is only set due to inheritance. */
10552 		VATTR_SET(vap, va_flags, (vap->va_flags | inherit_flags));
10553 	}
10554 	if (defaulted_fieldsp) {
10555 		if (defaulted_mode) {
10556 			*defaulted_fieldsp |= VATTR_PREPARE_DEFAULTED_MODE;
10557 		}
10558 		if (defaulted_group) {
10559 			*defaulted_fieldsp |= VATTR_PREPARE_DEFAULTED_GID;
10560 		}
10561 		if (defaulted_owner) {
10562 			*defaulted_fieldsp |= VATTR_PREPARE_DEFAULTED_UID;
10563 		}
10564 	}
10565 	return error;
10566 }
10567 
10568 /*
10569  * Check that the attribute information in vap can be legally written by the
10570  * context.
10571  *
10572  * Call this when you're not sure about the vnode_attr; either its contents
10573  * have come from an unknown source, or when they are variable.
10574  *
10575  * Returns errno, or zero and sets *actionp to the KAUTH_VNODE_* actions that
10576  * must be authorized to be permitted to write the vattr.
10577  */
10578 int
vnode_authattr(vnode_t vp,struct vnode_attr * vap,kauth_action_t * actionp,vfs_context_t ctx)10579 vnode_authattr(vnode_t vp, struct vnode_attr *vap, kauth_action_t *actionp, vfs_context_t ctx)
10580 {
10581 	struct vnode_attr ova;
10582 	kauth_action_t  required_action;
10583 	int             error, has_priv_suser, ismember, chowner, chgroup, clear_suid, clear_sgid;
10584 	guid_t          changer;
10585 	gid_t           group;
10586 	uid_t           owner;
10587 	mode_t          newmode;
10588 	kauth_cred_t    cred;
10589 	uint32_t        fdelta;
10590 
10591 	VATTR_INIT(&ova);
10592 	required_action = 0;
10593 	error = 0;
10594 
10595 	/*
10596 	 * Quickly check for enforcement applicability.
10597 	 */
10598 	if (vfs_authopaque(vp->v_mount)) {
10599 		goto out;
10600 	}
10601 
10602 	/*
10603 	 * Check for attempts to set nonsensical fields.
10604 	 */
10605 	if (vap->va_active & VNODE_ATTR_RDONLY) {
10606 		KAUTH_DEBUG("ATTR - ERROR: attempt to set readonly attribute(s)");
10607 		error = EINVAL;
10608 		goto out;
10609 	}
10610 
10611 	/*
10612 	 * We need to know if the caller is the superuser.
10613 	 */
10614 	cred = vfs_context_ucred(ctx);
10615 	has_priv_suser = kauth_cred_issuser(cred);
10616 
10617 	/*
10618 	 * If any of the following are changing, we need information from the old file:
10619 	 * va_uid
10620 	 * va_gid
10621 	 * va_mode
10622 	 * va_uuuid
10623 	 * va_guuid
10624 	 */
10625 	if (VATTR_IS_ACTIVE(vap, va_uid) ||
10626 	    VATTR_IS_ACTIVE(vap, va_gid) ||
10627 	    VATTR_IS_ACTIVE(vap, va_mode) ||
10628 	    VATTR_IS_ACTIVE(vap, va_uuuid) ||
10629 	    VATTR_IS_ACTIVE(vap, va_guuid)) {
10630 		VATTR_WANTED(&ova, va_mode);
10631 		VATTR_WANTED(&ova, va_uid);
10632 		VATTR_WANTED(&ova, va_gid);
10633 		VATTR_WANTED(&ova, va_uuuid);
10634 		VATTR_WANTED(&ova, va_guuid);
10635 		KAUTH_DEBUG("ATTR - security information changing, fetching existing attributes");
10636 	}
10637 
10638 	/*
10639 	 * If timestamps are being changed, we need to know who the file is owned
10640 	 * by.
10641 	 */
10642 	if (VATTR_IS_ACTIVE(vap, va_create_time) ||
10643 	    VATTR_IS_ACTIVE(vap, va_change_time) ||
10644 	    VATTR_IS_ACTIVE(vap, va_modify_time) ||
10645 	    VATTR_IS_ACTIVE(vap, va_access_time) ||
10646 	    VATTR_IS_ACTIVE(vap, va_backup_time) ||
10647 	    VATTR_IS_ACTIVE(vap, va_addedtime)) {
10648 		VATTR_WANTED(&ova, va_uid);
10649 #if 0   /* enable this when we support UUIDs as official owners */
10650 		VATTR_WANTED(&ova, va_uuuid);
10651 #endif
10652 		KAUTH_DEBUG("ATTR - timestamps changing, fetching uid and GUID");
10653 	}
10654 
10655 	/*
10656 	 * If flags are being changed, we need the old flags.
10657 	 */
10658 	if (VATTR_IS_ACTIVE(vap, va_flags)) {
10659 		KAUTH_DEBUG("ATTR - flags changing, fetching old flags");
10660 		VATTR_WANTED(&ova, va_flags);
10661 	}
10662 
10663 	/*
10664 	 * If ACLs are being changed, we need the old ACLs.
10665 	 */
10666 	if (VATTR_IS_ACTIVE(vap, va_acl)) {
10667 		KAUTH_DEBUG("ATTR - acl changing, fetching old flags");
10668 		VATTR_WANTED(&ova, va_acl);
10669 	}
10670 
10671 	/*
10672 	 * If the size is being set, make sure it's not a directory.
10673 	 */
10674 	if (VATTR_IS_ACTIVE(vap, va_data_size)) {
10675 		/* size is only meaningful on regular files, don't permit otherwise */
10676 		if (!vnode_isreg(vp)) {
10677 			KAUTH_DEBUG("ATTR - ERROR: size change requested on non-file");
10678 			error = vnode_isdir(vp) ? EISDIR : EINVAL;
10679 			goto out;
10680 		}
10681 	}
10682 
10683 	/*
10684 	 * Get old data.
10685 	 */
10686 	KAUTH_DEBUG("ATTR - fetching old attributes %016llx", ova.va_active);
10687 	if ((error = vnode_getattr(vp, &ova, ctx)) != 0) {
10688 		KAUTH_DEBUG("  ERROR - got %d trying to get attributes", error);
10689 		goto out;
10690 	}
10691 
10692 	/*
10693 	 * Size changes require write access to the file data.
10694 	 */
10695 	if (VATTR_IS_ACTIVE(vap, va_data_size)) {
10696 		/* if we can't get the size, or it's different, we need write access */
10697 		KAUTH_DEBUG("ATTR - size change, requiring WRITE_DATA");
10698 		required_action |= KAUTH_VNODE_WRITE_DATA;
10699 	}
10700 
10701 	/*
10702 	 * Changing timestamps?
10703 	 *
10704 	 * Note that we are only called to authorize user-requested time changes;
10705 	 * side-effect time changes are not authorized.  Authorisation is only
10706 	 * required for existing files.
10707 	 *
10708 	 * Non-owners are not permitted to change the time on an existing
10709 	 * file to anything other than the current time.
10710 	 */
10711 	if (VATTR_IS_ACTIVE(vap, va_create_time) ||
10712 	    VATTR_IS_ACTIVE(vap, va_change_time) ||
10713 	    VATTR_IS_ACTIVE(vap, va_modify_time) ||
10714 	    VATTR_IS_ACTIVE(vap, va_access_time) ||
10715 	    VATTR_IS_ACTIVE(vap, va_backup_time) ||
10716 	    VATTR_IS_ACTIVE(vap, va_addedtime)) {
10717 		/*
10718 		 * The owner and root may set any timestamps they like,
10719 		 * provided that the file is not immutable.  The owner still needs
10720 		 * WRITE_ATTRIBUTES (implied by ownership but still deniable).
10721 		 */
10722 		if (has_priv_suser || vauth_node_owner(&ova, cred)) {
10723 			KAUTH_DEBUG("ATTR - root or owner changing timestamps");
10724 			required_action |= KAUTH_VNODE_CHECKIMMUTABLE | KAUTH_VNODE_WRITE_ATTRIBUTES;
10725 		} else {
10726 			/* just setting the current time? */
10727 			if (vap->va_vaflags & VA_UTIMES_NULL) {
10728 				KAUTH_DEBUG("ATTR - non-root/owner changing timestamps, requiring WRITE_ATTRIBUTES");
10729 				required_action |= KAUTH_VNODE_WRITE_ATTRIBUTES;
10730 			} else {
10731 				KAUTH_DEBUG("ATTR - ERROR: illegal timestamp modification attempted");
10732 				error = EACCES;
10733 				goto out;
10734 			}
10735 		}
10736 	}
10737 
10738 	/*
10739 	 * Changing file mode?
10740 	 */
10741 	if (VATTR_IS_ACTIVE(vap, va_mode) && VATTR_IS_SUPPORTED(&ova, va_mode) && (ova.va_mode != vap->va_mode)) {
10742 		KAUTH_DEBUG("ATTR - mode change from %06o to %06o", ova.va_mode, vap->va_mode);
10743 
10744 		/*
10745 		 * Mode changes always have the same basic auth requirements.
10746 		 */
10747 		if (has_priv_suser) {
10748 			KAUTH_DEBUG("ATTR - superuser mode change, requiring immutability check");
10749 			required_action |= KAUTH_VNODE_CHECKIMMUTABLE;
10750 		} else {
10751 			/* need WRITE_SECURITY */
10752 			KAUTH_DEBUG("ATTR - non-superuser mode change, requiring WRITE_SECURITY");
10753 			required_action |= KAUTH_VNODE_WRITE_SECURITY;
10754 		}
10755 
10756 		/*
10757 		 * Can't set the setgid bit if you're not in the group and not root.  Have to have
10758 		 * existing group information in the case we're not setting it right now.
10759 		 */
10760 		if (vap->va_mode & S_ISGID) {
10761 			required_action |= KAUTH_VNODE_CHECKIMMUTABLE;  /* always required */
10762 			if (!has_priv_suser) {
10763 				if (VATTR_IS_ACTIVE(vap, va_gid)) {
10764 					group = vap->va_gid;
10765 				} else if (VATTR_IS_SUPPORTED(&ova, va_gid)) {
10766 					group = ova.va_gid;
10767 				} else {
10768 					KAUTH_DEBUG("ATTR - ERROR: setgid but no gid available");
10769 					error = EINVAL;
10770 					goto out;
10771 				}
10772 				/*
10773 				 * This might be too restrictive; WRITE_SECURITY might be implied by
10774 				 * membership in this case, rather than being an additional requirement.
10775 				 */
10776 				if ((error = kauth_cred_ismember_gid(cred, group, &ismember)) != 0) {
10777 					KAUTH_DEBUG("ATTR - ERROR: got %d checking for membership in %d", error, vap->va_gid);
10778 					goto out;
10779 				}
10780 				if (!ismember) {
10781 					KAUTH_DEBUG("  DENIED - can't set SGID bit, not a member of %d", group);
10782 					error = EPERM;
10783 					goto out;
10784 				}
10785 			}
10786 		}
10787 
10788 		/*
10789 		 * Can't set the setuid bit unless you're root or the file's owner.
10790 		 */
10791 		if (vap->va_mode & S_ISUID) {
10792 			required_action |= KAUTH_VNODE_CHECKIMMUTABLE;  /* always required */
10793 			if (!has_priv_suser) {
10794 				if (VATTR_IS_ACTIVE(vap, va_uid)) {
10795 					owner = vap->va_uid;
10796 				} else if (VATTR_IS_SUPPORTED(&ova, va_uid)) {
10797 					owner = ova.va_uid;
10798 				} else {
10799 					KAUTH_DEBUG("ATTR - ERROR: setuid but no uid available");
10800 					error = EINVAL;
10801 					goto out;
10802 				}
10803 				if (owner != kauth_cred_getuid(cred)) {
10804 					/*
10805 					 * We could allow this if WRITE_SECURITY is permitted, perhaps.
10806 					 */
10807 					KAUTH_DEBUG("ATTR - ERROR: illegal attempt to set the setuid bit");
10808 					error = EPERM;
10809 					goto out;
10810 				}
10811 			}
10812 		}
10813 	}
10814 
10815 	/*
10816 	 * Validate/mask flags changes.  This checks that only the flags in
10817 	 * the UF_SETTABLE mask are being set, and preserves the flags in
10818 	 * the SF_SETTABLE case.
10819 	 *
10820 	 * Since flags changes may be made in conjunction with other changes,
10821 	 * we will ask the auth code to ignore immutability in the case that
10822 	 * the SF_* flags are not set and we are only manipulating the file flags.
10823 	 *
10824 	 */
10825 	if (VATTR_IS_ACTIVE(vap, va_flags)) {
10826 		/* compute changing flags bits */
10827 		vap->va_flags &= ~SF_SYNTHETIC;
10828 		ova.va_flags &= ~SF_SYNTHETIC;
10829 		if (VATTR_IS_SUPPORTED(&ova, va_flags)) {
10830 			fdelta = vap->va_flags ^ ova.va_flags;
10831 		} else {
10832 			fdelta = vap->va_flags;
10833 		}
10834 
10835 		if (fdelta != 0) {
10836 			KAUTH_DEBUG("ATTR - flags changing, requiring WRITE_SECURITY");
10837 			required_action |= KAUTH_VNODE_WRITE_SECURITY;
10838 
10839 			/* check that changing bits are legal */
10840 			if (has_priv_suser) {
10841 				/*
10842 				 * The immutability check will prevent us from clearing the SF_*
10843 				 * flags unless the system securelevel permits it, so just check
10844 				 * for legal flags here.
10845 				 */
10846 				if (fdelta & ~(UF_SETTABLE | SF_SETTABLE)) {
10847 					error = EPERM;
10848 					KAUTH_DEBUG("  DENIED - superuser attempt to set illegal flag(s)");
10849 					goto out;
10850 				}
10851 			} else {
10852 				if (fdelta & ~UF_SETTABLE) {
10853 					error = EPERM;
10854 					KAUTH_DEBUG("  DENIED - user attempt to set illegal flag(s)");
10855 					goto out;
10856 				}
10857 			}
10858 			/*
10859 			 * If the caller has the ability to manipulate file flags,
10860 			 * security is not reduced by ignoring them for this operation.
10861 			 *
10862 			 * A more complete test here would consider the 'after' states of the flags
10863 			 * to determine whether it would permit the operation, but this becomes
10864 			 * very complex.
10865 			 *
10866 			 * Ignoring immutability is conditional on securelevel; this does not bypass
10867 			 * the SF_* flags if securelevel > 0.
10868 			 */
10869 			required_action |= KAUTH_VNODE_NOIMMUTABLE;
10870 		}
10871 	}
10872 
10873 	/*
10874 	 * Validate ownership information.
10875 	 */
10876 	chowner = 0;
10877 	chgroup = 0;
10878 	clear_suid = 0;
10879 	clear_sgid = 0;
10880 
10881 	/*
10882 	 * uid changing
10883 	 * Note that if the filesystem didn't give us a UID, we expect that it doesn't
10884 	 * support them in general, and will ignore it if/when we try to set it.
10885 	 * We might want to clear the uid out of vap completely here.
10886 	 */
10887 	if (VATTR_IS_ACTIVE(vap, va_uid)) {
10888 		if (VATTR_IS_SUPPORTED(&ova, va_uid) && (vap->va_uid != ova.va_uid)) {
10889 			if (!has_priv_suser && (kauth_cred_getuid(cred) != vap->va_uid)) {
10890 				KAUTH_DEBUG("  DENIED - non-superuser cannot change ownershipt to a third party");
10891 				error = EPERM;
10892 				goto out;
10893 			}
10894 			chowner = 1;
10895 		}
10896 		clear_suid = 1;
10897 	}
10898 
10899 	/*
10900 	 * gid changing
10901 	 * Note that if the filesystem didn't give us a GID, we expect that it doesn't
10902 	 * support them in general, and will ignore it if/when we try to set it.
10903 	 * We might want to clear the gid out of vap completely here.
10904 	 */
10905 	if (VATTR_IS_ACTIVE(vap, va_gid)) {
10906 		if (VATTR_IS_SUPPORTED(&ova, va_gid) && (vap->va_gid != ova.va_gid)) {
10907 			if (!has_priv_suser) {
10908 				if ((error = kauth_cred_ismember_gid(cred, vap->va_gid, &ismember)) != 0) {
10909 					KAUTH_DEBUG("  ERROR - got %d checking for membership in %d", error, vap->va_gid);
10910 					goto out;
10911 				}
10912 				if (!ismember) {
10913 					KAUTH_DEBUG("  DENIED - group change from %d to %d but not a member of target group",
10914 					    ova.va_gid, vap->va_gid);
10915 					error = EPERM;
10916 					goto out;
10917 				}
10918 			}
10919 			chgroup = 1;
10920 		}
10921 		clear_sgid = 1;
10922 	}
10923 
10924 	/*
10925 	 * Owner UUID being set or changed.
10926 	 */
10927 	if (VATTR_IS_ACTIVE(vap, va_uuuid)) {
10928 		/* if the owner UUID is not actually changing ... */
10929 		if (VATTR_IS_SUPPORTED(&ova, va_uuuid)) {
10930 			if (kauth_guid_equal(&vap->va_uuuid, &ova.va_uuuid)) {
10931 				goto no_uuuid_change;
10932 			}
10933 
10934 			/*
10935 			 * If the current owner UUID is a null GUID, check
10936 			 * it against the UUID corresponding to the owner UID.
10937 			 */
10938 			if (kauth_guid_equal(&ova.va_uuuid, &kauth_null_guid) &&
10939 			    VATTR_IS_SUPPORTED(&ova, va_uid)) {
10940 				guid_t uid_guid;
10941 
10942 				if (kauth_cred_uid2guid(ova.va_uid, &uid_guid) == 0 &&
10943 				    kauth_guid_equal(&vap->va_uuuid, &uid_guid)) {
10944 					goto no_uuuid_change;
10945 				}
10946 			}
10947 		}
10948 
10949 		/*
10950 		 * The owner UUID cannot be set by a non-superuser to anything other than
10951 		 * their own or a null GUID (to "unset" the owner UUID).
10952 		 * Note that file systems must be prepared to handle the
10953 		 * null UUID case in a manner appropriate for that file
10954 		 * system.
10955 		 */
10956 		if (!has_priv_suser) {
10957 			if ((error = kauth_cred_getguid(cred, &changer)) != 0) {
10958 				KAUTH_DEBUG("  ERROR - got %d trying to get caller UUID", error);
10959 				/* XXX ENOENT here - no UUID - should perhaps become EPERM */
10960 				goto out;
10961 			}
10962 			if (!kauth_guid_equal(&vap->va_uuuid, &changer) &&
10963 			    !kauth_guid_equal(&vap->va_uuuid, &kauth_null_guid)) {
10964 				KAUTH_DEBUG("  ERROR - cannot set supplied owner UUID - not us / null");
10965 				error = EPERM;
10966 				goto out;
10967 			}
10968 		}
10969 		chowner = 1;
10970 		clear_suid = 1;
10971 	}
10972 no_uuuid_change:
10973 	/*
10974 	 * Group UUID being set or changed.
10975 	 */
10976 	if (VATTR_IS_ACTIVE(vap, va_guuid)) {
10977 		/* if the group UUID is not actually changing ... */
10978 		if (VATTR_IS_SUPPORTED(&ova, va_guuid)) {
10979 			if (kauth_guid_equal(&vap->va_guuid, &ova.va_guuid)) {
10980 				goto no_guuid_change;
10981 			}
10982 
10983 			/*
10984 			 * If the current group UUID is a null UUID, check
10985 			 * it against the UUID corresponding to the group GID.
10986 			 */
10987 			if (kauth_guid_equal(&ova.va_guuid, &kauth_null_guid) &&
10988 			    VATTR_IS_SUPPORTED(&ova, va_gid)) {
10989 				guid_t gid_guid;
10990 
10991 				if (kauth_cred_gid2guid(ova.va_gid, &gid_guid) == 0 &&
10992 				    kauth_guid_equal(&vap->va_guuid, &gid_guid)) {
10993 					goto no_guuid_change;
10994 				}
10995 			}
10996 		}
10997 
10998 		/*
10999 		 * The group UUID cannot be set by a non-superuser to anything other than
11000 		 * one of which they are a member or a null GUID (to "unset"
11001 		 * the group UUID).
11002 		 * Note that file systems must be prepared to handle the
11003 		 * null UUID case in a manner appropriate for that file
11004 		 * system.
11005 		 */
11006 		if (!has_priv_suser) {
11007 			if (kauth_guid_equal(&vap->va_guuid, &kauth_null_guid)) {
11008 				ismember = 1;
11009 			} else if ((error = kauth_cred_ismember_guid(cred, &vap->va_guuid, &ismember)) != 0) {
11010 				KAUTH_DEBUG("  ERROR - got %d trying to check group membership", error);
11011 				goto out;
11012 			}
11013 			if (!ismember) {
11014 				KAUTH_DEBUG("  ERROR - cannot set supplied group UUID - not a member / null");
11015 				error = EPERM;
11016 				goto out;
11017 			}
11018 		}
11019 		chgroup = 1;
11020 	}
11021 no_guuid_change:
11022 
11023 	/*
11024 	 * Compute authorisation for group/ownership changes.
11025 	 */
11026 	if (chowner || chgroup || clear_suid || clear_sgid) {
11027 		if (has_priv_suser) {
11028 			KAUTH_DEBUG("ATTR - superuser changing file owner/group, requiring immutability check");
11029 			required_action |= KAUTH_VNODE_CHECKIMMUTABLE;
11030 		} else {
11031 			if (chowner) {
11032 				KAUTH_DEBUG("ATTR - ownership change, requiring TAKE_OWNERSHIP");
11033 				required_action |= KAUTH_VNODE_TAKE_OWNERSHIP;
11034 			}
11035 			if (chgroup && !chowner) {
11036 				KAUTH_DEBUG("ATTR - group change, requiring WRITE_SECURITY");
11037 				required_action |= KAUTH_VNODE_WRITE_SECURITY;
11038 			}
11039 		}
11040 
11041 		/*
11042 		 * clear set-uid and set-gid bits. POSIX only requires this for
11043 		 * non-privileged processes but we do it even for root.
11044 		 */
11045 		if (VATTR_IS_ACTIVE(vap, va_mode)) {
11046 			newmode = vap->va_mode;
11047 		} else if (VATTR_IS_SUPPORTED(&ova, va_mode)) {
11048 			newmode = ova.va_mode;
11049 		} else {
11050 			KAUTH_DEBUG("CHOWN - trying to change owner but cannot get mode from filesystem to mask setugid bits");
11051 			newmode = 0;
11052 		}
11053 
11054 		/* chown always clears setuid/gid bits. An exception is made for
11055 		 * setattrlist which can set both at the same time: <uid, gid, mode> on a file:
11056 		 * setattrlist is allowed to set the new mode on the file and change (chown)
11057 		 * uid/gid.
11058 		 */
11059 		if (newmode & (S_ISUID | S_ISGID)) {
11060 			if (!VATTR_IS_ACTIVE(vap, va_mode)) {
11061 				KAUTH_DEBUG("CHOWN - masking setugid bits from mode %o to %o",
11062 				    newmode, newmode & ~(S_ISUID | S_ISGID));
11063 				newmode &= ~(S_ISUID | S_ISGID);
11064 			}
11065 			VATTR_SET(vap, va_mode, newmode);
11066 		}
11067 	}
11068 
11069 	/*
11070 	 * Authorise changes in the ACL.
11071 	 */
11072 	if (VATTR_IS_ACTIVE(vap, va_acl)) {
11073 		/* no existing ACL */
11074 		if (!VATTR_IS_ACTIVE(&ova, va_acl) || (ova.va_acl == NULL)) {
11075 			/* adding an ACL */
11076 			if (vap->va_acl != NULL) {
11077 				required_action |= KAUTH_VNODE_WRITE_SECURITY;
11078 				KAUTH_DEBUG("CHMOD - adding ACL");
11079 			}
11080 
11081 			/* removing an existing ACL */
11082 		} else if (vap->va_acl == NULL) {
11083 			required_action |= KAUTH_VNODE_WRITE_SECURITY;
11084 			KAUTH_DEBUG("CHMOD - removing ACL");
11085 
11086 			/* updating an existing ACL */
11087 		} else {
11088 			if (vap->va_acl->acl_entrycount != ova.va_acl->acl_entrycount) {
11089 				/* entry count changed, must be different */
11090 				required_action |= KAUTH_VNODE_WRITE_SECURITY;
11091 				KAUTH_DEBUG("CHMOD - adding/removing ACL entries");
11092 			} else if (vap->va_acl->acl_entrycount > 0) {
11093 				/* both ACLs have the same ACE count, said count is 1 or more, bitwise compare ACLs */
11094 				if (memcmp(&vap->va_acl->acl_ace[0], &ova.va_acl->acl_ace[0],
11095 				    sizeof(struct kauth_ace) * vap->va_acl->acl_entrycount)) {
11096 					required_action |= KAUTH_VNODE_WRITE_SECURITY;
11097 					KAUTH_DEBUG("CHMOD - changing ACL entries");
11098 				}
11099 			}
11100 		}
11101 	}
11102 
11103 	/*
11104 	 * Other attributes that require authorisation.
11105 	 */
11106 	if (VATTR_IS_ACTIVE(vap, va_encoding)) {
11107 		required_action |= KAUTH_VNODE_WRITE_ATTRIBUTES;
11108 	}
11109 
11110 out:
11111 	if (VATTR_IS_SUPPORTED(&ova, va_acl) && (ova.va_acl != NULL)) {
11112 		kauth_acl_free(ova.va_acl);
11113 	}
11114 	if (error == 0) {
11115 		*actionp = required_action;
11116 	}
11117 	return error;
11118 }
11119 
11120 static int
setlocklocal_callback(struct vnode * vp,__unused void * cargs)11121 setlocklocal_callback(struct vnode *vp, __unused void *cargs)
11122 {
11123 	vnode_lock_spin(vp);
11124 	vp->v_flag |= VLOCKLOCAL;
11125 	vnode_unlock(vp);
11126 
11127 	return VNODE_RETURNED;
11128 }
11129 
11130 void
vfs_setlocklocal(mount_t mp)11131 vfs_setlocklocal(mount_t mp)
11132 {
11133 	mount_lock_spin(mp);
11134 	mp->mnt_kern_flag |= MNTK_LOCK_LOCAL;
11135 	mount_unlock(mp);
11136 
11137 	/*
11138 	 * The number of active vnodes is expected to be
11139 	 * very small when vfs_setlocklocal is invoked.
11140 	 */
11141 	vnode_iterate(mp, 0, setlocklocal_callback, NULL);
11142 }
11143 
11144 void
vfs_setcompoundopen(mount_t mp)11145 vfs_setcompoundopen(mount_t mp)
11146 {
11147 	mount_lock_spin(mp);
11148 	mp->mnt_compound_ops |= COMPOUND_VNOP_OPEN;
11149 	mount_unlock(mp);
11150 }
11151 
11152 void
vnode_setswapmount(vnode_t vp)11153 vnode_setswapmount(vnode_t vp)
11154 {
11155 	mount_lock(vp->v_mount);
11156 	vp->v_mount->mnt_kern_flag |= MNTK_SWAP_MOUNT;
11157 	mount_unlock(vp->v_mount);
11158 }
11159 
11160 void
vfs_setfskit(mount_t mp)11161 vfs_setfskit(mount_t mp)
11162 {
11163 	mount_lock_spin(mp);
11164 	mp->mnt_kern_flag |= MNTK_FSKIT;
11165 	mount_unlock(mp);
11166 }
11167 
11168 char *
vfs_getfstypenameref_locked(mount_t mp,size_t * lenp)11169 vfs_getfstypenameref_locked(mount_t mp, size_t *lenp)
11170 {
11171 	char *name;
11172 
11173 	if (mp->mnt_kern_flag & MNTK_TYPENAME_OVERRIDE) {
11174 		name = mp->fstypename_override;
11175 	} else {
11176 		name = mp->mnt_vfsstat.f_fstypename;
11177 	}
11178 	if (lenp != NULL) {
11179 		*lenp = strlen(name);
11180 	}
11181 	return name;
11182 }
11183 
11184 void
vfs_getfstypename(mount_t mp,char * buf,size_t buflen)11185 vfs_getfstypename(mount_t mp, char *buf, size_t buflen)
11186 {
11187 	mount_lock_spin(mp);
11188 	strlcpy(buf, vfs_getfstypenameref_locked(mp, NULL), buflen);
11189 	mount_unlock(mp);
11190 }
11191 
11192 void
vfs_setfstypename_locked(mount_t mp,const char * name)11193 vfs_setfstypename_locked(mount_t mp, const char *name)
11194 {
11195 	if (name == NULL || name[0] == '\0') {
11196 		mp->mnt_kern_flag &= ~MNTK_TYPENAME_OVERRIDE;
11197 		mp->fstypename_override[0] = '\0';
11198 	} else {
11199 		strlcpy(mp->fstypename_override, name,
11200 		    sizeof(mp->fstypename_override));
11201 		mp->mnt_kern_flag |= MNTK_TYPENAME_OVERRIDE;
11202 	}
11203 }
11204 
11205 void
vfs_setfstypename(mount_t mp,const char * name)11206 vfs_setfstypename(mount_t mp, const char *name)
11207 {
11208 	mount_lock_spin(mp);
11209 	vfs_setfstypename_locked(mp, name);
11210 	mount_unlock(mp);
11211 }
11212 
11213 int64_t
vnode_getswappin_avail(vnode_t vp)11214 vnode_getswappin_avail(vnode_t vp)
11215 {
11216 	int64_t max_swappin_avail = 0;
11217 
11218 	mount_lock(vp->v_mount);
11219 	if (vp->v_mount->mnt_ioflags & MNT_IOFLAGS_SWAPPIN_SUPPORTED) {
11220 		max_swappin_avail = vp->v_mount->mnt_max_swappin_available;
11221 	}
11222 	mount_unlock(vp->v_mount);
11223 
11224 	return max_swappin_avail;
11225 }
11226 
11227 
11228 void
vn_setunionwait(vnode_t vp)11229 vn_setunionwait(vnode_t vp)
11230 {
11231 	vnode_lock_spin(vp);
11232 	vp->v_flag |= VISUNION;
11233 	vnode_unlock(vp);
11234 }
11235 
11236 
11237 void
vn_checkunionwait(vnode_t vp)11238 vn_checkunionwait(vnode_t vp)
11239 {
11240 	vnode_lock_spin(vp);
11241 	while ((vp->v_flag & VISUNION) == VISUNION) {
11242 		msleep((caddr_t)&vp->v_flag, &vp->v_lock, 0, 0, 0);
11243 	}
11244 	vnode_unlock(vp);
11245 }
11246 
11247 void
vn_clearunionwait(vnode_t vp,int locked)11248 vn_clearunionwait(vnode_t vp, int locked)
11249 {
11250 	if (!locked) {
11251 		vnode_lock_spin(vp);
11252 	}
11253 	if ((vp->v_flag & VISUNION) == VISUNION) {
11254 		vp->v_flag &= ~VISUNION;
11255 		wakeup((caddr_t)&vp->v_flag);
11256 	}
11257 	if (!locked) {
11258 		vnode_unlock(vp);
11259 	}
11260 }
11261 
11262 /*
11263  * Removes orphaned apple double files during a rmdir
11264  * Works by:
11265  * 1. vnode_suspend().
11266  * 2. Call VNOP_READDIR() till the end of directory is reached.
11267  * 3. Check if the directory entries returned are regular files with name starting with "._".  If not, return ENOTEMPTY.
11268  * 4. Continue (2) and (3) till end of directory is reached.
11269  * 5. If all the entries in the directory were files with "._" name, delete all the files.
11270  * 6. vnode_resume()
11271  * 7. If deletion of all files succeeded, call VNOP_RMDIR() again.
11272  */
11273 
11274 errno_t
rmdir_remove_orphaned_appleDouble(vnode_t vp,vfs_context_t ctx,int * restart_flag)11275 rmdir_remove_orphaned_appleDouble(vnode_t vp, vfs_context_t ctx, int * restart_flag)
11276 {
11277 #define UIO_BUFF_SIZE 2048
11278 	uio_t auio = NULL;
11279 	int eofflag, siz = UIO_BUFF_SIZE, alloc_size = 0, nentries = 0;
11280 	int open_flag = 0, full_erase_flag = 0;
11281 	UIO_STACKBUF(uio_buf, 1);
11282 	char *rbuf = NULL;
11283 	void *dir_pos;
11284 	void *dir_end;
11285 	struct dirent *dp;
11286 	errno_t error;
11287 
11288 	error = vnode_suspend(vp);
11289 
11290 	/*
11291 	 * restart_flag is set so that the calling rmdir sleeps and resets
11292 	 */
11293 	if (error == EBUSY) {
11294 		*restart_flag = 1;
11295 	}
11296 	if (error != 0) {
11297 		return error;
11298 	}
11299 
11300 	/*
11301 	 * Prevent dataless fault materialization while we have
11302 	 * a suspended vnode.
11303 	 */
11304 	uthread_t ut = current_uthread();
11305 	bool saved_nodatalessfaults =
11306 	    (ut->uu_flag & UT_NSPACE_NODATALESSFAULTS) ? true : false;
11307 	ut->uu_flag |= UT_NSPACE_NODATALESSFAULTS;
11308 
11309 	/*
11310 	 * set up UIO
11311 	 */
11312 	rbuf = kalloc_data(siz, Z_WAITOK);
11313 	alloc_size = siz;
11314 	if (rbuf) {
11315 		auio = uio_createwithbuffer(1, 0, UIO_SYSSPACE, UIO_READ,
11316 		    &uio_buf[0], sizeof(uio_buf));
11317 	}
11318 	if (!rbuf || !auio) {
11319 		error = ENOMEM;
11320 		goto outsc;
11321 	}
11322 
11323 	uio_setoffset(auio, 0);
11324 
11325 	eofflag = 0;
11326 
11327 	if ((error = VNOP_OPEN(vp, FREAD, ctx))) {
11328 		goto outsc;
11329 	} else {
11330 		open_flag = 1;
11331 	}
11332 
11333 	/*
11334 	 * First pass checks if all files are appleDouble files.
11335 	 */
11336 
11337 	do {
11338 		siz = UIO_BUFF_SIZE;
11339 		uio_reset(auio, uio_offset(auio), UIO_SYSSPACE, UIO_READ);
11340 		uio_addiov(auio, CAST_USER_ADDR_T(rbuf), UIO_BUFF_SIZE);
11341 
11342 		if ((error = VNOP_READDIR(vp, auio, 0, &eofflag, &nentries, ctx))) {
11343 			goto outsc;
11344 		}
11345 
11346 		if (uio_resid(auio) != 0) {
11347 			siz -= uio_resid(auio);
11348 		}
11349 
11350 		/*
11351 		 * Iterate through directory
11352 		 */
11353 		dir_pos = (void*) rbuf;
11354 		dir_end = (void*) (rbuf + siz);
11355 		dp = (struct dirent*) (dir_pos);
11356 
11357 		if (dir_pos == dir_end) {
11358 			eofflag = 1;
11359 		}
11360 
11361 		while (dir_pos < dir_end) {
11362 			/*
11363 			 * Check for . and .. as well as directories
11364 			 */
11365 			if (dp->d_ino != 0 &&
11366 			    !((dp->d_namlen == 1 && dp->d_name[0] == '.') ||
11367 			    (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.'))) {
11368 				/*
11369 				 * Check for irregular files and ._ files
11370 				 * If there is a ._._ file abort the op
11371 				 */
11372 				if (dp->d_namlen < 2 ||
11373 				    strncmp(dp->d_name, "._", 2) ||
11374 				    (dp->d_namlen >= 4 && !strncmp(&(dp->d_name[2]), "._", 2))) {
11375 					error = ENOTEMPTY;
11376 					goto outsc;
11377 				}
11378 			}
11379 			dir_pos = (void*) ((uint8_t*)dir_pos + dp->d_reclen);
11380 			dp = (struct dirent*)dir_pos;
11381 		}
11382 
11383 		/*
11384 		 * workaround for HFS/NFS setting eofflag before end of file
11385 		 */
11386 		if (vp->v_tag == VT_HFS && nentries > 2) {
11387 			eofflag = 0;
11388 		}
11389 
11390 		if (vp->v_tag == VT_NFS) {
11391 			if (eofflag && !full_erase_flag) {
11392 				full_erase_flag = 1;
11393 				eofflag = 0;
11394 				uio_reset(auio, 0, UIO_SYSSPACE, UIO_READ);
11395 			} else if (!eofflag && full_erase_flag) {
11396 				full_erase_flag = 0;
11397 			}
11398 		}
11399 	} while (!eofflag);
11400 	/*
11401 	 * If we've made it here all the files in the dir are ._ files.
11402 	 * We can delete the files even though the node is suspended
11403 	 * because we are the owner of the file.
11404 	 */
11405 
11406 	uio_reset(auio, 0, UIO_SYSSPACE, UIO_READ);
11407 	eofflag = 0;
11408 	full_erase_flag = 0;
11409 
11410 	do {
11411 		siz = UIO_BUFF_SIZE;
11412 		uio_reset(auio, uio_offset(auio), UIO_SYSSPACE, UIO_READ);
11413 		uio_addiov(auio, CAST_USER_ADDR_T(rbuf), UIO_BUFF_SIZE);
11414 
11415 		error = VNOP_READDIR(vp, auio, 0, &eofflag, &nentries, ctx);
11416 
11417 		if (error != 0) {
11418 			goto outsc;
11419 		}
11420 
11421 		if (uio_resid(auio) != 0) {
11422 			siz -= uio_resid(auio);
11423 		}
11424 
11425 		/*
11426 		 * Iterate through directory
11427 		 */
11428 		dir_pos = (void*) rbuf;
11429 		dir_end = (void*) (rbuf + siz);
11430 		dp = (struct dirent*) dir_pos;
11431 
11432 		if (dir_pos == dir_end) {
11433 			eofflag = 1;
11434 		}
11435 
11436 		while (dir_pos < dir_end) {
11437 			/*
11438 			 * Check for . and .. as well as directories
11439 			 */
11440 			if (dp->d_ino != 0 &&
11441 			    !((dp->d_namlen == 1 && dp->d_name[0] == '.') ||
11442 			    (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.'))
11443 			    ) {
11444 				error = unlink1(ctx, vp,
11445 				    CAST_USER_ADDR_T(dp->d_name), UIO_SYSSPACE,
11446 				    VNODE_REMOVE_SKIP_NAMESPACE_EVENT |
11447 				    VNODE_REMOVE_NO_AUDIT_PATH);
11448 
11449 				if (error && error != ENOENT) {
11450 					goto outsc;
11451 				}
11452 			}
11453 			dir_pos = (void*) ((uint8_t*)dir_pos + dp->d_reclen);
11454 			dp = (struct dirent*)dir_pos;
11455 		}
11456 
11457 		/*
11458 		 * workaround for HFS/NFS setting eofflag before end of file
11459 		 */
11460 		if (vp->v_tag == VT_HFS && nentries > 2) {
11461 			eofflag = 0;
11462 		}
11463 
11464 		if (vp->v_tag == VT_NFS) {
11465 			if (eofflag && !full_erase_flag) {
11466 				full_erase_flag = 1;
11467 				eofflag = 0;
11468 				uio_reset(auio, 0, UIO_SYSSPACE, UIO_READ);
11469 			} else if (!eofflag && full_erase_flag) {
11470 				full_erase_flag = 0;
11471 			}
11472 		}
11473 	} while (!eofflag);
11474 
11475 
11476 	error = 0;
11477 
11478 outsc:
11479 	if (open_flag) {
11480 		VNOP_CLOSE(vp, FREAD, ctx);
11481 	}
11482 
11483 	if (auio) {
11484 		uio_free(auio);
11485 	}
11486 	kfree_data(rbuf, alloc_size);
11487 
11488 	if (saved_nodatalessfaults == false) {
11489 		ut->uu_flag &= ~UT_NSPACE_NODATALESSFAULTS;
11490 	}
11491 
11492 	vnode_resume(vp);
11493 
11494 	return error;
11495 }
11496 
11497 
11498 void
lock_vnode_and_post(vnode_t vp,int kevent_num)11499 lock_vnode_and_post(vnode_t vp, int kevent_num)
11500 {
11501 	/* Only take the lock if there's something there! */
11502 	if (vp->v_knotes.slh_first != NULL) {
11503 		vnode_lock(vp);
11504 		KNOTE(&vp->v_knotes, kevent_num);
11505 		vnode_unlock(vp);
11506 	}
11507 }
11508 
11509 void panic_print_vnodes(void);
11510 
11511 /* define PANIC_PRINTS_VNODES only if investigation is required. */
11512 #ifdef PANIC_PRINTS_VNODES
11513 
11514 static const char *
__vtype(uint16_t vtype)11515 __vtype(uint16_t vtype)
11516 {
11517 	switch (vtype) {
11518 	case VREG:
11519 		return "R";
11520 	case VDIR:
11521 		return "D";
11522 	case VBLK:
11523 		return "B";
11524 	case VCHR:
11525 		return "C";
11526 	case VLNK:
11527 		return "L";
11528 	case VSOCK:
11529 		return "S";
11530 	case VFIFO:
11531 		return "F";
11532 	case VBAD:
11533 		return "x";
11534 	case VSTR:
11535 		return "T";
11536 	case VCPLX:
11537 		return "X";
11538 	default:
11539 		return "?";
11540 	}
11541 }
11542 
11543 /*
11544  * build a path from the bottom up
11545  * NOTE: called from the panic path - no alloc'ing of memory and no locks!
11546  */
11547 static char *
__vpath(vnode_t vp,char * str,int len,int depth)11548 __vpath(vnode_t vp, char *str, int len, int depth)
11549 {
11550 	int vnm_len;
11551 	const char *src;
11552 	char *dst;
11553 
11554 	if (len <= 0) {
11555 		return str;
11556 	}
11557 	/* str + len is the start of the string we created */
11558 	if (!vp->v_name) {
11559 		return str + len;
11560 	}
11561 
11562 	/* follow mount vnodes to get the full path */
11563 	if ((vp->v_flag & VROOT)) {
11564 		if (vp->v_mount != NULL && vp->v_mount->mnt_vnodecovered) {
11565 			return __vpath(vp->v_mount->mnt_vnodecovered,
11566 			           str, len, depth + 1);
11567 		}
11568 		return str + len;
11569 	}
11570 
11571 	src = vp->v_name;
11572 	vnm_len = strlen(src);
11573 	if (vnm_len > len) {
11574 		/* truncate the name to fit in the string */
11575 		src += (vnm_len - len);
11576 		vnm_len = len;
11577 	}
11578 
11579 	/* start from the back and copy just characters (no NULLs) */
11580 
11581 	/* this will chop off leaf path (file) names */
11582 	if (depth > 0) {
11583 		dst = str + len - vnm_len;
11584 		memcpy(dst, src, vnm_len);
11585 		len -= vnm_len;
11586 	} else {
11587 		dst = str + len;
11588 	}
11589 
11590 	if (vp->v_parent && len > 1) {
11591 		/* follow parents up the chain */
11592 		len--;
11593 		*(dst - 1) = '/';
11594 		return __vpath(vp->v_parent, str, len, depth + 1);
11595 	}
11596 
11597 	return dst;
11598 }
11599 
11600 #define SANE_VNODE_PRINT_LIMIT 5000
11601 void
panic_print_vnodes(void)11602 panic_print_vnodes(void)
11603 {
11604 	mount_t mnt;
11605 	vnode_t vp;
11606 	int nvnodes = 0;
11607 	const char *type;
11608 	char *nm;
11609 	char vname[257];
11610 
11611 	paniclog_append_noflush("\n***** VNODES *****\n"
11612 	    "TYPE UREF ICNT PATH\n");
11613 
11614 	/* NULL-terminate the path name */
11615 	vname[sizeof(vname) - 1] = '\0';
11616 
11617 	/*
11618 	 * iterate all vnodelist items in all mounts (mntlist) -> mnt_vnodelist
11619 	 */
11620 	TAILQ_FOREACH(mnt, &mountlist, mnt_list) {
11621 		if (!ml_validate_nofault((vm_offset_t)mnt, sizeof(mount_t))) {
11622 			paniclog_append_noflush("Unable to iterate the mount list %p - encountered an invalid mount pointer %p \n",
11623 			    &mountlist, mnt);
11624 			break;
11625 		}
11626 
11627 		TAILQ_FOREACH(vp, &mnt->mnt_vnodelist, v_mntvnodes) {
11628 			if (!ml_validate_nofault((vm_offset_t)vp, sizeof(vnode_t))) {
11629 				paniclog_append_noflush("Unable to iterate the vnode list %p - encountered an invalid vnode pointer %p \n",
11630 				    &mnt->mnt_vnodelist, vp);
11631 				break;
11632 			}
11633 
11634 			if (++nvnodes > SANE_VNODE_PRINT_LIMIT) {
11635 				return;
11636 			}
11637 			type = __vtype(vp->v_type);
11638 			nm = __vpath(vp, vname, sizeof(vname) - 1, 0);
11639 			paniclog_append_noflush("%s %0d %0d %s\n",
11640 			    type, vp->v_usecount, vp->v_iocount, nm);
11641 		}
11642 	}
11643 }
11644 
11645 #else /* !PANIC_PRINTS_VNODES */
11646 void
panic_print_vnodes(void)11647 panic_print_vnodes(void)
11648 {
11649 	return;
11650 }
11651 #endif
11652 
11653 
11654 #ifdef CONFIG_IOCOUNT_TRACE
11655 static void
record_iocount_trace_vnode(vnode_t vp,int type)11656 record_iocount_trace_vnode(vnode_t vp, int type)
11657 {
11658 	void *stacks[IOCOUNT_TRACE_MAX_FRAMES] = {0};
11659 	int idx = vp->v_iocount_trace[type].idx;
11660 
11661 	if (idx >= IOCOUNT_TRACE_MAX_IDX) {
11662 		return;
11663 	}
11664 
11665 	OSBacktrace((void **)&stacks[0], IOCOUNT_TRACE_MAX_FRAMES);
11666 
11667 	/*
11668 	 * To save index space, only store the unique backtraces. If dup is found,
11669 	 * just bump the count and return.
11670 	 */
11671 	for (int i = 0; i < idx; i++) {
11672 		if (memcmp(&stacks[0], &vp->v_iocount_trace[type].stacks[i][0],
11673 		    sizeof(stacks)) == 0) {
11674 			vp->v_iocount_trace[type].counts[i]++;
11675 			return;
11676 		}
11677 	}
11678 
11679 	memcpy(&vp->v_iocount_trace[type].stacks[idx][0], &stacks[0],
11680 	    sizeof(stacks));
11681 	vp->v_iocount_trace[type].counts[idx] = 1;
11682 	vp->v_iocount_trace[type].idx++;
11683 }
11684 
11685 static void
record_iocount_trace_uthread(vnode_t vp,int count)11686 record_iocount_trace_uthread(vnode_t vp, int count)
11687 {
11688 	struct uthread *ut;
11689 
11690 	ut = current_uthread();
11691 	ut->uu_iocount += count;
11692 
11693 	if (count == 1) {
11694 		if (ut->uu_vpindex < 32) {
11695 			OSBacktrace((void **)&ut->uu_pcs[ut->uu_vpindex][0], 10);
11696 
11697 			ut->uu_vps[ut->uu_vpindex] = vp;
11698 			ut->uu_vpindex++;
11699 		}
11700 	}
11701 }
11702 
11703 static void
record_vp(vnode_t vp,int count)11704 record_vp(vnode_t vp, int count)
11705 {
11706 	if (__probable(bootarg_vnode_iocount_trace == 0 &&
11707 	    bootarg_uthread_iocount_trace == 0)) {
11708 		return;
11709 	}
11710 
11711 #if CONFIG_TRIGGERS
11712 	if (vp->v_resolve) {
11713 		return;
11714 	}
11715 #endif
11716 	if ((vp->v_flag & VSYSTEM)) {
11717 		return;
11718 	}
11719 
11720 	if (bootarg_vnode_iocount_trace) {
11721 		record_iocount_trace_vnode(vp,
11722 		    (count > 0) ? IOCOUNT_TRACE_VGET : IOCOUNT_TRACE_VPUT);
11723 	}
11724 	if (bootarg_uthread_iocount_trace) {
11725 		record_iocount_trace_uthread(vp, count);
11726 	}
11727 }
11728 #endif /* CONFIG_IOCOUNT_TRACE */
11729 
11730 #if CONFIG_TRIGGERS
11731 #define __triggers_unused
11732 #else
11733 #define __triggers_unused       __unused
11734 #endif
11735 
11736 resolver_result_t
vfs_resolver_result(__triggers_unused uint32_t seq,__triggers_unused enum resolver_status stat,__triggers_unused int aux)11737 vfs_resolver_result(__triggers_unused uint32_t seq, __triggers_unused enum resolver_status stat, __triggers_unused int aux)
11738 {
11739 #if CONFIG_TRIGGERS
11740 	/*
11741 	 * |<---   32   --->|<---  28  --->|<- 4 ->|
11742 	 *      sequence        auxiliary    status
11743 	 */
11744 	return (((uint64_t)seq) << 32) |
11745 	       (((uint64_t)(aux & 0x0fffffff)) << 4) |
11746 	       (uint64_t)(stat & 0x0000000F);
11747 #else
11748 	return (0x0ULL) | (((uint64_t)ENOTSUP) << 4) | (((uint64_t)RESOLVER_ERROR) & 0xF);
11749 #endif
11750 }
11751 
11752 #if CONFIG_TRIGGERS
11753 
11754 #define TRIG_DEBUG 0
11755 
11756 #if TRIG_DEBUG
11757 #define TRIG_LOG(...) do { printf("%s: ", __FUNCTION__); printf(__VA_ARGS__); } while (0)
11758 #else
11759 #define TRIG_LOG(...)
11760 #endif
11761 
11762 /*
11763  * Resolver result functions
11764  */
11765 
11766 
11767 enum resolver_status
vfs_resolver_status(resolver_result_t result)11768 vfs_resolver_status(resolver_result_t result)
11769 {
11770 	/* lower 4 bits is status */
11771 	return result & 0x0000000F;
11772 }
11773 
11774 uint32_t
vfs_resolver_sequence(resolver_result_t result)11775 vfs_resolver_sequence(resolver_result_t result)
11776 {
11777 	/* upper 32 bits is sequence */
11778 	return (uint32_t)(result >> 32);
11779 }
11780 
11781 int
vfs_resolver_auxiliary(resolver_result_t result)11782 vfs_resolver_auxiliary(resolver_result_t result)
11783 {
11784 	/* 28 bits of auxiliary */
11785 	return (int)(((uint32_t)(result & 0xFFFFFFF0)) >> 4);
11786 }
11787 
11788 /*
11789  * SPI
11790  * Call in for resolvers to update vnode trigger state
11791  */
11792 int
vnode_trigger_update(vnode_t vp,resolver_result_t result)11793 vnode_trigger_update(vnode_t vp, resolver_result_t result)
11794 {
11795 	vnode_resolve_t rp;
11796 	uint32_t seq;
11797 	enum resolver_status stat;
11798 
11799 	if (vp->v_resolve == NULL) {
11800 		return EINVAL;
11801 	}
11802 
11803 	stat = vfs_resolver_status(result);
11804 	seq = vfs_resolver_sequence(result);
11805 
11806 	if ((stat != RESOLVER_RESOLVED) && (stat != RESOLVER_UNRESOLVED)) {
11807 		return EINVAL;
11808 	}
11809 
11810 	rp = vp->v_resolve;
11811 	lck_mtx_lock(&rp->vr_lock);
11812 
11813 	if (seq > rp->vr_lastseq) {
11814 		if (stat == RESOLVER_RESOLVED) {
11815 			rp->vr_flags |= VNT_RESOLVED;
11816 		} else {
11817 			rp->vr_flags &= ~VNT_RESOLVED;
11818 		}
11819 
11820 		rp->vr_lastseq = seq;
11821 	}
11822 
11823 	lck_mtx_unlock(&rp->vr_lock);
11824 
11825 	return 0;
11826 }
11827 
11828 static int
vnode_resolver_attach(vnode_t vp,vnode_resolve_t rp,boolean_t ref)11829 vnode_resolver_attach(vnode_t vp, vnode_resolve_t rp, boolean_t ref)
11830 {
11831 	int error;
11832 
11833 	vnode_lock_spin(vp);
11834 	if (vp->v_resolve != NULL) {
11835 		vnode_unlock(vp);
11836 		return EINVAL;
11837 	} else {
11838 		vp->v_resolve = rp;
11839 	}
11840 	vnode_unlock(vp);
11841 
11842 	if (ref) {
11843 		error = vnode_ref_ext(vp, O_EVTONLY, VNODE_REF_FORCE);
11844 		if (error != 0) {
11845 			panic("VNODE_REF_FORCE didn't help...");
11846 		}
11847 	}
11848 
11849 	return 0;
11850 }
11851 
11852 /*
11853  * VFS internal interfaces for vnode triggers
11854  *
11855  * vnode must already have an io count on entry
11856  * v_resolve is stable when io count is non-zero
11857  */
11858 static int
vnode_resolver_create(mount_t mp,vnode_t vp,struct vnode_trigger_param * tinfo,boolean_t external)11859 vnode_resolver_create(mount_t mp, vnode_t vp, struct vnode_trigger_param *tinfo, boolean_t external)
11860 {
11861 	vnode_resolve_t rp;
11862 	int result;
11863 	char byte;
11864 
11865 #if 1
11866 	/* minimum pointer test (debugging) */
11867 	if (tinfo->vnt_data) {
11868 		byte = *((char *)tinfo->vnt_data);
11869 	}
11870 #endif
11871 	rp = kalloc_type(struct vnode_resolve, Z_WAITOK | Z_NOFAIL);
11872 
11873 	lck_mtx_init(&rp->vr_lock, &trigger_vnode_lck_grp, &trigger_vnode_lck_attr);
11874 
11875 	rp->vr_resolve_func = tinfo->vnt_resolve_func;
11876 	rp->vr_unresolve_func = tinfo->vnt_unresolve_func;
11877 	rp->vr_rearm_func = tinfo->vnt_rearm_func;
11878 	rp->vr_reclaim_func = tinfo->vnt_reclaim_func;
11879 	rp->vr_data = tinfo->vnt_data;
11880 	rp->vr_lastseq = 0;
11881 	rp->vr_flags = tinfo->vnt_flags & VNT_VALID_MASK;
11882 	if (external) {
11883 		rp->vr_flags |= VNT_EXTERNAL;
11884 	}
11885 
11886 	result = vnode_resolver_attach(vp, rp, external);
11887 	if (result != 0) {
11888 		goto out;
11889 	}
11890 
11891 	if (mp) {
11892 		OSAddAtomic(1, &mp->mnt_numtriggers);
11893 	}
11894 
11895 	return result;
11896 
11897 out:
11898 	kfree_type(struct vnode_resolve, rp);
11899 	return result;
11900 }
11901 
11902 static void
vnode_resolver_release(vnode_resolve_t rp)11903 vnode_resolver_release(vnode_resolve_t rp)
11904 {
11905 	/*
11906 	 * Give them a chance to free any private data
11907 	 */
11908 	if (rp->vr_data && rp->vr_reclaim_func) {
11909 		rp->vr_reclaim_func(NULLVP, rp->vr_data);
11910 	}
11911 
11912 	lck_mtx_destroy(&rp->vr_lock, &trigger_vnode_lck_grp);
11913 	kfree_type(struct vnode_resolve, rp);
11914 }
11915 
11916 /* Called after the vnode has been drained */
11917 static void
vnode_resolver_detach(vnode_t vp)11918 vnode_resolver_detach(vnode_t vp)
11919 {
11920 	vnode_resolve_t rp;
11921 	mount_t mp;
11922 
11923 	mp = vnode_mount(vp);
11924 
11925 	vnode_lock(vp);
11926 	rp = vp->v_resolve;
11927 	vp->v_resolve = NULL;
11928 	vnode_unlock(vp);
11929 
11930 	if ((rp->vr_flags & VNT_EXTERNAL) != 0) {
11931 		vnode_rele_ext(vp, O_EVTONLY, 1);
11932 	}
11933 
11934 	vnode_resolver_release(rp);
11935 
11936 	/* Keep count of active trigger vnodes per mount */
11937 	OSAddAtomic(-1, &mp->mnt_numtriggers);
11938 }
11939 
11940 __private_extern__
11941 void
vnode_trigger_rearm(vnode_t vp,vfs_context_t ctx)11942 vnode_trigger_rearm(vnode_t vp, vfs_context_t ctx)
11943 {
11944 	vnode_resolve_t rp;
11945 	resolver_result_t result;
11946 	enum resolver_status status;
11947 	uint32_t seq;
11948 
11949 	if ((vp->v_resolve == NULL) ||
11950 	    (vp->v_resolve->vr_rearm_func == NULL) ||
11951 	    (vp->v_resolve->vr_flags & VNT_AUTO_REARM) == 0) {
11952 		return;
11953 	}
11954 
11955 	rp = vp->v_resolve;
11956 	lck_mtx_lock(&rp->vr_lock);
11957 
11958 	/*
11959 	 * Check if VFS initiated this unmount. If so, we'll catch it after the unresolve completes.
11960 	 */
11961 	if (rp->vr_flags & VNT_VFS_UNMOUNTED) {
11962 		lck_mtx_unlock(&rp->vr_lock);
11963 		return;
11964 	}
11965 
11966 	/* Check if this vnode is already armed */
11967 	if ((rp->vr_flags & VNT_RESOLVED) == 0) {
11968 		lck_mtx_unlock(&rp->vr_lock);
11969 		return;
11970 	}
11971 
11972 	lck_mtx_unlock(&rp->vr_lock);
11973 
11974 	result = rp->vr_rearm_func(vp, 0, rp->vr_data, ctx);
11975 	status = vfs_resolver_status(result);
11976 	seq = vfs_resolver_sequence(result);
11977 
11978 	lck_mtx_lock(&rp->vr_lock);
11979 	if (seq > rp->vr_lastseq) {
11980 		if (status == RESOLVER_UNRESOLVED) {
11981 			rp->vr_flags &= ~VNT_RESOLVED;
11982 		}
11983 		rp->vr_lastseq = seq;
11984 	}
11985 	lck_mtx_unlock(&rp->vr_lock);
11986 }
11987 
11988 __private_extern__
11989 int
vnode_trigger_resolve(vnode_t vp,struct nameidata * ndp,vfs_context_t ctx)11990 vnode_trigger_resolve(vnode_t vp, struct nameidata *ndp, vfs_context_t ctx)
11991 {
11992 	vnode_resolve_t rp;
11993 	enum path_operation op;
11994 	resolver_result_t result;
11995 	enum resolver_status status;
11996 	uint32_t seq;
11997 
11998 	/*
11999 	 * N.B. we cannot call vfs_context_can_resolve_triggers()
12000 	 * here because we really only want to suppress that in
12001 	 * the event the trigger will be resolved by something in
12002 	 * user-space.  Any triggers that are resolved by the kernel
12003 	 * do not pose a threat of deadlock.
12004 	 */
12005 
12006 	/* Only trigger on topmost vnodes */
12007 	if ((vp->v_resolve == NULL) ||
12008 	    (vp->v_resolve->vr_resolve_func == NULL) ||
12009 	    (vp->v_mountedhere != NULL)) {
12010 		return 0;
12011 	}
12012 
12013 	rp = vp->v_resolve;
12014 	lck_mtx_lock(&rp->vr_lock);
12015 
12016 	/* Check if this vnode is already resolved */
12017 	if (rp->vr_flags & VNT_RESOLVED) {
12018 		lck_mtx_unlock(&rp->vr_lock);
12019 		return 0;
12020 	}
12021 
12022 	lck_mtx_unlock(&rp->vr_lock);
12023 
12024 #if CONFIG_MACF
12025 	if ((rp->vr_flags & VNT_KERN_RESOLVE) == 0) {
12026 		/*
12027 		 * VNT_KERN_RESOLVE indicates this trigger has no parameters
12028 		 * at the discression of the accessing process other than
12029 		 * the act of access. All other triggers must be checked
12030 		 */
12031 		int rv = mac_vnode_check_trigger_resolve(ctx, vp, &ndp->ni_cnd);
12032 		if (rv != 0) {
12033 			return rv;
12034 		}
12035 	}
12036 #endif
12037 
12038 	/*
12039 	 * XXX
12040 	 * assumes that resolver will not access this trigger vnode (otherwise the kernel will deadlock)
12041 	 * is there anyway to know this???
12042 	 * there can also be other legitimate lookups in parallel
12043 	 *
12044 	 * XXX - should we call this on a separate thread with a timeout?
12045 	 *
12046 	 * XXX - should we use ISLASTCN to pick the op value???  Perhaps only leafs should
12047 	 * get the richer set and non-leafs should get generic OP_LOOKUP?  TBD
12048 	 */
12049 	op = (ndp->ni_op < OP_MAXOP) ? ndp->ni_op: OP_LOOKUP;
12050 
12051 	result = rp->vr_resolve_func(vp, &ndp->ni_cnd, op, 0, rp->vr_data, ctx);
12052 	status = vfs_resolver_status(result);
12053 	seq = vfs_resolver_sequence(result);
12054 
12055 	lck_mtx_lock(&rp->vr_lock);
12056 	if (seq > rp->vr_lastseq) {
12057 		if (status == RESOLVER_RESOLVED) {
12058 			rp->vr_flags |= VNT_RESOLVED;
12059 		}
12060 		rp->vr_lastseq = seq;
12061 	}
12062 	lck_mtx_unlock(&rp->vr_lock);
12063 
12064 	/* On resolver errors, propagate the error back up */
12065 	return status == RESOLVER_ERROR ? vfs_resolver_auxiliary(result) : 0;
12066 }
12067 
12068 static int
vnode_trigger_unresolve(vnode_t vp,int flags,vfs_context_t ctx)12069 vnode_trigger_unresolve(vnode_t vp, int flags, vfs_context_t ctx)
12070 {
12071 	vnode_resolve_t rp;
12072 	resolver_result_t result;
12073 	enum resolver_status status;
12074 	uint32_t seq;
12075 
12076 	if ((vp->v_resolve == NULL) || (vp->v_resolve->vr_unresolve_func == NULL)) {
12077 		return 0;
12078 	}
12079 
12080 	rp = vp->v_resolve;
12081 	lck_mtx_lock(&rp->vr_lock);
12082 
12083 	/* Check if this vnode is already resolved */
12084 	if ((rp->vr_flags & VNT_RESOLVED) == 0) {
12085 		printf("vnode_trigger_unresolve: not currently resolved\n");
12086 		lck_mtx_unlock(&rp->vr_lock);
12087 		return 0;
12088 	}
12089 
12090 	rp->vr_flags |= VNT_VFS_UNMOUNTED;
12091 
12092 	lck_mtx_unlock(&rp->vr_lock);
12093 
12094 	/*
12095 	 * XXX
12096 	 * assumes that resolver will not access this trigger vnode (otherwise the kernel will deadlock)
12097 	 * there can also be other legitimate lookups in parallel
12098 	 *
12099 	 * XXX - should we call this on a separate thread with a timeout?
12100 	 */
12101 
12102 	result = rp->vr_unresolve_func(vp, flags, rp->vr_data, ctx);
12103 	status = vfs_resolver_status(result);
12104 	seq = vfs_resolver_sequence(result);
12105 
12106 	lck_mtx_lock(&rp->vr_lock);
12107 	if (seq > rp->vr_lastseq) {
12108 		if (status == RESOLVER_UNRESOLVED) {
12109 			rp->vr_flags &= ~VNT_RESOLVED;
12110 		}
12111 		rp->vr_lastseq = seq;
12112 	}
12113 	rp->vr_flags &= ~VNT_VFS_UNMOUNTED;
12114 	lck_mtx_unlock(&rp->vr_lock);
12115 
12116 	/* On resolver errors, propagate the error back up */
12117 	return status == RESOLVER_ERROR ? vfs_resolver_auxiliary(result) : 0;
12118 }
12119 
12120 static int
triggerisdescendant(mount_t mp,mount_t rmp)12121 triggerisdescendant(mount_t mp, mount_t rmp)
12122 {
12123 	int match = FALSE;
12124 
12125 	/*
12126 	 * walk up vnode covered chain looking for a match
12127 	 */
12128 	name_cache_lock_shared();
12129 
12130 	while (1) {
12131 		vnode_t vp;
12132 
12133 		/* did we encounter "/" ? */
12134 		if (mp->mnt_flag & MNT_ROOTFS) {
12135 			break;
12136 		}
12137 
12138 		vp = mp->mnt_vnodecovered;
12139 		if (vp == NULLVP) {
12140 			break;
12141 		}
12142 
12143 		mp = vp->v_mount;
12144 		if (mp == rmp) {
12145 			match = TRUE;
12146 			break;
12147 		}
12148 	}
12149 
12150 	name_cache_unlock();
12151 
12152 	return match;
12153 }
12154 
12155 struct trigger_unmount_info {
12156 	vfs_context_t   ctx;
12157 	mount_t         top_mp;
12158 	vnode_t         trigger_vp;
12159 	mount_t         trigger_mp;
12160 	uint32_t        trigger_vid;
12161 	int             flags;
12162 };
12163 
12164 static int
trigger_unmount_callback(mount_t mp,void * arg)12165 trigger_unmount_callback(mount_t mp, void * arg)
12166 {
12167 	struct trigger_unmount_info * infop = (struct trigger_unmount_info *)arg;
12168 	boolean_t mountedtrigger = FALSE;
12169 
12170 	/*
12171 	 * When we encounter the top level mount we're done
12172 	 */
12173 	if (mp == infop->top_mp) {
12174 		return VFS_RETURNED_DONE;
12175 	}
12176 
12177 	if ((mp->mnt_vnodecovered == NULL) ||
12178 	    (vnode_getwithref(mp->mnt_vnodecovered) != 0)) {
12179 		return VFS_RETURNED;
12180 	}
12181 
12182 	if ((mp->mnt_vnodecovered->v_mountedhere == mp) &&
12183 	    (mp->mnt_vnodecovered->v_resolve != NULL) &&
12184 	    (mp->mnt_vnodecovered->v_resolve->vr_flags & VNT_RESOLVED)) {
12185 		mountedtrigger = TRUE;
12186 	}
12187 	vnode_put(mp->mnt_vnodecovered);
12188 
12189 	/*
12190 	 * When we encounter a mounted trigger, check if its under the top level mount
12191 	 */
12192 	if (!mountedtrigger || !triggerisdescendant(mp, infop->top_mp)) {
12193 		return VFS_RETURNED;
12194 	}
12195 
12196 	/*
12197 	 * Process any pending nested mount (now that its not referenced)
12198 	 */
12199 	if ((infop->trigger_vp != NULLVP) &&
12200 	    (vnode_getwithvid(infop->trigger_vp, infop->trigger_vid) == 0)) {
12201 		vnode_t vp = infop->trigger_vp;
12202 		int error;
12203 
12204 		vnode_drop(infop->trigger_vp);
12205 		infop->trigger_vp = NULLVP;
12206 
12207 		if (mp == vp->v_mountedhere) {
12208 			vnode_put(vp);
12209 			printf("trigger_unmount_callback: unexpected match '%s'\n",
12210 			    mp->mnt_vfsstat.f_mntonname);
12211 			return VFS_RETURNED;
12212 		}
12213 		if (infop->trigger_mp != vp->v_mountedhere) {
12214 			vnode_put(vp);
12215 			printf("trigger_unmount_callback: trigger mnt changed! (%p != %p)\n",
12216 			    infop->trigger_mp, vp->v_mountedhere);
12217 			goto savenext;
12218 		}
12219 
12220 		error = vnode_trigger_unresolve(vp, infop->flags, infop->ctx);
12221 		vnode_put(vp);
12222 		if (error) {
12223 			printf("unresolving: '%s', err %d\n",
12224 			    vp->v_mountedhere ? vp->v_mountedhere->mnt_vfsstat.f_mntonname :
12225 			    "???", error);
12226 			return VFS_RETURNED_DONE; /* stop iteration on errors */
12227 		}
12228 	} else if (infop->trigger_vp != NULLVP) {
12229 		vnode_drop(infop->trigger_vp);
12230 	}
12231 
12232 savenext:
12233 	/*
12234 	 * We can't call resolver here since we hold a mount iter
12235 	 * ref on mp so save its covered vp for later processing
12236 	 */
12237 	infop->trigger_vp = mp->mnt_vnodecovered;
12238 	if ((infop->trigger_vp != NULLVP) &&
12239 	    (vnode_getwithref(infop->trigger_vp) == 0)) {
12240 		if (infop->trigger_vp->v_mountedhere == mp) {
12241 			infop->trigger_vid = infop->trigger_vp->v_id;
12242 			vnode_hold(infop->trigger_vp);
12243 			infop->trigger_mp = mp;
12244 		}
12245 		vnode_put(infop->trigger_vp);
12246 	}
12247 
12248 	return VFS_RETURNED;
12249 }
12250 
12251 /*
12252  * Attempt to unmount any trigger mounts nested underneath a mount.
12253  * This is a best effort attempt and no retries are performed here.
12254  *
12255  * Note: mp->mnt_rwlock is held exclusively on entry (so be carefull)
12256  */
12257 __private_extern__
12258 void
vfs_nested_trigger_unmounts(mount_t mp,int flags,vfs_context_t ctx)12259 vfs_nested_trigger_unmounts(mount_t mp, int flags, vfs_context_t ctx)
12260 {
12261 	struct trigger_unmount_info info;
12262 
12263 	/* Must have trigger vnodes */
12264 	if (mp->mnt_numtriggers == 0) {
12265 		return;
12266 	}
12267 	/* Avoid recursive requests (by checking covered vnode) */
12268 	if ((mp->mnt_vnodecovered != NULL) &&
12269 	    (vnode_getwithref(mp->mnt_vnodecovered) == 0)) {
12270 		boolean_t recursive = FALSE;
12271 
12272 		if ((mp->mnt_vnodecovered->v_mountedhere == mp) &&
12273 		    (mp->mnt_vnodecovered->v_resolve != NULL) &&
12274 		    (mp->mnt_vnodecovered->v_resolve->vr_flags & VNT_VFS_UNMOUNTED)) {
12275 			recursive = TRUE;
12276 		}
12277 		vnode_put(mp->mnt_vnodecovered);
12278 		if (recursive) {
12279 			return;
12280 		}
12281 	}
12282 
12283 	/*
12284 	 * Attempt to unmount any nested trigger mounts (best effort)
12285 	 */
12286 	info.ctx = ctx;
12287 	info.top_mp = mp;
12288 	info.trigger_vp = NULLVP;
12289 	info.trigger_vid = 0;
12290 	info.trigger_mp = NULL;
12291 	info.flags = flags;
12292 
12293 	(void) vfs_iterate(VFS_ITERATE_TAIL_FIRST, trigger_unmount_callback, &info);
12294 
12295 	/*
12296 	 * Process remaining nested mount (now that its not referenced)
12297 	 */
12298 	if ((info.trigger_vp != NULLVP) &&
12299 	    (vnode_getwithvid(info.trigger_vp, info.trigger_vid) == 0)) {
12300 		vnode_t vp = info.trigger_vp;
12301 
12302 		if (info.trigger_mp == vp->v_mountedhere) {
12303 			(void) vnode_trigger_unresolve(vp, flags, ctx);
12304 		}
12305 		vnode_put(vp);
12306 		vnode_drop(vp);
12307 	} else if (info.trigger_vp != NULLVP) {
12308 		vnode_drop(info.trigger_vp);
12309 	}
12310 }
12311 
12312 int
vfs_addtrigger(mount_t mp,const char * relpath,struct vnode_trigger_info * vtip,vfs_context_t ctx)12313 vfs_addtrigger(mount_t mp, const char *relpath, struct vnode_trigger_info *vtip, vfs_context_t ctx)
12314 {
12315 	struct nameidata *ndp;
12316 	int res;
12317 	vnode_t rvp, vp;
12318 	struct vnode_trigger_param vtp;
12319 
12320 	/*
12321 	 * Must be called for trigger callback, wherein rwlock is held
12322 	 */
12323 	lck_rw_assert(&mp->mnt_rwlock, LCK_RW_ASSERT_HELD);
12324 
12325 	TRIG_LOG("Adding trigger at %s\n", relpath);
12326 	TRIG_LOG("Trying VFS_ROOT\n");
12327 
12328 	ndp = kalloc_type(struct nameidata, Z_WAITOK | Z_NOFAIL);
12329 
12330 	/*
12331 	 * We do a lookup starting at the root of the mountpoint, unwilling
12332 	 * to cross into other mountpoints.
12333 	 */
12334 	res = VFS_ROOT(mp, &rvp, ctx);
12335 	if (res != 0) {
12336 		goto out;
12337 	}
12338 
12339 	TRIG_LOG("Trying namei\n");
12340 
12341 	NDINIT(ndp, LOOKUP, OP_LOOKUP, USEDVP | NOCROSSMOUNT | FOLLOW, UIO_SYSSPACE,
12342 	    CAST_USER_ADDR_T(relpath), ctx);
12343 	ndp->ni_dvp = rvp;
12344 	res = namei(ndp);
12345 	if (res != 0) {
12346 		vnode_put(rvp);
12347 		goto out;
12348 	}
12349 
12350 	vp = ndp->ni_vp;
12351 	nameidone(ndp);
12352 	vnode_put(rvp);
12353 
12354 	TRIG_LOG("Trying vnode_resolver_create()\n");
12355 
12356 	/*
12357 	 * Set up blob.  vnode_create() takes a larger structure
12358 	 * with creation info, and we needed something different
12359 	 * for this case.  One needs to win, or we need to munge both;
12360 	 * vnode_create() wins.
12361 	 */
12362 	bzero(&vtp, sizeof(vtp));
12363 	vtp.vnt_resolve_func = vtip->vti_resolve_func;
12364 	vtp.vnt_unresolve_func = vtip->vti_unresolve_func;
12365 	vtp.vnt_rearm_func = vtip->vti_rearm_func;
12366 	vtp.vnt_reclaim_func = vtip->vti_reclaim_func;
12367 	vtp.vnt_reclaim_func = vtip->vti_reclaim_func;
12368 	vtp.vnt_data = vtip->vti_data;
12369 	vtp.vnt_flags = vtip->vti_flags;
12370 
12371 	res = vnode_resolver_create(mp, vp, &vtp, TRUE);
12372 	vnode_put(vp);
12373 out:
12374 	kfree_type(struct nameidata, ndp);
12375 	TRIG_LOG("Returning %d\n", res);
12376 	return res;
12377 }
12378 
12379 #endif /* CONFIG_TRIGGERS */
12380 
12381 vm_offset_t
kdebug_vnode(vnode_t vp)12382 kdebug_vnode(vnode_t vp)
12383 {
12384 	return VM_KERNEL_ADDRPERM(vp);
12385 }
12386 
12387 static int flush_cache_on_write = 0;
12388 SYSCTL_INT(_kern, OID_AUTO, flush_cache_on_write,
12389     CTLFLAG_RW | CTLFLAG_LOCKED, &flush_cache_on_write, 0,
12390     "always flush the drive cache on writes to uncached files");
12391 
12392 int
vnode_should_flush_after_write(vnode_t vp,int ioflag)12393 vnode_should_flush_after_write(vnode_t vp, int ioflag)
12394 {
12395 	return flush_cache_on_write
12396 	       && (ISSET(ioflag, IO_NOCACHE) || vnode_isnocache(vp));
12397 }
12398 
12399 /*
12400  * sysctl for use by disk I/O tracing tools to get the list of existing
12401  * vnodes' paths
12402  */
12403 
12404 #define NPATH_WORDS (MAXPATHLEN / sizeof(unsigned long))
12405 struct vnode_trace_paths_context {
12406 	uint64_t count;
12407 	/*
12408 	 * Must be a multiple of 4, then -1, for tracing!
12409 	 */
12410 	unsigned long path[NPATH_WORDS + (4 - (NPATH_WORDS % 4)) - 1];
12411 };
12412 
12413 static int
vnode_trace_path_callback(struct vnode * vp,void * vctx)12414 vnode_trace_path_callback(struct vnode *vp, void *vctx)
12415 {
12416 	struct vnode_trace_paths_context *ctx = vctx;
12417 	size_t path_len = sizeof(ctx->path);
12418 
12419 	int getpath_len = (int)path_len;
12420 	if (vn_getpath(vp, (char *)ctx->path, &getpath_len) == 0) {
12421 		/* vn_getpath() NUL-terminates, and len includes the NUL. */
12422 		assert(getpath_len >= 0);
12423 		path_len = (size_t)getpath_len;
12424 
12425 		assert(path_len <= sizeof(ctx->path));
12426 		kdebug_vfs_lookup(ctx->path, (int)path_len, vp,
12427 		    KDBG_VFS_LOOKUP_FLAG_LOOKUP | KDBG_VFS_LOOKUP_FLAG_NOPROCFILT);
12428 
12429 		if (++(ctx->count) == 1000) {
12430 			thread_yield_to_preemption();
12431 			ctx->count = 0;
12432 		}
12433 	}
12434 
12435 	return VNODE_RETURNED;
12436 }
12437 
12438 static int
vfs_trace_paths_callback(mount_t mp,void * arg)12439 vfs_trace_paths_callback(mount_t mp, void *arg)
12440 {
12441 	if (mp->mnt_flag & MNT_LOCAL) {
12442 		vnode_iterate(mp, VNODE_ITERATE_ALL, vnode_trace_path_callback, arg);
12443 	}
12444 
12445 	return VFS_RETURNED;
12446 }
12447 
12448 static int sysctl_vfs_trace_paths SYSCTL_HANDLER_ARGS {
12449 	struct vnode_trace_paths_context ctx;
12450 
12451 	(void)oidp;
12452 	(void)arg1;
12453 	(void)arg2;
12454 	(void)req;
12455 
12456 	if (!kauth_cred_issuser(kauth_cred_get())) {
12457 		return EPERM;
12458 	}
12459 
12460 	if (!kdebug_enable || !kdebug_debugid_enabled(VFS_LOOKUP)) {
12461 		return EINVAL;
12462 	}
12463 
12464 	bzero(&ctx, sizeof(struct vnode_trace_paths_context));
12465 
12466 	vfs_iterate(0, vfs_trace_paths_callback, &ctx);
12467 
12468 	return 0;
12469 }
12470 
12471 SYSCTL_PROC(_vfs_generic, OID_AUTO, trace_paths, CTLFLAG_RD | CTLFLAG_LOCKED | CTLFLAG_MASKED, NULL, 0, &sysctl_vfs_trace_paths, "-", "trace_paths");
12472 
12473 #if CONFIG_FILE_LEASES
12474 #include <IOKit/IOBSD.h>
12475 #include <sys/file_internal.h>
12476 
12477 #define FILE_LEASES_ENTITLEMENT    "com.apple.private.vfs.file-leases"
12478 
12479 static uint32_t lease_break_timeout = 60; /* secs */
12480 
12481 #if (DEVELOPMENT || DEBUG)
12482 static int lease_debug = 0;
12483 static int lease_entitlement_override = 0;
12484 
12485 SYSCTL_NODE(_vfs, OID_AUTO, lease, CTLFLAG_RW | CTLFLAG_LOCKED, NULL, "vfs lease");
12486 SYSCTL_UINT(_vfs_lease, OID_AUTO, break_timeout, CTLFLAG_RW | CTLFLAG_LOCKED, &lease_break_timeout, 0, "");
12487 SYSCTL_INT(_vfs_lease, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_LOCKED, &lease_debug, 0, "");
12488 SYSCTL_INT(_vfs_lease, OID_AUTO, entitlement_override, CTLFLAG_RW | CTLFLAG_LOCKED, &lease_entitlement_override, 0, "");
12489 
12490 #define LEASEDBG(fmt, args...)                                       \
12491 do {                                                                 \
12492 	if (__improbable(lease_debug)) {                                 \
12493 	        pid_t cur_pid = proc_getpid(current_proc());             \
12494 	        printf("%s(%d): " fmt "\n", __func__, cur_pid, ##args);  \
12495 	}                                                                \
12496 } while(0)
12497 #else
12498 #define LEASEDBG(fmt, args...)  /**/
12499 #endif /* (DEVELOPMENT || DEBUG) */
12500 
12501 static bool
allow_setlease(vfs_context_t ctx)12502 allow_setlease(vfs_context_t ctx)
12503 {
12504 	bool entitled;
12505 
12506 	entitled = IOTaskHasEntitlement(vfs_context_task(ctx),
12507 	    FILE_LEASES_ENTITLEMENT);
12508 
12509 #if (DEVELOPMENT || DEBUG)
12510 	if (!entitled) {
12511 		entitled = (lease_entitlement_override == 1);
12512 	}
12513 #endif
12514 
12515 	return entitled;
12516 }
12517 
12518 static file_lease_t
file_lease_alloc(struct fileglob * fg,int fl_type,pid_t pid)12519 file_lease_alloc(struct fileglob *fg, int fl_type, pid_t pid)
12520 {
12521 	file_lease_t fl;
12522 
12523 	fl = kalloc_type(struct file_lease, Z_WAITOK);
12524 	/*
12525 	 * Duplicated file descriptors created by dup() or fork() would have the
12526 	 * same 'fileglob' so the lease can be released or modified with the
12527 	 * duplicated fds. Opening the same file (by either same or different
12528 	 * process) would have different 'fileglob' so a lease always follows a
12529 	 * 'fileglob'.
12530 	 */
12531 	fl->fl_fg = fg;
12532 	fl->fl_type = fl_type;
12533 	fl->fl_pid = pid;
12534 	fl->fl_downgrade_start = fl->fl_release_start = 0;
12535 
12536 	return fl;
12537 }
12538 
12539 static void
file_lease_free(file_lease_t fl)12540 file_lease_free(file_lease_t fl)
12541 {
12542 	kfree_type(struct file_lease, fl);
12543 }
12544 
12545 /*
12546  * A read lease can be placed only on a file/directory that is opened for
12547  * read-only which means no other processes have the file/directory opened in
12548  * read-write/write-only mode or mmap'ed writable.
12549  * A write lease can be placed on a file only if there are no other opens
12550  * for the file.
12551  *
12552  * Needs to be called with vnode's lock held.
12553  */
12554 static int
check_for_open_conflict(vnode_t vp,struct fileglob * fg,int fl_type,int expcounts)12555 check_for_open_conflict(vnode_t vp, struct fileglob *fg, int fl_type,
12556     int expcounts)
12557 {
12558 	int error = 0;
12559 
12560 	if (fl_type == F_RDLCK) {
12561 		if (vp->v_writecount > expcounts &&
12562 		    !(vp->v_writecount == 1 && (fg->fg_flag & FWRITE))) {
12563 			error = EAGAIN;
12564 		} else if (ubc_is_mapped_writable(vp)) {
12565 			error = EAGAIN;
12566 		}
12567 	} else if (fl_type == F_WRLCK && vp->v_usecount > expcounts) {
12568 		error = EAGAIN;
12569 	}
12570 
12571 	return error;
12572 }
12573 
12574 /* Needs to be called with vnode's lock held. */
12575 static void
modify_file_lease(vnode_t vp,file_lease_t fl,int new_fl_type,struct fileglob * new_fg)12576 modify_file_lease(vnode_t vp, file_lease_t fl, int new_fl_type,
12577     struct fileglob *new_fg)
12578 {
12579 	LEASEDBG("fl %p changing fl_type from %d to %d (flags 0x%x)",
12580 	    fl, fl->fl_type, new_fl_type, fl->fl_flags);
12581 
12582 	fl->fl_type = new_fl_type;
12583 
12584 	/*
12585 	 * The lease being modified may be using a different file
12586 	 * descriptor, so usurp the fileglob pointer here.  In this
12587 	 * case the old descriptor no longer holds the lease.
12588 	 */
12589 	if (new_fg != NULL) {
12590 		fl->fl_fg = new_fg;
12591 	}
12592 
12593 	if (fl->fl_flags & FL_FLAG_RELEASE_PENDING ||
12594 	    fl->fl_flags & FL_FLAG_DOWNGRADE_PENDING) {
12595 		wakeup(&vp->v_leases);
12596 	}
12597 }
12598 
12599 static int
acquire_file_lease(vnode_t vp,struct fileglob * fg,int fl_type,int expcounts,vfs_context_t ctx)12600 acquire_file_lease(vnode_t vp, struct fileglob *fg, int fl_type, int expcounts,
12601     vfs_context_t ctx)
12602 {
12603 	file_lease_t fl, new_fl, our_fl;
12604 	int error;
12605 
12606 	/* Make sure "expected count" looks sane. */
12607 	if (expcounts < 0 || expcounts > OPEN_MAX) {
12608 		return EINVAL;
12609 	}
12610 
12611 	new_fl = file_lease_alloc(fg, fl_type, vfs_context_pid(ctx));
12612 
12613 	vnode_lock(vp);
12614 
12615 	error = check_for_open_conflict(vp, fg, fl_type, expcounts);
12616 	if (error) {
12617 		LEASEDBG("open conflict on vp %p type %d writecnt %d usecnt %d "
12618 		    "fl_type %d expcounts %d",
12619 		    vp, vp->v_type, vp->v_writecount, vp->v_usecount, fl_type,
12620 		    expcounts);
12621 		goto out;
12622 	}
12623 
12624 	our_fl = NULL;
12625 	LIST_FOREACH(fl, &vp->v_leases, fl_link) {
12626 		/* Does the existing lease belong to us? */
12627 		if (fl->fl_fg == new_fl->fl_fg ||
12628 		    fl->fl_pid == new_fl->fl_pid) {
12629 			our_fl = fl;
12630 			continue;
12631 		}
12632 
12633 		/*
12634 		 * We don't allow placing a new write lease when there is an existing
12635 		 * read lease that doesn't belong to us. We also don't allow putting
12636 		 * a new read lease if there is a pending release on the lease.
12637 		 * Putting a new read lease when there is a pending downgrade on the
12638 		 * lease is fine as it won't cause lease conflict.
12639 		 */
12640 		if (fl_type == F_WRLCK || fl->fl_flags & FL_FLAG_RELEASE_PENDING) {
12641 			break;
12642 		}
12643 	}
12644 
12645 	/*
12646 	 * Found an existing lease that we don't own and it conflicts with the
12647 	 * new lease.
12648 	 */
12649 	if (fl) {
12650 		LEASEDBG("lease conflict on vp %p fl %p fl_type %d cur_fl_type %d",
12651 		    vp, fl, fl_type, fl->fl_type);
12652 		goto out;
12653 	}
12654 
12655 	/* Found an existing lease that we own so just change the type. */
12656 	if (our_fl) {
12657 		LEASEDBG("replace lease on vp %p fl %p old_fl_type %d new_fl_type %d",
12658 		    vp, our_fl, our_fl->fl_type, fl_type);
12659 
12660 		modify_file_lease(vp, our_fl, new_fl->fl_type, new_fl->fl_fg);
12661 		goto out;
12662 	}
12663 
12664 	LEASEDBG("acquired lease on vp %p type %d fl %p fl_type %d fg %p",
12665 	    vp, vp->v_type, new_fl, new_fl->fl_type, new_fl->fl_fg);
12666 
12667 	LIST_INSERT_HEAD(&vp->v_leases, new_fl, fl_link);
12668 	new_fl = NULL;
12669 
12670 out:
12671 	vnode_unlock(vp);
12672 
12673 	if (new_fl) {
12674 		file_lease_free(new_fl);
12675 	}
12676 
12677 	return error;
12678 }
12679 
12680 static int
release_file_lease(vnode_t vp,struct fileglob * fg)12681 release_file_lease(vnode_t vp, struct fileglob *fg)
12682 {
12683 	file_lease_t fl, fl_tmp;
12684 	int error = 0;
12685 
12686 	LEASEDBG("request to release lease on vp %p type %d fg %p",
12687 	    vp, vp->v_type, fg);
12688 
12689 	vnode_lock(vp);
12690 
12691 	LIST_FOREACH_SAFE(fl, &vp->v_leases, fl_link, fl_tmp) {
12692 		if (fl->fl_fg == fg) {
12693 			LEASEDBG("released lease on vp %p fl %p type %d",
12694 			    vp, fl, fl->fl_type);
12695 
12696 			LIST_REMOVE(fl, fl_link);
12697 			modify_file_lease(vp, fl, F_UNLCK, NULL);
12698 			break;
12699 		}
12700 	}
12701 
12702 	vnode_unlock(vp);
12703 
12704 	if (fl) {
12705 		file_lease_free(fl);
12706 	} else {
12707 		error = ENOLCK;
12708 	}
12709 
12710 	return error;
12711 }
12712 
12713 /*
12714  * Acquire or release a file lease according to the given type (F_RDLCK,
12715  * F_WRLCK or F_UNLCK).
12716  *
12717  * Returns:	0			Success
12718  *		EAGAIN			Failed to acquire a file lease due to conflicting opens
12719  *		ENOLCK			Failed to release a file lease due to lease not found
12720  *		EPERM           Current task doesn't have the entitlement
12721  */
12722 int
vnode_setlease(vnode_t vp,struct fileglob * fg,int fl_type,int expcounts,vfs_context_t ctx)12723 vnode_setlease(vnode_t vp, struct fileglob *fg, int fl_type, int expcounts,
12724     vfs_context_t ctx)
12725 {
12726 	int error;
12727 
12728 	if (!allow_setlease(ctx)) {
12729 		return EPERM;
12730 	}
12731 
12732 	error = (fl_type == F_UNLCK) ? release_file_lease(vp, fg) :
12733 	    acquire_file_lease(vp, fg, fl_type, expcounts, ctx);
12734 
12735 	return error;
12736 }
12737 
12738 /*
12739  * Retrieve the currently in place lease for the file.
12740  *
12741  * Returns:
12742  *		F_RDLCK			Read lease
12743  *		F_WRLCK			Write lease
12744  *		F_UNLCK			No lease
12745  */
12746 int
vnode_getlease(vnode_t vp)12747 vnode_getlease(vnode_t vp)
12748 {
12749 	file_lease_t fl;
12750 	int fl_type = F_UNLCK;
12751 
12752 	vnode_lock(vp);
12753 
12754 	/*
12755 	 * There should be only one type of lease in the list as read and write
12756 	 * leases can't co-exist for the same file.
12757 	 */
12758 	fl = LIST_FIRST(&vp->v_leases);
12759 	if (fl) {
12760 		fl_type = fl->fl_type;
12761 	}
12762 
12763 	vnode_unlock(vp);
12764 
12765 	LEASEDBG("vp %p fl %p fl_type %d", vp, fl, fl_type);
12766 
12767 	return fl_type;
12768 }
12769 
12770 /* Must be called with vnode's lock held. */
12771 static bool
check_for_lease_conflict(vnode_t vp,int breaker_fl_type,vfs_context_t ctx)12772 check_for_lease_conflict(vnode_t vp, int breaker_fl_type, vfs_context_t ctx)
12773 {
12774 	file_lease_t fl;
12775 	pid_t pid = vfs_context_pid(ctx);
12776 	bool is_conflict = false;
12777 
12778 	LIST_FOREACH(fl, &vp->v_leases, fl_link) {
12779 		if ((fl->fl_type == F_WRLCK && fl->fl_pid != pid) ||
12780 		    (breaker_fl_type == F_WRLCK && fl->fl_pid != pid)) {
12781 			LEASEDBG("conflict detected on vp %p type %d fl_type %d "
12782 			    "breaker_fl_type %d",
12783 			    vp, vp->v_type, fl->fl_type, breaker_fl_type);
12784 
12785 			is_conflict = true;
12786 			break;
12787 		}
12788 	}
12789 
12790 	return is_conflict;
12791 }
12792 
12793 static uint64_t
absolutetime_elapsed_in_secs(uint64_t start)12794 absolutetime_elapsed_in_secs(uint64_t start)
12795 {
12796 	uint64_t elapsed, elapsed_sec;
12797 	uint64_t now = mach_absolute_time();
12798 
12799 	elapsed = now - start;
12800 	absolutetime_to_nanoseconds(elapsed, &elapsed_sec);
12801 	elapsed_sec /= NSEC_PER_SEC;
12802 
12803 	return elapsed_sec;
12804 }
12805 
12806 /* Must be called with vnode's lock held. */
12807 static void
handle_lease_break_timedout(vnode_t vp)12808 handle_lease_break_timedout(vnode_t vp)
12809 {
12810 	file_lease_t fl, fl_tmp;
12811 	uint64_t elapsed_sec;
12812 
12813 	LIST_FOREACH_SAFE(fl, &vp->v_leases, fl_link, fl_tmp) {
12814 		if (fl->fl_flags & FL_FLAG_DOWNGRADE_PENDING) {
12815 			elapsed_sec = absolutetime_elapsed_in_secs(fl->fl_downgrade_start);
12816 
12817 			if (elapsed_sec >= lease_break_timeout) {
12818 				LEASEDBG("force downgrade on vp %p for fl %p elapsed %llu "
12819 				    "timeout %u", vp, fl, elapsed_sec, lease_break_timeout);
12820 
12821 				fl->fl_flags &= ~FL_FLAG_DOWNGRADE_PENDING;
12822 				fl->fl_downgrade_start = 0;
12823 				modify_file_lease(vp, fl, F_RDLCK, NULL);
12824 				continue;
12825 			}
12826 		}
12827 		if (fl->fl_flags & FL_FLAG_RELEASE_PENDING) {
12828 			elapsed_sec = absolutetime_elapsed_in_secs(fl->fl_release_start);
12829 
12830 			if (elapsed_sec >= lease_break_timeout) {
12831 				LEASEDBG("force release on vp %p for fl %p elapsed %llu "
12832 				    "timeout %u", vp, fl, elapsed_sec, lease_break_timeout);
12833 
12834 				LIST_REMOVE(fl, fl_link);
12835 				file_lease_free(fl);
12836 				continue;
12837 			}
12838 		}
12839 	}
12840 
12841 	/* Wakeup the lease breaker(s). */
12842 	wakeup(&vp->v_leases);
12843 }
12844 
12845 /* Must be called with vnode's lock held. */
12846 static void
wait_for_lease_break(vnode_t vp,int breaker_fl_type,vfs_context_t ctx)12847 wait_for_lease_break(vnode_t vp, int breaker_fl_type, vfs_context_t ctx)
12848 {
12849 	file_lease_t fl;
12850 	struct timespec ts;
12851 	uint64_t elapsed_sec, start_time;
12852 	int error;
12853 
12854 restart:
12855 	fl = LIST_FIRST(&vp->v_leases);
12856 	assert(fl);
12857 
12858 	/*
12859 	 * In a rare case it is possible that the lease that we are blocked on has
12860 	 * been released and a new lease has been put in place after we are
12861 	 * signalled to wake up. In this particular, we would treat it as no
12862 	 * conflict and proceed. This could only happen for directory leasing.
12863 	 */
12864 	if ((fl->fl_flags & (FL_FLAG_DOWNGRADE_PENDING | FL_FLAG_RELEASE_PENDING)) == 0) {
12865 		LEASEDBG("new lease in place on vp %p fl %p fl_type %d "
12866 		    "breaker_fl_type %d",
12867 		    vp, fl, fl->fl_type, breaker_fl_type);
12868 
12869 		return;
12870 	}
12871 	/*
12872 	 * Figure out which timer to use for lease break timedout as we could have
12873 	 * both timers active. If both timers active, pick the one with earliest
12874 	 * start time.
12875 	 */
12876 	if (fl->fl_release_start) {
12877 		if (fl->fl_downgrade_start == 0 ||
12878 		    fl->fl_downgrade_start < fl->fl_release_start) {
12879 			start_time = fl->fl_release_start;
12880 		} else {
12881 			start_time = fl->fl_downgrade_start;
12882 		}
12883 	} else {
12884 		start_time = fl->fl_downgrade_start;
12885 	}
12886 	assert(start_time > 0);
12887 
12888 	elapsed_sec = absolutetime_elapsed_in_secs(start_time);
12889 
12890 	LEASEDBG("elapsed_sec %llu release_start %llu downgrade_start %llu",
12891 	    elapsed_sec, fl->fl_release_start, fl->fl_downgrade_start);
12892 
12893 	ts.tv_sec = (lease_break_timeout > elapsed_sec ?
12894 	    (lease_break_timeout - elapsed_sec) : 0);
12895 	ts.tv_nsec = (ts.tv_sec == 0 ? 1 : 0);
12896 	error = msleep(&vp->v_leases, &vp->v_lock, PVFS, __func__, &ts);
12897 
12898 	if (error == 0 || error != EWOULDBLOCK) {
12899 		/*
12900 		 * Woken up due to lease is released/downgraded by lease holder.
12901 		 * We don't expect any other error from msleep() beside EWOULDBLOCK.
12902 		 * Check if there is any further conflicts. If so, then continue to
12903 		 * wait for the next conflict to resolve.
12904 		 */
12905 		if (check_for_lease_conflict(vp, breaker_fl_type, ctx)) {
12906 			goto restart;
12907 		}
12908 	} else {
12909 		/*
12910 		 * Woken due to lease break timeout expired (EWOULDBLOCK returned).
12911 		 * Break/downgrade all conflicting leases.
12912 		 */
12913 		handle_lease_break_timedout(vp);
12914 
12915 		if (check_for_lease_conflict(vp, breaker_fl_type, ctx)) {
12916 			goto restart;
12917 		}
12918 	}
12919 }
12920 
12921 /* Must be called with vnode's lock held. */
12922 static void
send_lease_break_event(vnode_t vp,uint32_t event)12923 send_lease_break_event(vnode_t vp, uint32_t event)
12924 {
12925 	if (vp->v_knotes.slh_first != NULL) {
12926 		KNOTE(&vp->v_knotes, event);
12927 	}
12928 }
12929 
12930 static bool
is_dataless_file(vnode_t vp,vfs_context_t ctx)12931 is_dataless_file(vnode_t vp, vfs_context_t ctx)
12932 {
12933 	struct vnode_attr va;
12934 	bool is_dataless = false;
12935 	int error;
12936 
12937 	VATTR_INIT(&va);
12938 	VATTR_WANTED(&va, va_flags);
12939 
12940 	error = vnode_getattr(vp, &va, ctx);
12941 	if (!error && (va.va_flags & SF_DATALESS)) {
12942 		is_dataless = true;
12943 	}
12944 
12945 	return is_dataless;
12946 }
12947 
12948 /*
12949  * Break lease(s) in place for the file when there is conflict.
12950  * This function would return 0 for almost all call sites. The only exception
12951  * is when it is called from open1() with O_NONBLOCK flag and it needs to block
12952  * waiting for the lease conflict(s) to resolve. In this case EWOULDBLOCK is
12953  * returned.
12954  */
12955 int
vnode_breaklease(vnode_t vp,uint32_t oflags,vfs_context_t ctx)12956 vnode_breaklease(vnode_t vp, uint32_t oflags, vfs_context_t ctx)
12957 {
12958 	file_lease_t fl;
12959 	uint64_t now;
12960 	int fl_type;
12961 	int error = 0;
12962 
12963 	vnode_lock(vp);
12964 
12965 	if (__probable(LIST_EMPTY(&vp->v_leases))) {
12966 		goto out_unlock;
12967 	}
12968 
12969 	/* Determine the access mode requested by the lease breaker. */
12970 	fl_type = (oflags & (O_WRONLY | O_RDWR | O_CREAT | O_TRUNC)) ? F_WRLCK : F_RDLCK;
12971 
12972 	/*
12973 	 * If the lease-breaker is just reading, check that it can break
12974 	 * leases first. If the lease-breaker is writing, or if the
12975 	 * context was not specified, we always break.
12976 	 * We skip lease break if the lease-breaker is dataless manipulator and
12977 	 * the file is dataless.
12978 	 */
12979 	if ((fl_type == F_RDLCK && !vfs_context_can_break_leases(ctx)) ||
12980 	    (vfs_context_is_dataless_manipulator(ctx) && (vp->v_type == VREG) &&
12981 	    is_dataless_file(vp, ctx))) {
12982 		goto out_unlock;
12983 	}
12984 
12985 	if (!check_for_lease_conflict(vp, fl_type, ctx)) {
12986 		goto out_unlock;
12987 	}
12988 
12989 	now = mach_absolute_time();
12990 
12991 	LEASEDBG("break lease on vp %p type %d oflags 0x%x cur_time %llu",
12992 	    vp, vp->v_type, oflags, now);
12993 
12994 	/*
12995 	 * We get to this point then this means all lease(s) are conflict and
12996 	 * we need to send the lease break event to the lease holder(s).
12997 	 * It is possible that a lease could have both downgrade and release events
12998 	 * pending triggered by multiple breakers trying to open the file in
12999 	 * different modes. Both events would have different lease break timers.
13000 	 * Consider the following case:
13001 	 * 1. Process A holds the write lease on file X.
13002 	 * 2. Provess B opens the file X in read-only mode.
13003 	 *    This triggers downgrade lease event to Process A.
13004 	 * 3. While downgrade is pending, Process C opens the file X in read-write
13005 	 *    mode. This triggers release lease event to Process A.
13006 	 */
13007 	LIST_FOREACH(fl, &vp->v_leases, fl_link) {
13008 		if (fl_type == F_WRLCK) {
13009 			/* File is opened for writing or truncate. */
13010 			if (fl->fl_flags & FL_FLAG_RELEASE_PENDING) {
13011 				continue;
13012 			}
13013 			fl->fl_release_start = now;
13014 			fl->fl_flags |= FL_FLAG_RELEASE_PENDING;
13015 			send_lease_break_event(vp, NOTE_LEASE_RELEASE);
13016 		} else {
13017 			/* File is opened for reading. */
13018 			if (fl->fl_flags & FL_FLAG_DOWNGRADE_PENDING ||
13019 			    fl->fl_flags & FL_FLAG_RELEASE_PENDING) {
13020 				continue;
13021 			}
13022 			fl->fl_downgrade_start = now;
13023 			fl->fl_flags |= FL_FLAG_DOWNGRADE_PENDING;
13024 			send_lease_break_event(vp, NOTE_LEASE_DOWNGRADE);
13025 		}
13026 	}
13027 
13028 	/*
13029 	 * If open is requested with O_NONBLOCK, then we can't block and wait for
13030 	 * the lease to be released/downgraded. Just bail out with EWOULDBLOCK.
13031 	 */
13032 	if (oflags & O_NONBLOCK) {
13033 		error = EWOULDBLOCK;
13034 		goto out;
13035 	}
13036 
13037 	wait_for_lease_break(vp, fl_type, ctx);
13038 
13039 out:
13040 	LEASEDBG("break lease on vp %p oflags 0x%x, error %d", vp, oflags, error);
13041 
13042 out_unlock:
13043 	vnode_unlock(vp);
13044 
13045 	return error;
13046 }
13047 
13048 /*
13049  * Get parent vnode by parent ID (only for file system that supports
13050  * MNTK_PATH_FROM_ID).
13051  * On success, the parent's vnode is returned with iocount held.
13052  */
13053 static vnode_t
vnode_getparent_byid(vnode_t vp)13054 vnode_getparent_byid(vnode_t vp)
13055 {
13056 	struct vnode_attr va;
13057 	vnode_t dvp = NULLVP;
13058 	vfs_context_t ctx = vfs_context_current();
13059 	int error;
13060 
13061 	if (!(vp->v_mount->mnt_kern_flag & MNTK_PATH_FROM_ID)) {
13062 		goto out;
13063 	}
13064 
13065 	VATTR_INIT(&va);
13066 	VATTR_WANTED(&va, va_parentid);
13067 
13068 	/* Get the vnode's parent id from the file system. */
13069 	error = vnode_getattr(vp, &va, ctx);
13070 	if (error || !VATTR_IS_SUPPORTED(&va, va_parentid)) {
13071 		goto out;
13072 	}
13073 
13074 	/*
13075 	 * Ask the file system for the parent vnode.
13076 	 * We are ignoring the error here as we don't expect the parent vnode to be
13077 	 * populated on error.
13078 	 */
13079 	(void)VFS_VGET(vp->v_mount, (ino64_t)va.va_parentid, &dvp, ctx);
13080 
13081 out:
13082 	return dvp;
13083 }
13084 
13085 /*
13086  * Break directory's lease.
13087  * If 'need_parent' is true, then parent is obtained via vnode_getparent() (or
13088  * vnode_getparent_byid()) on the provided 'vp'.
13089  */
13090 void
vnode_breakdirlease(vnode_t vp,bool need_parent,uint32_t oflags)13091 vnode_breakdirlease(vnode_t vp, bool need_parent, uint32_t oflags)
13092 {
13093 	vnode_t dvp;
13094 
13095 	if ((vnode_vtype(vp) != VREG && vnode_vtype(vp) != VDIR) ||
13096 	    (vp == rootvnode)) {
13097 		return;
13098 	}
13099 
13100 	/*
13101 	 * If parent is not provided, first try to get it from the name cache.
13102 	 * If failed, then we will attempt to ask the file system for parent vnode.
13103 	 * This is just a best effort as both attempts could still fail.
13104 	 */
13105 	if (need_parent) {
13106 		dvp = vnode_getparent(vp);
13107 		if (__improbable(dvp == NULLVP)) {
13108 			dvp = vnode_getparent_byid(vp);
13109 		}
13110 	} else {
13111 		dvp = vp;
13112 	}
13113 
13114 	if (__probable(dvp != NULLVP)) {
13115 		/* Always break dir leases. */
13116 		(void)vnode_breaklease(dvp, oflags, vfs_context_current());
13117 	}
13118 
13119 	if (need_parent && (dvp != NULLVP)) {
13120 		vnode_put(dvp);
13121 	}
13122 }
13123 
13124 /*
13125  * Revoke all lease(s) in place for the file.
13126  * This is called when the vnode is reclaimed.
13127  */
13128 void
vnode_revokelease(vnode_t vp,bool locked)13129 vnode_revokelease(vnode_t vp, bool locked)
13130 {
13131 	file_lease_t fl, fl_tmp;
13132 	bool need_wakeup = false;
13133 
13134 	if ((vnode_vtype(vp) != VREG && vnode_vtype(vp) != VDIR)) {
13135 		return;
13136 	}
13137 
13138 	if (!locked) {
13139 		vnode_lock(vp);
13140 	}
13141 
13142 	LIST_FOREACH_SAFE(fl, &vp->v_leases, fl_link, fl_tmp) {
13143 		LIST_REMOVE(fl, fl_link);
13144 		file_lease_free(fl);
13145 		need_wakeup = true;
13146 	}
13147 
13148 	/* Wakeup any lease breaker(s) that might be currently blocked. */
13149 	if (__improbable(need_wakeup)) {
13150 		wakeup(&vp->v_leases);
13151 	}
13152 
13153 	if (!locked) {
13154 		vnode_unlock(vp);
13155 	}
13156 }
13157 
13158 #endif /* CONFIG_FILE_LEASES */
13159 
13160 errno_t
vnode_rdadvise(vnode_t vp,off_t offset,int len,vfs_context_t ctx)13161 vnode_rdadvise(vnode_t vp, off_t offset, int len, vfs_context_t ctx)
13162 {
13163 	struct radvisory ra_struct;
13164 
13165 	assert(vp);
13166 
13167 	if (offset < 0 || len < 0) {
13168 		return EINVAL;
13169 	}
13170 
13171 	ra_struct.ra_offset = offset;
13172 	ra_struct.ra_count = len;
13173 
13174 	return VNOP_IOCTL(vp, F_RDADVISE, (caddr_t)&ra_struct, 0, ctx);
13175 }
13176