xref: /netbsd-src/sys/fs/union/union_vnops.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: union_vnops.c,v 1.61 2014/05/17 04:07:15 dholland Exp $	*/
2 
3 /*
4  * Copyright (c) 1992, 1993, 1994, 1995
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Jan-Simon Pendry.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *	@(#)union_vnops.c	8.33 (Berkeley) 7/31/95
35  */
36 
37 /*
38  * Copyright (c) 1992, 1993, 1994, 1995 Jan-Simon Pendry.
39  *
40  * This code is derived from software contributed to Berkeley by
41  * Jan-Simon Pendry.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  * 1. Redistributions of source code must retain the above copyright
47  *    notice, this list of conditions and the following disclaimer.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. All advertising materials mentioning features or use of this software
52  *    must display the following acknowledgement:
53  *	This product includes software developed by the University of
54  *	California, Berkeley and its contributors.
55  * 4. Neither the name of the University nor the names of its contributors
56  *    may be used to endorse or promote products derived from this software
57  *    without specific prior written permission.
58  *
59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69  * SUCH DAMAGE.
70  *
71  *	@(#)union_vnops.c	8.33 (Berkeley) 7/31/95
72  */
73 
74 #include <sys/cdefs.h>
75 __KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.61 2014/05/17 04:07:15 dholland Exp $");
76 
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/proc.h>
80 #include <sys/file.h>
81 #include <sys/time.h>
82 #include <sys/stat.h>
83 #include <sys/vnode.h>
84 #include <sys/mount.h>
85 #include <sys/namei.h>
86 #include <sys/malloc.h>
87 #include <sys/buf.h>
88 #include <sys/queue.h>
89 #include <sys/lock.h>
90 #include <sys/kauth.h>
91 
92 #include <fs/union/union.h>
93 #include <miscfs/genfs/genfs.h>
94 #include <miscfs/specfs/specdev.h>
95 
96 int union_lookup(void *);
97 int union_create(void *);
98 int union_whiteout(void *);
99 int union_mknod(void *);
100 int union_open(void *);
101 int union_close(void *);
102 int union_access(void *);
103 int union_getattr(void *);
104 int union_setattr(void *);
105 int union_read(void *);
106 int union_write(void *);
107 int union_ioctl(void *);
108 int union_poll(void *);
109 int union_revoke(void *);
110 int union_mmap(void *);
111 int union_fsync(void *);
112 int union_seek(void *);
113 int union_remove(void *);
114 int union_link(void *);
115 int union_rename(void *);
116 int union_mkdir(void *);
117 int union_rmdir(void *);
118 int union_symlink(void *);
119 int union_readdir(void *);
120 int union_readlink(void *);
121 int union_abortop(void *);
122 int union_inactive(void *);
123 int union_reclaim(void *);
124 int union_lock(void *);
125 int union_unlock(void *);
126 int union_bmap(void *);
127 int union_print(void *);
128 int union_islocked(void *);
129 int union_pathconf(void *);
130 int union_advlock(void *);
131 int union_strategy(void *);
132 int union_bwrite(void *);
133 int union_getpages(void *);
134 int union_putpages(void *);
135 int union_kqfilter(void *);
136 
137 static int union_lookup1(struct vnode *, struct vnode **,
138 			      struct vnode **, struct componentname *);
139 
140 
141 /*
142  * Global vfs data structures
143  */
144 int (**union_vnodeop_p)(void *);
145 const struct vnodeopv_entry_desc union_vnodeop_entries[] = {
146 	{ &vop_default_desc, vn_default_error },
147 	{ &vop_lookup_desc, union_lookup },		/* lookup */
148 	{ &vop_create_desc, union_create },		/* create */
149 	{ &vop_whiteout_desc, union_whiteout },		/* whiteout */
150 	{ &vop_mknod_desc, union_mknod },		/* mknod */
151 	{ &vop_open_desc, union_open },			/* open */
152 	{ &vop_close_desc, union_close },		/* close */
153 	{ &vop_access_desc, union_access },		/* access */
154 	{ &vop_getattr_desc, union_getattr },		/* getattr */
155 	{ &vop_setattr_desc, union_setattr },		/* setattr */
156 	{ &vop_read_desc, union_read },			/* read */
157 	{ &vop_write_desc, union_write },		/* write */
158 	{ &vop_ioctl_desc, union_ioctl },		/* ioctl */
159 	{ &vop_poll_desc, union_poll },			/* select */
160 	{ &vop_revoke_desc, union_revoke },		/* revoke */
161 	{ &vop_mmap_desc, union_mmap },			/* mmap */
162 	{ &vop_fsync_desc, union_fsync },		/* fsync */
163 	{ &vop_seek_desc, union_seek },			/* seek */
164 	{ &vop_remove_desc, union_remove },		/* remove */
165 	{ &vop_link_desc, union_link },			/* link */
166 	{ &vop_rename_desc, union_rename },		/* rename */
167 	{ &vop_mkdir_desc, union_mkdir },		/* mkdir */
168 	{ &vop_rmdir_desc, union_rmdir },		/* rmdir */
169 	{ &vop_symlink_desc, union_symlink },		/* symlink */
170 	{ &vop_readdir_desc, union_readdir },		/* readdir */
171 	{ &vop_readlink_desc, union_readlink },		/* readlink */
172 	{ &vop_abortop_desc, union_abortop },		/* abortop */
173 	{ &vop_inactive_desc, union_inactive },		/* inactive */
174 	{ &vop_reclaim_desc, union_reclaim },		/* reclaim */
175 	{ &vop_lock_desc, union_lock },			/* lock */
176 	{ &vop_unlock_desc, union_unlock },		/* unlock */
177 	{ &vop_bmap_desc, union_bmap },			/* bmap */
178 	{ &vop_strategy_desc, union_strategy },		/* strategy */
179 	{ &vop_bwrite_desc, union_bwrite },		/* bwrite */
180 	{ &vop_print_desc, union_print },		/* print */
181 	{ &vop_islocked_desc, union_islocked },		/* islocked */
182 	{ &vop_pathconf_desc, union_pathconf },		/* pathconf */
183 	{ &vop_advlock_desc, union_advlock },		/* advlock */
184 	{ &vop_getpages_desc, union_getpages },		/* getpages */
185 	{ &vop_putpages_desc, union_putpages },		/* putpages */
186 	{ &vop_kqfilter_desc, union_kqfilter },		/* kqfilter */
187 	{ NULL, NULL }
188 };
189 const struct vnodeopv_desc union_vnodeop_opv_desc =
190 	{ &union_vnodeop_p, union_vnodeop_entries };
191 
192 #define NODE_IS_SPECIAL(vp) \
193 	((vp)->v_type == VBLK || (vp)->v_type == VCHR || \
194 	(vp)->v_type == VSOCK || (vp)->v_type == VFIFO)
195 
196 static int
197 union_lookup1(struct vnode *udvp, struct vnode **dvpp, struct vnode **vpp,
198 	struct componentname *cnp)
199 {
200 	int error;
201 	struct vnode *tdvp;
202 	struct vnode *dvp;
203 	struct mount *mp;
204 
205 	dvp = *dvpp;
206 
207 	/*
208 	 * If stepping up the directory tree, check for going
209 	 * back across the mount point, in which case do what
210 	 * lookup would do by stepping back down the mount
211 	 * hierarchy.
212 	 */
213 	if (cnp->cn_flags & ISDOTDOT) {
214 		while ((dvp != udvp) && (dvp->v_vflag & VV_ROOT)) {
215 			/*
216 			 * Don't do the NOCROSSMOUNT check
217 			 * at this level.  By definition,
218 			 * union fs deals with namespaces, not
219 			 * filesystems.
220 			 */
221 			tdvp = dvp;
222 			*dvpp = dvp = dvp->v_mount->mnt_vnodecovered;
223 			VOP_UNLOCK(tdvp);
224 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
225 		}
226 	}
227 
228         error = VOP_LOOKUP(dvp, &tdvp, cnp);
229 	if (error)
230 		return (error);
231 	if (dvp != tdvp) {
232 		if (cnp->cn_flags & ISDOTDOT)
233 			VOP_UNLOCK(dvp);
234 		error = vn_lock(tdvp, LK_EXCLUSIVE);
235 		if (cnp->cn_flags & ISDOTDOT)
236 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
237 		if (error) {
238 			vrele(tdvp);
239 			return error;
240 		}
241 		dvp = tdvp;
242 	}
243 
244 	/*
245 	 * Lastly check if the current node is a mount point in
246 	 * which case walk up the mount hierarchy making sure not to
247 	 * bump into the root of the mount tree (ie. dvp != udvp).
248 	 */
249 	while (dvp != udvp && (dvp->v_type == VDIR) &&
250 	       (mp = dvp->v_mountedhere)) {
251 		if (vfs_busy(mp, NULL))
252 			continue;
253 		vput(dvp);
254 		error = VFS_ROOT(mp, &tdvp);
255 		vfs_unbusy(mp, false, NULL);
256 		if (error) {
257 			return (error);
258 		}
259 		dvp = tdvp;
260 	}
261 
262 	*vpp = dvp;
263 	return (0);
264 }
265 
266 int
267 union_lookup(void *v)
268 {
269 	struct vop_lookup_v2_args /* {
270 		struct vnodeop_desc *a_desc;
271 		struct vnode *a_dvp;
272 		struct vnode **a_vpp;
273 		struct componentname *a_cnp;
274 	} */ *ap = v;
275 	int error;
276 	int uerror, lerror;
277 	struct vnode *uppervp, *lowervp;
278 	struct vnode *upperdvp, *lowerdvp;
279 	struct vnode *dvp = ap->a_dvp;
280 	struct union_node *dun = VTOUNION(dvp);
281 	struct componentname *cnp = ap->a_cnp;
282 	struct union_mount *um = MOUNTTOUNIONMOUNT(dvp->v_mount);
283 	kauth_cred_t saved_cred = NULL;
284 	int iswhiteout;
285 	struct vattr va;
286 
287 #ifdef notyet
288 	if (cnp->cn_namelen == 3 &&
289 			cnp->cn_nameptr[2] == '.' &&
290 			cnp->cn_nameptr[1] == '.' &&
291 			cnp->cn_nameptr[0] == '.') {
292 		dvp = *ap->a_vpp = LOWERVP(ap->a_dvp);
293 		if (dvp == NULLVP)
294 			return (ENOENT);
295 		vref(dvp);
296 		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
297 		return (0);
298 	}
299 #endif
300 
301 	if ((cnp->cn_flags & ISLASTCN) &&
302 	    (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
303 	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
304 		return (EROFS);
305 
306 start:
307 	upperdvp = dun->un_uppervp;
308 	lowerdvp = dun->un_lowervp;
309 	uppervp = NULLVP;
310 	lowervp = NULLVP;
311 	iswhiteout = 0;
312 
313 	/*
314 	 * do the lookup in the upper level.
315 	 * if that level comsumes additional pathnames,
316 	 * then assume that something special is going
317 	 * on and just return that vnode.
318 	 */
319 	if (upperdvp != NULLVP) {
320 		uerror = union_lookup1(um->um_uppervp, &upperdvp,
321 					&uppervp, cnp);
322 		if (cnp->cn_consume != 0) {
323 			if (uppervp != upperdvp)
324 				VOP_UNLOCK(uppervp);
325 			*ap->a_vpp = uppervp;
326 			return (uerror);
327 		}
328 		if (uerror == ENOENT || uerror == EJUSTRETURN) {
329 			if (cnp->cn_flags & ISWHITEOUT) {
330 				iswhiteout = 1;
331 			} else if (lowerdvp != NULLVP) {
332 				lerror = VOP_GETATTR(upperdvp, &va,
333 					cnp->cn_cred);
334 				if (lerror == 0 && (va.va_flags & OPAQUE))
335 					iswhiteout = 1;
336 			}
337 		}
338 	} else {
339 		uerror = ENOENT;
340 	}
341 
342 	/*
343 	 * in a similar way to the upper layer, do the lookup
344 	 * in the lower layer.   this time, if there is some
345 	 * component magic going on, then vput whatever we got
346 	 * back from the upper layer and return the lower vnode
347 	 * instead.
348 	 */
349 	if (lowerdvp != NULLVP && !iswhiteout) {
350 		int nameiop;
351 
352 		vn_lock(lowerdvp, LK_EXCLUSIVE | LK_RETRY);
353 
354 		/*
355 		 * Only do a LOOKUP on the bottom node, since
356 		 * we won't be making changes to it anyway.
357 		 */
358 		nameiop = cnp->cn_nameiop;
359 		cnp->cn_nameiop = LOOKUP;
360 		if (um->um_op == UNMNT_BELOW) {
361 			saved_cred = cnp->cn_cred;
362 			cnp->cn_cred = um->um_cred;
363 		}
364 
365 		/*
366 		 * we shouldn't have to worry about locking interactions
367 		 * between the lower layer and our union layer (w.r.t.
368 		 * `..' processing) because we don't futz with lowervp
369 		 * locks in the union-node instantiation code path.
370 		 */
371 		lerror = union_lookup1(um->um_lowervp, &lowerdvp,
372 				&lowervp, cnp);
373 		if (um->um_op == UNMNT_BELOW)
374 			cnp->cn_cred = saved_cred;
375 		cnp->cn_nameiop = nameiop;
376 
377 		if (lowervp != lowerdvp)
378 			VOP_UNLOCK(lowerdvp);
379 
380 		if (cnp->cn_consume != 0) {
381 			if (uppervp != NULLVP) {
382 				if (uppervp == upperdvp)
383 					vrele(uppervp);
384 				else
385 					vput(uppervp);
386 				uppervp = NULLVP;
387 			}
388 			*ap->a_vpp = lowervp;
389 			return (lerror);
390 		}
391 	} else {
392 		lerror = ENOENT;
393 		if ((cnp->cn_flags & ISDOTDOT) && dun->un_pvp != NULLVP) {
394 			lowervp = LOWERVP(dun->un_pvp);
395 			if (lowervp != NULLVP) {
396 				vref(lowervp);
397 				vn_lock(lowervp, LK_EXCLUSIVE | LK_RETRY);
398 				lerror = 0;
399 			}
400 		}
401 	}
402 
403 	/*
404 	 * EJUSTRETURN is used by underlying filesystems to indicate that
405 	 * a directory modification op was started successfully.
406 	 * This will only happen in the upper layer, since
407 	 * the lower layer only does LOOKUPs.
408 	 * If this union is mounted read-only, bounce it now.
409 	 */
410 
411 	if ((uerror == EJUSTRETURN) && (cnp->cn_flags & ISLASTCN) &&
412 	    (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
413 	    ((cnp->cn_nameiop == CREATE) || (cnp->cn_nameiop == RENAME)))
414 		uerror = EROFS;
415 
416 	/*
417 	 * at this point, we have uerror and lerror indicating
418 	 * possible errors with the lookups in the upper and lower
419 	 * layers.  additionally, uppervp and lowervp are (locked)
420 	 * references to existing vnodes in the upper and lower layers.
421 	 *
422 	 * there are now three cases to consider.
423 	 * 1. if both layers returned an error, then return whatever
424 	 *    error the upper layer generated.
425 	 *
426 	 * 2. if the top layer failed and the bottom layer succeeded
427 	 *    then two subcases occur.
428 	 *    a.  the bottom vnode is not a directory, in which
429 	 *	  case just return a new union vnode referencing
430 	 *	  an empty top layer and the existing bottom layer.
431 	 *    b.  the bottom vnode is a directory, in which case
432 	 *	  create a new directory in the top-level and
433 	 *	  continue as in case 3.
434 	 *
435 	 * 3. if the top layer succeeded then return a new union
436 	 *    vnode referencing whatever the new top layer and
437 	 *    whatever the bottom layer returned.
438 	 */
439 
440 	*ap->a_vpp = NULLVP;
441 
442 
443 	/* case 1. */
444 	if ((uerror != 0) && (lerror != 0)) {
445 		return (uerror);
446 	}
447 
448 	/* case 2. */
449 	if (uerror != 0 /* && (lerror == 0) */ ) {
450 		if (lowervp->v_type == VDIR) { /* case 2b. */
451 			/*
452 			 * We may be racing another process to make the
453 			 * upper-level shadow directory.  Be careful with
454 			 * locks/etc!
455 			 * If we have to create a shadow directory and want
456 			 * to commit the node we have to restart the lookup
457 			 * to get the componentname right.
458 			 */
459 			if (upperdvp) {
460 				VOP_UNLOCK(upperdvp);
461 				uerror = union_mkshadow(um, upperdvp, cnp,
462 				    &uppervp);
463 				vn_lock(upperdvp, LK_EXCLUSIVE | LK_RETRY);
464 				if (uerror == 0 && cnp->cn_nameiop != LOOKUP) {
465 					vrele(uppervp);
466 					if (lowervp != NULLVP)
467 						vput(lowervp);
468 					goto start;
469 				}
470 			}
471 			if (uerror) {
472 				if (lowervp != NULLVP) {
473 					vput(lowervp);
474 					lowervp = NULLVP;
475 				}
476 				return (uerror);
477 			}
478 		}
479 	} else { /* uerror == 0 */
480 		if (uppervp != upperdvp)
481 			VOP_UNLOCK(uppervp);
482 	}
483 
484 	if (lowervp != NULLVP)
485 		VOP_UNLOCK(lowervp);
486 
487 	error = union_allocvp(ap->a_vpp, dvp->v_mount, dvp, upperdvp, cnp,
488 			      uppervp, lowervp, 1);
489 
490 	if (error) {
491 		if (uppervp != NULLVP)
492 			vrele(uppervp);
493 		if (lowervp != NULLVP)
494 			vrele(lowervp);
495 		return error;
496 	}
497 
498 	return 0;
499 }
500 
501 int
502 union_create(void *v)
503 {
504 	struct vop_create_v3_args /* {
505 		struct vnode *a_dvp;
506 		struct vnode **a_vpp;
507 		struct componentname *a_cnp;
508 		struct vattr *a_vap;
509 	} */ *ap = v;
510 	struct union_node *un = VTOUNION(ap->a_dvp);
511 	struct vnode *dvp = un->un_uppervp;
512 	struct componentname *cnp = ap->a_cnp;
513 
514 	if (dvp != NULLVP) {
515 		int error;
516 		struct vnode *vp;
517 		struct mount *mp;
518 
519 		mp = ap->a_dvp->v_mount;
520 
521 		vp = NULL;
522 		error = VOP_CREATE(dvp, &vp, cnp, ap->a_vap);
523 		if (error)
524 			return (error);
525 
526 		error = union_allocvp(ap->a_vpp, mp, NULLVP, NULLVP, cnp, vp,
527 				NULLVP, 1);
528 		if (error)
529 			vrele(vp);
530 		return (error);
531 	}
532 
533 	return (EROFS);
534 }
535 
536 int
537 union_whiteout(void *v)
538 {
539 	struct vop_whiteout_args /* {
540 		struct vnode *a_dvp;
541 		struct componentname *a_cnp;
542 		int a_flags;
543 	} */ *ap = v;
544 	struct union_node *un = VTOUNION(ap->a_dvp);
545 	struct componentname *cnp = ap->a_cnp;
546 
547 	if (un->un_uppervp == NULLVP)
548 		return (EOPNOTSUPP);
549 
550 	return (VOP_WHITEOUT(un->un_uppervp, cnp, ap->a_flags));
551 }
552 
553 int
554 union_mknod(void *v)
555 {
556 	struct vop_mknod_v3_args /* {
557 		struct vnode *a_dvp;
558 		struct vnode **a_vpp;
559 		struct componentname *a_cnp;
560 		struct vattr *a_vap;
561 	} */ *ap = v;
562 	struct union_node *un = VTOUNION(ap->a_dvp);
563 	struct vnode *dvp = un->un_uppervp;
564 	struct componentname *cnp = ap->a_cnp;
565 
566 	if (dvp != NULLVP) {
567 		int error;
568 		struct vnode *vp;
569 		struct mount *mp;
570 
571 		mp = ap->a_dvp->v_mount;
572 		error = VOP_MKNOD(dvp, &vp, cnp, ap->a_vap);
573 		if (error)
574 			return (error);
575 
576 		error = union_allocvp(ap->a_vpp, mp, NULLVP, NULLVP,
577 				      cnp, vp, NULLVP, 1);
578 		if (error)
579 			vrele(vp);
580 		return (error);
581 	}
582 
583 	return (EROFS);
584 }
585 
586 int
587 union_open(void *v)
588 {
589 	struct vop_open_args /* {
590 		struct vnodeop_desc *a_desc;
591 		struct vnode *a_vp;
592 		int a_mode;
593 		kauth_cred_t a_cred;
594 	} */ *ap = v;
595 	struct union_node *un = VTOUNION(ap->a_vp);
596 	struct vnode *tvp;
597 	int mode = ap->a_mode;
598 	kauth_cred_t cred = ap->a_cred;
599 	struct lwp *l = curlwp;
600 	int error;
601 
602 	/*
603 	 * If there is an existing upper vp then simply open that.
604 	 */
605 	tvp = un->un_uppervp;
606 	if (tvp == NULLVP) {
607 		/*
608 		 * If the lower vnode is being opened for writing, then
609 		 * copy the file contents to the upper vnode and open that,
610 		 * otherwise can simply open the lower vnode.
611 		 */
612 		tvp = un->un_lowervp;
613 		if ((ap->a_mode & FWRITE) && (tvp->v_type == VREG)) {
614 			error = union_copyup(un, (mode&O_TRUNC) == 0, cred, l);
615 			if (error == 0)
616 				error = VOP_OPEN(un->un_uppervp, mode, cred);
617 			return (error);
618 		}
619 
620 		/*
621 		 * Just open the lower vnode, but check for nodev mount flag
622 		 */
623 		if ((tvp->v_type == VBLK || tvp->v_type == VCHR) &&
624 		    (ap->a_vp->v_mount->mnt_flag & MNT_NODEV))
625 			return ENXIO;
626 		un->un_openl++;
627 		vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY);
628 		error = VOP_OPEN(tvp, mode, cred);
629 		VOP_UNLOCK(tvp);
630 
631 		return (error);
632 	}
633 	/*
634 	 * Just open the upper vnode, checking for nodev mount flag first
635 	 */
636 	if ((tvp->v_type == VBLK || tvp->v_type == VCHR) &&
637 	    (ap->a_vp->v_mount->mnt_flag & MNT_NODEV))
638 		return ENXIO;
639 
640 	error = VOP_OPEN(tvp, mode, cred);
641 
642 	return (error);
643 }
644 
645 int
646 union_close(void *v)
647 {
648 	struct vop_close_args /* {
649 		struct vnode *a_vp;
650 		int  a_fflag;
651 		kauth_cred_t a_cred;
652 	} */ *ap = v;
653 	struct union_node *un = VTOUNION(ap->a_vp);
654 	struct vnode *vp;
655 	int error;
656 	bool do_lock;
657 
658 	vp = un->un_uppervp;
659 	if (vp != NULLVP) {
660 		do_lock = false;
661 	} else {
662 		KASSERT(un->un_openl > 0);
663 		--un->un_openl;
664 		vp = un->un_lowervp;
665 		do_lock = true;
666 	}
667 
668 	KASSERT(vp != NULLVP);
669 	ap->a_vp = vp;
670 	if (do_lock)
671 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
672 	error = VCALL(vp, VOFFSET(vop_close), ap);
673 	if (do_lock)
674 		VOP_UNLOCK(vp);
675 
676 	return error;
677 }
678 
679 /*
680  * Check access permission on the union vnode.
681  * The access check being enforced is to check
682  * against both the underlying vnode, and any
683  * copied vnode.  This ensures that no additional
684  * file permissions are given away simply because
685  * the user caused an implicit file copy.
686  */
687 int
688 union_access(void *v)
689 {
690 	struct vop_access_args /* {
691 		struct vnodeop_desc *a_desc;
692 		struct vnode *a_vp;
693 		int a_mode;
694 		kauth_cred_t a_cred;
695 	} */ *ap = v;
696 	struct vnode *vp = ap->a_vp;
697 	struct union_node *un = VTOUNION(vp);
698 	int error = EACCES;
699 	struct union_mount *um = MOUNTTOUNIONMOUNT(vp->v_mount);
700 
701 	/*
702 	 * Disallow write attempts on read-only file systems;
703 	 * unless the file is a socket, fifo, or a block or
704 	 * character device resident on the file system.
705 	 */
706 	if (ap->a_mode & VWRITE) {
707 		switch (vp->v_type) {
708 		case VDIR:
709 		case VLNK:
710 		case VREG:
711 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
712 				return (EROFS);
713 			break;
714 		case VBAD:
715 		case VBLK:
716 		case VCHR:
717 		case VSOCK:
718 		case VFIFO:
719 		case VNON:
720 		default:
721 			break;
722 		}
723 	}
724 
725 
726 	if ((vp = un->un_uppervp) != NULLVP) {
727 		ap->a_vp = vp;
728 		return (VCALL(vp, VOFFSET(vop_access), ap));
729 	}
730 
731 	if ((vp = un->un_lowervp) != NULLVP) {
732 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
733 		ap->a_vp = vp;
734 		error = VCALL(vp, VOFFSET(vop_access), ap);
735 		if (error == 0) {
736 			if (um->um_op == UNMNT_BELOW) {
737 				ap->a_cred = um->um_cred;
738 				error = VCALL(vp, VOFFSET(vop_access), ap);
739 			}
740 		}
741 		VOP_UNLOCK(vp);
742 		if (error)
743 			return (error);
744 	}
745 
746 	return (error);
747 }
748 
749 /*
750  * We handle getattr only to change the fsid and
751  * track object sizes
752  */
753 int
754 union_getattr(void *v)
755 {
756 	struct vop_getattr_args /* {
757 		struct vnode *a_vp;
758 		struct vattr *a_vap;
759 		kauth_cred_t a_cred;
760 	} */ *ap = v;
761 	int error;
762 	struct union_node *un = VTOUNION(ap->a_vp);
763 	struct vnode *vp = un->un_uppervp;
764 	struct vattr *vap;
765 	struct vattr va;
766 
767 
768 	/*
769 	 * Some programs walk the filesystem hierarchy by counting
770 	 * links to directories to avoid stat'ing all the time.
771 	 * This means the link count on directories needs to be "correct".
772 	 * The only way to do that is to call getattr on both layers
773 	 * and fix up the link count.  The link count will not necessarily
774 	 * be accurate but will be large enough to defeat the tree walkers.
775 	 *
776 	 * To make life more interesting, some filesystems don't keep
777 	 * track of link counts in the expected way, and return a
778 	 * link count of `1' for those directories; if either of the
779 	 * component directories returns a link count of `1', we return a 1.
780 	 */
781 
782 	vap = ap->a_vap;
783 
784 	vp = un->un_uppervp;
785 	if (vp != NULLVP) {
786 		error = VOP_GETATTR(vp, vap, ap->a_cred);
787 		if (error)
788 			return (error);
789 		mutex_enter(&un->un_lock);
790 		union_newsize(ap->a_vp, vap->va_size, VNOVAL);
791 	}
792 
793 	if (vp == NULLVP) {
794 		vp = un->un_lowervp;
795 	} else if (vp->v_type == VDIR) {
796 		vp = un->un_lowervp;
797 		if (vp != NULLVP)
798 			vap = &va;
799 	} else {
800 		vp = NULLVP;
801 	}
802 
803 	if (vp != NULLVP) {
804 		if (vp == un->un_lowervp)
805 			vn_lock(vp, LK_SHARED | LK_RETRY);
806 		error = VOP_GETATTR(vp, vap, ap->a_cred);
807 		if (vp == un->un_lowervp)
808 			VOP_UNLOCK(vp);
809 		if (error)
810 			return (error);
811 		mutex_enter(&un->un_lock);
812 		union_newsize(ap->a_vp, VNOVAL, vap->va_size);
813 	}
814 
815 	if ((vap != ap->a_vap) && (vap->va_type == VDIR)) {
816 		/*
817 		 * Link count manipulation:
818 		 *	- If both return "2", return 2 (no subdirs)
819 		 *	- If one or the other return "1", return "1" (ENOCLUE)
820 		 */
821 		if ((ap->a_vap->va_nlink == 2) &&
822 		    (vap->va_nlink == 2))
823 			;
824 		else if (ap->a_vap->va_nlink != 1) {
825 			if (vap->va_nlink == 1)
826 				ap->a_vap->va_nlink = 1;
827 			else
828 				ap->a_vap->va_nlink += vap->va_nlink;
829 		}
830 	}
831 	ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0];
832 	return (0);
833 }
834 
835 int
836 union_setattr(void *v)
837 {
838 	struct vop_setattr_args /* {
839 		struct vnode *a_vp;
840 		struct vattr *a_vap;
841 		kauth_cred_t a_cred;
842 	} */ *ap = v;
843 	struct vattr *vap = ap->a_vap;
844 	struct vnode *vp = ap->a_vp;
845 	struct union_node *un = VTOUNION(vp);
846 	bool size_only;		/* All but va_size are VNOVAL. */
847 	int error;
848 
849 	size_only = (vap->va_flags == VNOVAL && vap->va_uid == (uid_t)VNOVAL &&
850 	    vap->va_gid == (gid_t)VNOVAL && vap->va_atime.tv_sec == VNOVAL &&
851 	    vap->va_mtime.tv_sec == VNOVAL && vap->va_mode == (mode_t)VNOVAL);
852 
853 	if (!size_only && (vp->v_mount->mnt_flag & MNT_RDONLY))
854 		return (EROFS);
855 	if (vap->va_size != VNOVAL) {
856  		switch (vp->v_type) {
857  		case VDIR:
858  			return (EISDIR);
859  		case VCHR:
860  		case VBLK:
861  		case VSOCK:
862  		case VFIFO:
863 			break;
864 		case VREG:
865 		case VLNK:
866  		default:
867 			/*
868 			 * Disallow write attempts if the filesystem is
869 			 * mounted read-only.
870 			 */
871 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
872 				return (EROFS);
873 		}
874 	}
875 
876 	/*
877 	 * Handle case of truncating lower object to zero size,
878 	 * by creating a zero length upper object.  This is to
879 	 * handle the case of open with O_TRUNC and O_CREAT.
880 	 */
881 	if ((un->un_uppervp == NULLVP) &&
882 	    /* assert(un->un_lowervp != NULLVP) */
883 	    (un->un_lowervp->v_type == VREG)) {
884 		error = union_copyup(un, (vap->va_size != 0),
885 						ap->a_cred, curlwp);
886 		if (error)
887 			return (error);
888 	}
889 
890 	/*
891 	 * Try to set attributes in upper layer, ignore size change to zero
892 	 * for devices to handle O_TRUNC and return read-only filesystem error
893 	 * otherwise.
894 	 */
895 	if (un->un_uppervp != NULLVP) {
896 		error = VOP_SETATTR(un->un_uppervp, vap, ap->a_cred);
897 		if ((error == 0) && (vap->va_size != VNOVAL)) {
898 			mutex_enter(&un->un_lock);
899 			union_newsize(ap->a_vp, vap->va_size, VNOVAL);
900 		}
901 	} else {
902 		KASSERT(un->un_lowervp != NULLVP);
903 		if (NODE_IS_SPECIAL(un->un_lowervp)) {
904 			if (size_only &&
905 			    (vap->va_size == 0 || vap->va_size == VNOVAL))
906 				error = 0;
907 			else
908 				error = EROFS;
909 		} else {
910 			error = EROFS;
911 		}
912 	}
913 
914 	return (error);
915 }
916 
917 int
918 union_read(void *v)
919 {
920 	struct vop_read_args /* {
921 		struct vnode *a_vp;
922 		struct uio *a_uio;
923 		int  a_ioflag;
924 		kauth_cred_t a_cred;
925 	} */ *ap = v;
926 	int error;
927 	struct vnode *vp = OTHERVP(ap->a_vp);
928 	int dolock = (vp == LOWERVP(ap->a_vp));
929 
930 	if (dolock)
931 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
932 	error = VOP_READ(vp, ap->a_uio, ap->a_ioflag, ap->a_cred);
933 	if (dolock)
934 		VOP_UNLOCK(vp);
935 
936 	/*
937 	 * XXX
938 	 * perhaps the size of the underlying object has changed under
939 	 * our feet.  take advantage of the offset information present
940 	 * in the uio structure.
941 	 */
942 	if (error == 0) {
943 		struct union_node *un = VTOUNION(ap->a_vp);
944 		off_t cur = ap->a_uio->uio_offset;
945 		off_t usz = VNOVAL, lsz = VNOVAL;
946 
947 		mutex_enter(&un->un_lock);
948 		if (vp == un->un_uppervp) {
949 			if (cur > un->un_uppersz)
950 				usz = cur;
951 		} else {
952 			if (cur > un->un_lowersz)
953 				lsz = cur;
954 		}
955 
956 		if (usz != VNOVAL || lsz != VNOVAL)
957 			union_newsize(ap->a_vp, usz, lsz);
958 		else
959 			mutex_exit(&un->un_lock);
960 	}
961 
962 	return (error);
963 }
964 
965 int
966 union_write(void *v)
967 {
968 	struct vop_read_args /* {
969 		struct vnode *a_vp;
970 		struct uio *a_uio;
971 		int  a_ioflag;
972 		kauth_cred_t a_cred;
973 	} */ *ap = v;
974 	int error;
975 	struct vnode *vp;
976 	struct union_node *un = VTOUNION(ap->a_vp);
977 
978 	vp = UPPERVP(ap->a_vp);
979 	if (vp == NULLVP) {
980 		vp = LOWERVP(ap->a_vp);
981 		if (NODE_IS_SPECIAL(vp)) {
982 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
983 			error = VOP_WRITE(vp, ap->a_uio, ap->a_ioflag,
984 			    ap->a_cred);
985 			VOP_UNLOCK(vp);
986 			return error;
987 		}
988 		panic("union: missing upper layer in write");
989 	}
990 
991 	error = VOP_WRITE(vp, ap->a_uio, ap->a_ioflag, ap->a_cred);
992 
993 	/*
994 	 * the size of the underlying object may be changed by the
995 	 * write.
996 	 */
997 	if (error == 0) {
998 		off_t cur = ap->a_uio->uio_offset;
999 
1000 		mutex_enter(&un->un_lock);
1001 		if (cur > un->un_uppersz)
1002 			union_newsize(ap->a_vp, cur, VNOVAL);
1003 		else
1004 			mutex_exit(&un->un_lock);
1005 	}
1006 
1007 	return (error);
1008 }
1009 
1010 int
1011 union_ioctl(void *v)
1012 {
1013 	struct vop_ioctl_args /* {
1014 		struct vnode *a_vp;
1015 		int  a_command;
1016 		void *a_data;
1017 		int  a_fflag;
1018 		kauth_cred_t a_cred;
1019 	} */ *ap = v;
1020 	struct vnode *ovp = OTHERVP(ap->a_vp);
1021 
1022 	ap->a_vp = ovp;
1023 	return (VCALL(ovp, VOFFSET(vop_ioctl), ap));
1024 }
1025 
1026 int
1027 union_poll(void *v)
1028 {
1029 	struct vop_poll_args /* {
1030 		struct vnode *a_vp;
1031 		int a_events;
1032 	} */ *ap = v;
1033 	struct vnode *ovp = OTHERVP(ap->a_vp);
1034 
1035 	ap->a_vp = ovp;
1036 	return (VCALL(ovp, VOFFSET(vop_poll), ap));
1037 }
1038 
1039 int
1040 union_revoke(void *v)
1041 {
1042 	struct vop_revoke_args /* {
1043 		struct vnode *a_vp;
1044 		int a_flags;
1045 		struct proc *a_p;
1046 	} */ *ap = v;
1047 	struct vnode *vp = ap->a_vp;
1048 
1049 	if (UPPERVP(vp))
1050 		VOP_REVOKE(UPPERVP(vp), ap->a_flags);
1051 	if (LOWERVP(vp))
1052 		VOP_REVOKE(LOWERVP(vp), ap->a_flags);
1053 	vgone(vp);	/* XXXAD?? */
1054 	return (0);
1055 }
1056 
1057 int
1058 union_mmap(void *v)
1059 {
1060 	struct vop_mmap_args /* {
1061 		struct vnode *a_vp;
1062 		vm_prot_t a_prot;
1063 		kauth_cred_t a_cred;
1064 	} */ *ap = v;
1065 	struct vnode *ovp = OTHERVP(ap->a_vp);
1066 
1067 	ap->a_vp = ovp;
1068 	return (VCALL(ovp, VOFFSET(vop_mmap), ap));
1069 }
1070 
1071 int
1072 union_fsync(void *v)
1073 {
1074 	struct vop_fsync_args /* {
1075 		struct vnode *a_vp;
1076 		kauth_cred_t a_cred;
1077 		int  a_flags;
1078 		off_t offhi;
1079 		off_t offlo;
1080 	} */ *ap = v;
1081 	int error = 0;
1082 	struct vnode *targetvp;
1083 
1084 	/*
1085 	 * If vinvalbuf is calling us, it's a "shallow fsync" -- don't
1086 	 * bother syncing the underlying vnodes, since (a) they'll be
1087 	 * fsync'ed when reclaimed and (b) we could deadlock if
1088 	 * they're locked; otherwise, pass it through to the
1089 	 * underlying layer.
1090 	 */
1091 	if (ap->a_vp->v_type == VBLK || ap->a_vp->v_type == VCHR) {
1092 		error = spec_fsync(v);
1093 		if (error)
1094 			return error;
1095 	}
1096 
1097 	if (ap->a_flags & FSYNC_RECLAIM)
1098 		return 0;
1099 
1100 	targetvp = OTHERVP(ap->a_vp);
1101 	if (targetvp != NULLVP) {
1102 		int dolock = (targetvp == LOWERVP(ap->a_vp));
1103 
1104 		if (dolock)
1105 			vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY);
1106 		error = VOP_FSYNC(targetvp, ap->a_cred, ap->a_flags,
1107 			    ap->a_offlo, ap->a_offhi);
1108 		if (dolock)
1109 			VOP_UNLOCK(targetvp);
1110 	}
1111 
1112 	return (error);
1113 }
1114 
1115 int
1116 union_seek(void *v)
1117 {
1118 	struct vop_seek_args /* {
1119 		struct vnode *a_vp;
1120 		off_t  a_oldoff;
1121 		off_t  a_newoff;
1122 		kauth_cred_t a_cred;
1123 	} */ *ap = v;
1124 	struct vnode *ovp = OTHERVP(ap->a_vp);
1125 
1126 	ap->a_vp = ovp;
1127 	return (VCALL(ovp, VOFFSET(vop_seek), ap));
1128 }
1129 
1130 int
1131 union_remove(void *v)
1132 {
1133 	struct vop_remove_args /* {
1134 		struct vnode *a_dvp;
1135 		struct vnode *a_vp;
1136 		struct componentname *a_cnp;
1137 	} */ *ap = v;
1138 	int error;
1139 	struct union_node *dun = VTOUNION(ap->a_dvp);
1140 	struct union_node *un = VTOUNION(ap->a_vp);
1141 	struct componentname *cnp = ap->a_cnp;
1142 
1143 	if (dun->un_uppervp == NULLVP)
1144 		panic("union remove: null upper vnode");
1145 
1146 	if (un->un_uppervp != NULLVP) {
1147 		struct vnode *dvp = dun->un_uppervp;
1148 		struct vnode *vp = un->un_uppervp;
1149 
1150 		/*
1151 		 * Account for VOP_REMOVE to vrele dvp and vp.
1152 		 * Note: VOP_REMOVE will unlock dvp and vp.
1153 		 */
1154 		vref(dvp);
1155 		vref(vp);
1156 		if (union_dowhiteout(un, cnp->cn_cred))
1157 			cnp->cn_flags |= DOWHITEOUT;
1158 		error = VOP_REMOVE(dvp, vp, cnp);
1159 		if (!error)
1160 			union_removed_upper(un);
1161 		vrele(ap->a_dvp);
1162 		vrele(ap->a_vp);
1163 	} else {
1164 		error = union_mkwhiteout(
1165 			MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount),
1166 			dun->un_uppervp, ap->a_cnp, un);
1167 		vput(ap->a_dvp);
1168 		vput(ap->a_vp);
1169 	}
1170 
1171 	return (error);
1172 }
1173 
1174 int
1175 union_link(void *v)
1176 {
1177 	struct vop_link_args /* {
1178 		struct vnode *a_dvp;
1179 		struct vnode *a_vp;
1180 		struct componentname *a_cnp;
1181 	} */ *ap = v;
1182 	int error = 0;
1183 	struct componentname *cnp = ap->a_cnp;
1184 	struct union_node *dun;
1185 	struct vnode *vp;
1186 	struct vnode *dvp;
1187 
1188 	dun = VTOUNION(ap->a_dvp);
1189 
1190 	KASSERT((ap->a_cnp->cn_flags & LOCKPARENT) != 0);
1191 
1192 	if (ap->a_dvp->v_op != ap->a_vp->v_op) {
1193 		vp = ap->a_vp;
1194 	} else {
1195 		struct union_node *un = VTOUNION(ap->a_vp);
1196 		if (un->un_uppervp == NULLVP) {
1197 			const bool droplock = (dun->un_uppervp == un->un_dirvp);
1198 
1199 			/*
1200 			 * Needs to be copied before we can link it.
1201 			 */
1202 			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1203 			if (droplock)
1204 				VOP_UNLOCK(dun->un_uppervp);
1205 			error = union_copyup(un, 1, cnp->cn_cred, curlwp);
1206 			if (droplock) {
1207 				vn_lock(dun->un_uppervp,
1208 				    LK_EXCLUSIVE | LK_RETRY);
1209 				/*
1210 				 * During copyup, we dropped the lock on the
1211 				 * dir and invalidated any saved namei lookup
1212 				 * state for the directory we'll be entering
1213 				 * the link in.  We need to re-run the lookup
1214 				 * in that directory to reset any state needed
1215 				 * for VOP_LINK.
1216 				 * Call relookup on the union-layer to reset
1217 				 * the state.
1218 				 */
1219 				vp  = NULLVP;
1220 				if (dun->un_uppervp == NULLVP)
1221 					 panic("union: null upperdvp?");
1222 				error = relookup(ap->a_dvp, &vp, ap->a_cnp, 0);
1223 				if (error) {
1224 					VOP_UNLOCK(ap->a_vp);
1225 					return EROFS;	/* ? */
1226 				}
1227 				if (vp != NULLVP) {
1228 					/*
1229 					 * The name we want to create has
1230 					 * mysteriously appeared (a race?)
1231 					 */
1232 					error = EEXIST;
1233 					VOP_UNLOCK(ap->a_vp);
1234 					vput(ap->a_dvp);
1235 					vput(vp);
1236 					return (error);
1237 				}
1238 			}
1239 			VOP_UNLOCK(ap->a_vp);
1240 		}
1241 		vp = un->un_uppervp;
1242 	}
1243 
1244 	dvp = dun->un_uppervp;
1245 	if (dvp == NULLVP)
1246 		error = EROFS;
1247 
1248 	if (error) {
1249 		vput(ap->a_dvp);
1250 		return (error);
1251 	}
1252 
1253 	/*
1254 	 * Account for VOP_LINK to vrele dvp.
1255 	 * Note: VOP_LINK will unlock dvp.
1256 	 */
1257 	vref(dvp);
1258 	error = VOP_LINK(dvp, vp, cnp);
1259 	vrele(ap->a_dvp);
1260 
1261 	return error;
1262 }
1263 
1264 int
1265 union_rename(void *v)
1266 {
1267 	struct vop_rename_args  /* {
1268 		struct vnode *a_fdvp;
1269 		struct vnode *a_fvp;
1270 		struct componentname *a_fcnp;
1271 		struct vnode *a_tdvp;
1272 		struct vnode *a_tvp;
1273 		struct componentname *a_tcnp;
1274 	} */ *ap = v;
1275 	int error;
1276 
1277 	struct vnode *fdvp = ap->a_fdvp;
1278 	struct vnode *fvp = ap->a_fvp;
1279 	struct vnode *tdvp = ap->a_tdvp;
1280 	struct vnode *tvp = ap->a_tvp;
1281 
1282 	/*
1283 	 * Account for VOP_RENAME to vrele all nodes.
1284 	 * Note: VOP_RENAME will unlock tdvp.
1285 	 */
1286 
1287 	if (fdvp->v_op == union_vnodeop_p) {	/* always true */
1288 		struct union_node *un = VTOUNION(fdvp);
1289 		if (un->un_uppervp == NULLVP) {
1290 			/*
1291 			 * this should never happen in normal
1292 			 * operation but might if there was
1293 			 * a problem creating the top-level shadow
1294 			 * directory.
1295 			 */
1296 			error = EXDEV;
1297 			goto bad;
1298 		}
1299 
1300 		fdvp = un->un_uppervp;
1301 		vref(fdvp);
1302 	}
1303 
1304 	if (fvp->v_op == union_vnodeop_p) {	/* always true */
1305 		struct union_node *un = VTOUNION(fvp);
1306 		if (un->un_uppervp == NULLVP) {
1307 			/* XXX: should do a copyup */
1308 			error = EXDEV;
1309 			goto bad;
1310 		}
1311 
1312 		if (un->un_lowervp != NULLVP)
1313 			ap->a_fcnp->cn_flags |= DOWHITEOUT;
1314 
1315 		fvp = un->un_uppervp;
1316 		vref(fvp);
1317 	}
1318 
1319 	if (tdvp->v_op == union_vnodeop_p) {
1320 		struct union_node *un = VTOUNION(tdvp);
1321 		if (un->un_uppervp == NULLVP) {
1322 			/*
1323 			 * this should never happen in normal
1324 			 * operation but might if there was
1325 			 * a problem creating the top-level shadow
1326 			 * directory.
1327 			 */
1328 			error = EXDEV;
1329 			goto bad;
1330 		}
1331 
1332 		tdvp = un->un_uppervp;
1333 		vref(tdvp);
1334 	}
1335 
1336 	if (tvp != NULLVP && tvp->v_op == union_vnodeop_p) {
1337 		struct union_node *un = VTOUNION(tvp);
1338 
1339 		tvp = un->un_uppervp;
1340 		if (tvp != NULLVP) {
1341 			vref(tvp);
1342 		}
1343 	}
1344 
1345 	error = VOP_RENAME(fdvp, fvp, ap->a_fcnp, tdvp, tvp, ap->a_tcnp);
1346 	goto out;
1347 
1348 bad:
1349 	vput(tdvp);
1350 	if (tvp != NULLVP)
1351 		vput(tvp);
1352 	vrele(fdvp);
1353 	vrele(fvp);
1354 
1355 out:
1356 	if (fdvp != ap->a_fdvp) {
1357 		vrele(ap->a_fdvp);
1358 	}
1359 	if (fvp != ap->a_fvp) {
1360 		vrele(ap->a_fvp);
1361 	}
1362 	if (tdvp != ap->a_tdvp) {
1363 		vrele(ap->a_tdvp);
1364 	}
1365 	if (tvp != ap->a_tvp) {
1366 		vrele(ap->a_tvp);
1367 	}
1368 	return (error);
1369 }
1370 
1371 int
1372 union_mkdir(void *v)
1373 {
1374 	struct vop_mkdir_v3_args /* {
1375 		struct vnode *a_dvp;
1376 		struct vnode **a_vpp;
1377 		struct componentname *a_cnp;
1378 		struct vattr *a_vap;
1379 	} */ *ap = v;
1380 	struct union_node *un = VTOUNION(ap->a_dvp);
1381 	struct vnode *dvp = un->un_uppervp;
1382 	struct componentname *cnp = ap->a_cnp;
1383 
1384 	if (dvp != NULLVP) {
1385 		int error;
1386 		struct vnode *vp;
1387 
1388 		vp = NULL;
1389 		error = VOP_MKDIR(dvp, &vp, cnp, ap->a_vap);
1390 		if (error) {
1391 			vrele(ap->a_dvp);
1392 			return (error);
1393 		}
1394 
1395 		error = union_allocvp(ap->a_vpp, ap->a_dvp->v_mount, ap->a_dvp,
1396 				NULLVP, cnp, vp, NULLVP, 1);
1397 		if (error)
1398 			vrele(vp);
1399 		return (error);
1400 	}
1401 
1402 	return (EROFS);
1403 }
1404 
1405 int
1406 union_rmdir(void *v)
1407 {
1408 	struct vop_rmdir_args /* {
1409 		struct vnode *a_dvp;
1410 		struct vnode *a_vp;
1411 		struct componentname *a_cnp;
1412 	} */ *ap = v;
1413 	int error;
1414 	struct union_node *dun = VTOUNION(ap->a_dvp);
1415 	struct union_node *un = VTOUNION(ap->a_vp);
1416 	struct componentname *cnp = ap->a_cnp;
1417 
1418 	if (dun->un_uppervp == NULLVP)
1419 		panic("union rmdir: null upper vnode");
1420 
1421 	error = union_check_rmdir(un, cnp->cn_cred);
1422 	if (error) {
1423 		vput(ap->a_dvp);
1424 		vput(ap->a_vp);
1425 		return error;
1426 	}
1427 
1428 	if (un->un_uppervp != NULLVP) {
1429 		struct vnode *dvp = dun->un_uppervp;
1430 		struct vnode *vp = un->un_uppervp;
1431 
1432 		/*
1433 		 * Account for VOP_RMDIR to vrele dvp and vp.
1434 		 * Note: VOP_RMDIR will unlock dvp and vp.
1435 		 */
1436 		vref(dvp);
1437 		vref(vp);
1438 		if (union_dowhiteout(un, cnp->cn_cred))
1439 			cnp->cn_flags |= DOWHITEOUT;
1440 		error = VOP_RMDIR(dvp, vp, ap->a_cnp);
1441 		if (!error)
1442 			union_removed_upper(un);
1443 		vrele(ap->a_dvp);
1444 		vrele(ap->a_vp);
1445 	} else {
1446 		error = union_mkwhiteout(
1447 			MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount),
1448 			dun->un_uppervp, ap->a_cnp, un);
1449 		vput(ap->a_dvp);
1450 		vput(ap->a_vp);
1451 	}
1452 
1453 	return (error);
1454 }
1455 
1456 int
1457 union_symlink(void *v)
1458 {
1459 	struct vop_symlink_v3_args /* {
1460 		struct vnode *a_dvp;
1461 		struct vnode **a_vpp;
1462 		struct componentname *a_cnp;
1463 		struct vattr *a_vap;
1464 		char *a_target;
1465 	} */ *ap = v;
1466 	struct union_node *un = VTOUNION(ap->a_dvp);
1467 	struct vnode *dvp = un->un_uppervp;
1468 	struct componentname *cnp = ap->a_cnp;
1469 
1470 	if (dvp != NULLVP) {
1471 		int error;
1472 
1473 		error = VOP_SYMLINK(dvp, ap->a_vpp, cnp, ap->a_vap,
1474 				    ap->a_target);
1475 		return (error);
1476 	}
1477 
1478 	return (EROFS);
1479 }
1480 
1481 /*
1482  * union_readdir works in concert with getdirentries and
1483  * readdir(3) to provide a list of entries in the unioned
1484  * directories.  getdirentries is responsible for walking
1485  * down the union stack.  readdir(3) is responsible for
1486  * eliminating duplicate names from the returned data stream.
1487  */
1488 int
1489 union_readdir(void *v)
1490 {
1491 	struct vop_readdir_args /* {
1492 		struct vnodeop_desc *a_desc;
1493 		struct vnode *a_vp;
1494 		struct uio *a_uio;
1495 		kauth_cred_t a_cred;
1496 		int *a_eofflag;
1497 		u_long *a_cookies;
1498 		int a_ncookies;
1499 	} */ *ap = v;
1500 	struct union_node *un = VTOUNION(ap->a_vp);
1501 	struct vnode *uvp = un->un_uppervp;
1502 
1503 	if (uvp == NULLVP)
1504 		return (0);
1505 
1506 	ap->a_vp = uvp;
1507 	return (VCALL(uvp, VOFFSET(vop_readdir), ap));
1508 }
1509 
1510 int
1511 union_readlink(void *v)
1512 {
1513 	struct vop_readlink_args /* {
1514 		struct vnode *a_vp;
1515 		struct uio *a_uio;
1516 		kauth_cred_t a_cred;
1517 	} */ *ap = v;
1518 	int error;
1519 	struct vnode *vp = OTHERVP(ap->a_vp);
1520 	int dolock = (vp == LOWERVP(ap->a_vp));
1521 
1522 	if (dolock)
1523 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1524 	ap->a_vp = vp;
1525 	error = VCALL(vp, VOFFSET(vop_readlink), ap);
1526 	if (dolock)
1527 		VOP_UNLOCK(vp);
1528 
1529 	return (error);
1530 }
1531 
1532 int
1533 union_abortop(void *v)
1534 {
1535 	struct vop_abortop_args /* {
1536 		struct vnode *a_dvp;
1537 		struct componentname *a_cnp;
1538 	} */ *ap = v;
1539 
1540 	KASSERT(UPPERVP(ap->a_dvp) != NULL);
1541 
1542 	ap->a_dvp = UPPERVP(ap->a_dvp);
1543 	return VCALL(ap->a_dvp, VOFFSET(vop_abortop), ap);
1544 }
1545 
1546 int
1547 union_inactive(void *v)
1548 {
1549 	struct vop_inactive_args /* {
1550 		const struct vnodeop_desc *a_desc;
1551 		struct vnode *a_vp;
1552 		bool *a_recycle;
1553 	} */ *ap = v;
1554 	struct vnode *vp = ap->a_vp;
1555 	struct union_node *un = VTOUNION(vp);
1556 	struct vnode **vpp;
1557 
1558 	/*
1559 	 * Do nothing (and _don't_ bypass).
1560 	 * Wait to vrele lowervp until reclaim,
1561 	 * so that until then our union_node is in the
1562 	 * cache and reusable.
1563 	 *
1564 	 * NEEDSWORK: Someday, consider inactive'ing
1565 	 * the lowervp and then trying to reactivate it
1566 	 * with capabilities (v_id)
1567 	 * like they do in the name lookup cache code.
1568 	 * That's too much work for now.
1569 	 */
1570 
1571 	if (un->un_dircache != 0) {
1572 		for (vpp = un->un_dircache; *vpp != NULLVP; vpp++)
1573 			vrele(*vpp);
1574 		free(un->un_dircache, M_TEMP);
1575 		un->un_dircache = 0;
1576 	}
1577 
1578 	*ap->a_recycle = ((un->un_cflags & UN_CACHED) == 0);
1579 	VOP_UNLOCK(vp);
1580 
1581 	return (0);
1582 }
1583 
1584 int
1585 union_reclaim(void *v)
1586 {
1587 	struct vop_reclaim_args /* {
1588 		struct vnode *a_vp;
1589 	} */ *ap = v;
1590 
1591 	union_freevp(ap->a_vp);
1592 
1593 	return (0);
1594 }
1595 
1596 static int
1597 union_lock1(struct vnode *vp, struct vnode *lockvp, int flags)
1598 {
1599 	struct vop_lock_args ap;
1600 
1601 	if (lockvp == vp) {
1602 		ap.a_vp = vp;
1603 		ap.a_flags = flags;
1604 		return genfs_lock(&ap);
1605 	} else
1606 		return VOP_LOCK(lockvp, flags);
1607 }
1608 
1609 static int
1610 union_unlock1(struct vnode *vp, struct vnode *lockvp)
1611 {
1612 	struct vop_unlock_args ap;
1613 
1614 	if (lockvp == vp) {
1615 		ap.a_vp = vp;
1616 		return genfs_unlock(&ap);
1617 	} else
1618 		return VOP_UNLOCK(lockvp);
1619 }
1620 
1621 int
1622 union_lock(void *v)
1623 {
1624 	struct vop_lock_args /* {
1625 		struct vnode *a_vp;
1626 		int a_flags;
1627 	} */ *ap = v;
1628 	struct vnode *vp = ap->a_vp, *lockvp;
1629 	struct union_node *un = VTOUNION(vp);
1630 	int flags = ap->a_flags;
1631 	int error;
1632 
1633 	if ((flags & LK_NOWAIT) != 0) {
1634 		if (!mutex_tryenter(&un->un_lock))
1635 			return EBUSY;
1636 		lockvp = LOCKVP(vp);
1637 		error = union_lock1(vp, lockvp, flags);
1638 		mutex_exit(&un->un_lock);
1639 		if (error)
1640 			return error;
1641 		if (mutex_tryenter(vp->v_interlock)) {
1642 			error = vdead_check(vp, VDEAD_NOWAIT);
1643 			mutex_exit(vp->v_interlock);
1644 		} else
1645 			error = EBUSY;
1646 		if (error)
1647 			union_unlock1(vp, lockvp);
1648 		return error;
1649 	}
1650 
1651 	mutex_enter(&un->un_lock);
1652 	for (;;) {
1653 		lockvp = LOCKVP(vp);
1654 		mutex_exit(&un->un_lock);
1655 		error = union_lock1(vp, lockvp, flags);
1656 		if (error != 0)
1657 			return error;
1658 		mutex_enter(&un->un_lock);
1659 		if (lockvp == LOCKVP(vp))
1660 			break;
1661 		union_unlock1(vp, lockvp);
1662 	}
1663 	mutex_exit(&un->un_lock);
1664 
1665 	mutex_enter(vp->v_interlock);
1666 	error = vdead_check(vp, VDEAD_NOWAIT);
1667 	if (error) {
1668 		union_unlock1(vp, lockvp);
1669 		error = vdead_check(vp, 0);
1670 		KASSERT(error == ENOENT);
1671 	}
1672 	mutex_exit(vp->v_interlock);
1673 	return error;
1674 }
1675 
1676 int
1677 union_unlock(void *v)
1678 {
1679 	struct vop_unlock_args /* {
1680 		struct vnode *a_vp;
1681 		int a_flags;
1682 	} */ *ap = v;
1683 	struct vnode *vp = ap->a_vp, *lockvp;
1684 
1685 	lockvp = LOCKVP(vp);
1686 	union_unlock1(vp, lockvp);
1687 
1688 	return 0;
1689 }
1690 
1691 int
1692 union_bmap(void *v)
1693 {
1694 	struct vop_bmap_args /* {
1695 		struct vnode *a_vp;
1696 		daddr_t  a_bn;
1697 		struct vnode **a_vpp;
1698 		daddr_t *a_bnp;
1699 		int *a_runp;
1700 	} */ *ap = v;
1701 	int error;
1702 	struct vnode *vp = OTHERVP(ap->a_vp);
1703 	int dolock = (vp == LOWERVP(ap->a_vp));
1704 
1705 	if (dolock)
1706 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1707 	ap->a_vp = vp;
1708 	error = VCALL(vp, VOFFSET(vop_bmap), ap);
1709 	if (dolock)
1710 		VOP_UNLOCK(vp);
1711 
1712 	return (error);
1713 }
1714 
1715 int
1716 union_print(void *v)
1717 {
1718 	struct vop_print_args /* {
1719 		struct vnode *a_vp;
1720 	} */ *ap = v;
1721 	struct vnode *vp = ap->a_vp;
1722 
1723 	printf("\ttag VT_UNION, vp=%p, uppervp=%p, lowervp=%p\n",
1724 			vp, UPPERVP(vp), LOWERVP(vp));
1725 	if (UPPERVP(vp) != NULLVP)
1726 		vprint("union: upper", UPPERVP(vp));
1727 	if (LOWERVP(vp) != NULLVP)
1728 		vprint("union: lower", LOWERVP(vp));
1729 	if (VTOUNION(vp)->un_dircache) {
1730 		struct vnode **vpp;
1731 		for (vpp = VTOUNION(vp)->un_dircache; *vpp != NULLVP; vpp++)
1732 			vprint("dircache:", *vpp);
1733 	}
1734 
1735 	return (0);
1736 }
1737 
1738 int
1739 union_islocked(void *v)
1740 {
1741 	struct vop_islocked_args /* {
1742 		struct vnode *a_vp;
1743 	} */ *ap = v;
1744 	struct vnode *vp;
1745 	struct union_node *un;
1746 
1747 	un = VTOUNION(ap->a_vp);
1748 	mutex_enter(&un->un_lock);
1749 	vp = LOCKVP(ap->a_vp);
1750 	mutex_exit(&un->un_lock);
1751 
1752 	if (vp == ap->a_vp)
1753 		return genfs_islocked(ap);
1754 	else
1755 		return VOP_ISLOCKED(vp);
1756 }
1757 
1758 int
1759 union_pathconf(void *v)
1760 {
1761 	struct vop_pathconf_args /* {
1762 		struct vnode *a_vp;
1763 		int a_name;
1764 		int *a_retval;
1765 	} */ *ap = v;
1766 	int error;
1767 	struct vnode *vp = OTHERVP(ap->a_vp);
1768 	int dolock = (vp == LOWERVP(ap->a_vp));
1769 
1770 	if (dolock)
1771 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1772 	ap->a_vp = vp;
1773 	error = VCALL(vp, VOFFSET(vop_pathconf), ap);
1774 	if (dolock)
1775 		VOP_UNLOCK(vp);
1776 
1777 	return (error);
1778 }
1779 
1780 int
1781 union_advlock(void *v)
1782 {
1783 	struct vop_advlock_args /* {
1784 		struct vnode *a_vp;
1785 		void *a_id;
1786 		int  a_op;
1787 		struct flock *a_fl;
1788 		int  a_flags;
1789 	} */ *ap = v;
1790 	struct vnode *ovp = OTHERVP(ap->a_vp);
1791 
1792 	ap->a_vp = ovp;
1793 	return (VCALL(ovp, VOFFSET(vop_advlock), ap));
1794 }
1795 
1796 int
1797 union_strategy(void *v)
1798 {
1799 	struct vop_strategy_args /* {
1800 		struct vnode *a_vp;
1801 		struct buf *a_bp;
1802 	} */ *ap = v;
1803 	struct vnode *ovp = OTHERVP(ap->a_vp);
1804 	struct buf *bp = ap->a_bp;
1805 
1806 	KASSERT(ovp != NULLVP);
1807 	if (!NODE_IS_SPECIAL(ovp))
1808 		KASSERT((bp->b_flags & B_READ) || ovp != LOWERVP(bp->b_vp));
1809 
1810 	return (VOP_STRATEGY(ovp, bp));
1811 }
1812 
1813 int
1814 union_bwrite(void *v)
1815 {
1816 	struct vop_bwrite_args /* {
1817 		struct vnode *a_vp;
1818 		struct buf *a_bp;
1819 	} */ *ap = v;
1820 	struct vnode *ovp = OTHERVP(ap->a_vp);
1821 	struct buf *bp = ap->a_bp;
1822 
1823 	KASSERT(ovp != NULLVP);
1824 	if (!NODE_IS_SPECIAL(ovp))
1825 		KASSERT((bp->b_flags & B_READ) || ovp != LOWERVP(bp->b_vp));
1826 
1827 	return (VOP_BWRITE(ovp, bp));
1828 }
1829 
1830 int
1831 union_getpages(void *v)
1832 {
1833 	struct vop_getpages_args /* {
1834 		struct vnode *a_vp;
1835 		voff_t a_offset;
1836 		struct vm_page **a_m;
1837 		int *a_count;
1838 		int a_centeridx;
1839 		vm_prot_t a_access_type;
1840 		int a_advice;
1841 		int a_flags;
1842 	} */ *ap = v;
1843 	struct vnode *vp = ap->a_vp;
1844 
1845 	KASSERT(mutex_owned(vp->v_interlock));
1846 
1847 	if (ap->a_flags & PGO_LOCKED) {
1848 		return EBUSY;
1849 	}
1850 	ap->a_vp = OTHERVP(vp);
1851 	KASSERT(vp->v_interlock == ap->a_vp->v_interlock);
1852 
1853 	/* Just pass the request on to the underlying layer. */
1854 	return VCALL(ap->a_vp, VOFFSET(vop_getpages), ap);
1855 }
1856 
1857 int
1858 union_putpages(void *v)
1859 {
1860 	struct vop_putpages_args /* {
1861 		struct vnode *a_vp;
1862 		voff_t a_offlo;
1863 		voff_t a_offhi;
1864 		int a_flags;
1865 	} */ *ap = v;
1866 	struct vnode *vp = ap->a_vp;
1867 
1868 	KASSERT(mutex_owned(vp->v_interlock));
1869 
1870 	ap->a_vp = OTHERVP(vp);
1871 	KASSERT(vp->v_interlock == ap->a_vp->v_interlock);
1872 
1873 	if (ap->a_flags & PGO_RECLAIM) {
1874 		mutex_exit(vp->v_interlock);
1875 		return 0;
1876 	}
1877 
1878 	/* Just pass the request on to the underlying layer. */
1879 	return VCALL(ap->a_vp, VOFFSET(vop_putpages), ap);
1880 }
1881 
1882 int
1883 union_kqfilter(void *v)
1884 {
1885 	struct vop_kqfilter_args /* {
1886 		struct vnode	*a_vp;
1887 		struct knote	*a_kn;
1888 	} */ *ap = v;
1889 	int error;
1890 
1891 	/*
1892 	 * We watch either the upper layer file (if it already exists),
1893 	 * or the lower layer one. If there is lower layer file only
1894 	 * at this moment, we will keep watching that lower layer file
1895 	 * even if upper layer file would be created later on.
1896 	 */
1897 	if (UPPERVP(ap->a_vp))
1898 		error = VOP_KQFILTER(UPPERVP(ap->a_vp), ap->a_kn);
1899 	else if (LOWERVP(ap->a_vp))
1900 		error = VOP_KQFILTER(LOWERVP(ap->a_vp), ap->a_kn);
1901 	else {
1902 		/* panic? */
1903 		error = EOPNOTSUPP;
1904 	}
1905 
1906 	return (error);
1907 }
1908