xref: /freebsd/sys/fs/unionfs/union_vnops.c (revision 278d6950943a9fec2bddb037b547c04a847c54ba)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1992, 1993, 1994, 1995 Jan-Simon Pendry.
5  * Copyright (c) 1992, 1993, 1994, 1995
6  *      The Regents of the University of California.
7  * Copyright (c) 2005, 2006, 2012 Masanori Ozawa <ozawa@ongs.co.jp>, ONGS Inc.
8  * Copyright (c) 2006, 2012 Daichi Goto <daichi@freebsd.org>
9  * All rights reserved.
10  *
11  * This code is derived from software contributed to Berkeley by
12  * Jan-Simon Pendry.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  */
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/conf.h>
43 #include <sys/kernel.h>
44 #include <sys/lock.h>
45 #include <sys/malloc.h>
46 #include <sys/mount.h>
47 #include <sys/mutex.h>
48 #include <sys/namei.h>
49 #include <sys/sysctl.h>
50 #include <sys/vnode.h>
51 #include <sys/kdb.h>
52 #include <sys/fcntl.h>
53 #include <sys/stat.h>
54 #include <sys/dirent.h>
55 #include <sys/proc.h>
56 #include <sys/bio.h>
57 #include <sys/buf.h>
58 
59 #include <fs/unionfs/union.h>
60 
61 #include <machine/atomic.h>
62 
63 #include <vm/vm.h>
64 #include <vm/vm_extern.h>
65 #include <vm/vm_object.h>
66 #include <vm/vnode_pager.h>
67 
68 #if 0
69 #define UNIONFS_INTERNAL_DEBUG(msg, args...)    printf(msg, ## args)
70 #define UNIONFS_IDBG_RENAME
71 #else
72 #define UNIONFS_INTERNAL_DEBUG(msg, args...)
73 #endif
74 
75 #define KASSERT_UNIONFS_VNODE(vp) \
76 	VNASSERT(((vp)->v_op == &unionfs_vnodeops), vp, \
77 	    ("%s: non-unionfs vnode", __func__))
78 
79 static int
80 unionfs_lookup(struct vop_cachedlookup_args *ap)
81 {
82 	struct unionfs_node *dunp, *unp;
83 	struct vnode   *dvp, *udvp, *ldvp, *vp, *uvp, *lvp, *dtmpvp;
84 	struct vattr	va;
85 	struct componentname *cnp;
86 	struct thread  *td;
87 	u_long		nameiop;
88 	u_long		cnflags, cnflagsbk;
89 	int		iswhiteout;
90 	int		lockflag;
91 	int		error , uerror, lerror;
92 
93 	iswhiteout = 0;
94 	lockflag = 0;
95 	error = uerror = lerror = ENOENT;
96 	cnp = ap->a_cnp;
97 	nameiop = cnp->cn_nameiop;
98 	cnflags = cnp->cn_flags;
99 	dvp = ap->a_dvp;
100 	dunp = VTOUNIONFS(dvp);
101 	udvp = dunp->un_uppervp;
102 	ldvp = dunp->un_lowervp;
103 	vp = uvp = lvp = NULLVP;
104 	td = curthread;
105 	*(ap->a_vpp) = NULLVP;
106 
107 	UNIONFS_INTERNAL_DEBUG(
108 	    "unionfs_lookup: enter: nameiop=%ld, flags=%lx, path=%s\n",
109 	    nameiop, cnflags, cnp->cn_nameptr);
110 
111 	if (dvp->v_type != VDIR)
112 		return (ENOTDIR);
113 
114 	/*
115 	 * If read-only and op is not LOOKUP, will return EROFS.
116 	 */
117 	if ((cnflags & ISLASTCN) &&
118 	    (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
119 	    LOOKUP != nameiop)
120 		return (EROFS);
121 
122 	/*
123 	 * lookup dotdot
124 	 */
125 	if (cnflags & ISDOTDOT) {
126 		if (LOOKUP != nameiop && udvp == NULLVP)
127 			return (EROFS);
128 
129 		if (udvp != NULLVP) {
130 			dtmpvp = udvp;
131 			if (ldvp != NULLVP)
132 				VOP_UNLOCK(ldvp);
133 		}
134 		else
135 			dtmpvp = ldvp;
136 
137 		error = VOP_LOOKUP(dtmpvp, &vp, cnp);
138 
139 		if (dtmpvp == udvp && ldvp != NULLVP) {
140 			VOP_UNLOCK(udvp);
141 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
142 			dunp = VTOUNIONFS(dvp);
143 			if (error == 0 && dunp == NULL)
144 				error = ENOENT;
145 		}
146 
147 		if (error == 0) {
148 			/*
149 			 * Exchange lock and reference from vp to
150 			 * dunp->un_dvp. vp is upper/lower vnode, but it
151 			 * will need to return the unionfs vnode.
152 			 */
153 			if (nameiop == DELETE  || nameiop == RENAME ||
154 			    (cnp->cn_lkflags & LK_TYPE_MASK))
155 				VOP_UNLOCK(vp);
156 			vrele(vp);
157 
158 			dtmpvp = dunp->un_dvp;
159 			vref(dtmpvp);
160 			VOP_UNLOCK(dvp);
161 			*(ap->a_vpp) = dtmpvp;
162 
163 			if (nameiop == DELETE || nameiop == RENAME)
164 				vn_lock(dtmpvp, LK_EXCLUSIVE | LK_RETRY);
165 			else if (cnp->cn_lkflags & LK_TYPE_MASK)
166 				vn_lock(dtmpvp, cnp->cn_lkflags |
167 				    LK_RETRY);
168 
169 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
170 		} else if (error == ENOENT && (cnflags & MAKEENTRY) != 0)
171 			cache_enter(dvp, NULLVP, cnp);
172 
173 		goto unionfs_lookup_return;
174 	}
175 
176 	/*
177 	 * lookup upper layer
178 	 */
179 	if (udvp != NULLVP) {
180 		uerror = VOP_LOOKUP(udvp, &uvp, cnp);
181 
182 		if (uerror == 0) {
183 			if (udvp == uvp) {	/* is dot */
184 				vrele(uvp);
185 				*(ap->a_vpp) = dvp;
186 				vref(dvp);
187 
188 				error = uerror;
189 				goto unionfs_lookup_return;
190 			}
191 			if (nameiop == DELETE || nameiop == RENAME ||
192 			    (cnp->cn_lkflags & LK_TYPE_MASK))
193 				VOP_UNLOCK(uvp);
194 		}
195 
196 		/* check whiteout */
197 		if (uerror == ENOENT || uerror == EJUSTRETURN)
198 			if (cnp->cn_flags & ISWHITEOUT)
199 				iswhiteout = 1;	/* don't lookup lower */
200 		if (iswhiteout == 0 && ldvp != NULLVP)
201 			if (!VOP_GETATTR(udvp, &va, cnp->cn_cred) &&
202 			    (va.va_flags & OPAQUE))
203 				iswhiteout = 1;	/* don't lookup lower */
204 #if 0
205 		UNIONFS_INTERNAL_DEBUG(
206 		    "unionfs_lookup: debug: whiteout=%d, path=%s\n",
207 		    iswhiteout, cnp->cn_nameptr);
208 #endif
209 	}
210 
211 	/*
212 	 * lookup lower layer
213 	 */
214 	if (ldvp != NULLVP && !(cnflags & DOWHITEOUT) && iswhiteout == 0) {
215 		/* always op is LOOKUP */
216 		cnp->cn_nameiop = LOOKUP;
217 		cnflagsbk = cnp->cn_flags;
218 		cnp->cn_flags = cnflags;
219 
220 		lerror = VOP_LOOKUP(ldvp, &lvp, cnp);
221 
222 		cnp->cn_nameiop = nameiop;
223 		if (udvp != NULLVP && (uerror == 0 || uerror == EJUSTRETURN))
224 			cnp->cn_flags = cnflagsbk;
225 
226 		if (lerror == 0) {
227 			if (ldvp == lvp) {	/* is dot */
228 				if (uvp != NULLVP)
229 					vrele(uvp);	/* no need? */
230 				vrele(lvp);
231 				*(ap->a_vpp) = dvp;
232 				vref(dvp);
233 
234 				UNIONFS_INTERNAL_DEBUG(
235 				    "unionfs_lookup: leave (%d)\n", lerror);
236 
237 				return (lerror);
238 			}
239 			if (cnp->cn_lkflags & LK_TYPE_MASK)
240 				VOP_UNLOCK(lvp);
241 		}
242 	}
243 
244 	/*
245 	 * check lookup result
246 	 */
247 	if (uvp == NULLVP && lvp == NULLVP) {
248 		error = (udvp != NULLVP ? uerror : lerror);
249 		goto unionfs_lookup_return;
250 	}
251 
252 	/*
253 	 * check vnode type
254 	 */
255 	if (uvp != NULLVP && lvp != NULLVP && uvp->v_type != lvp->v_type) {
256 		vrele(lvp);
257 		lvp = NULLVP;
258 	}
259 
260 	/*
261 	 * check shadow dir
262 	 */
263 	if (uerror != 0 && uerror != EJUSTRETURN && udvp != NULLVP &&
264 	    lerror == 0 && lvp != NULLVP && lvp->v_type == VDIR &&
265 	    !(dvp->v_mount->mnt_flag & MNT_RDONLY) &&
266 	    (1 < cnp->cn_namelen || '.' != *(cnp->cn_nameptr))) {
267 		/* get unionfs vnode in order to create a new shadow dir. */
268 		error = unionfs_nodeget(dvp->v_mount, NULLVP, lvp, dvp, &vp,
269 		    cnp);
270 		if (error != 0)
271 			goto unionfs_lookup_cleanup;
272 
273 		if (LK_SHARED == (cnp->cn_lkflags & LK_TYPE_MASK))
274 			VOP_UNLOCK(vp);
275 		if (LK_EXCLUSIVE != VOP_ISLOCKED(vp)) {
276 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
277 			lockflag = 1;
278 		}
279 		unp = VTOUNIONFS(vp);
280 		if (unp == NULL)
281 			error = ENOENT;
282 		else
283 			error = unionfs_mkshadowdir(MOUNTTOUNIONFSMOUNT(dvp->v_mount),
284 			    udvp, unp, cnp, td);
285 		if (lockflag != 0)
286 			VOP_UNLOCK(vp);
287 		if (error != 0) {
288 			UNIONFSDEBUG(
289 			    "unionfs_lookup: Unable to create shadow dir.");
290 			if ((cnp->cn_lkflags & LK_TYPE_MASK) == LK_EXCLUSIVE)
291 				vput(vp);
292 			else
293 				vrele(vp);
294 			goto unionfs_lookup_cleanup;
295 		}
296 		if ((cnp->cn_lkflags & LK_TYPE_MASK) == LK_SHARED)
297 			vn_lock(vp, LK_SHARED | LK_RETRY);
298 	}
299 	/*
300 	 * get unionfs vnode.
301 	 */
302 	else {
303 		if (uvp != NULLVP)
304 			error = uerror;
305 		else
306 			error = lerror;
307 		if (error != 0)
308 			goto unionfs_lookup_cleanup;
309 		error = unionfs_nodeget(dvp->v_mount, uvp, lvp,
310 		    dvp, &vp, cnp);
311 		if (error != 0) {
312 			UNIONFSDEBUG(
313 			    "unionfs_lookup: Unable to create unionfs vnode.");
314 			goto unionfs_lookup_cleanup;
315 		}
316 		if ((nameiop == DELETE || nameiop == RENAME) &&
317 		    (cnp->cn_lkflags & LK_TYPE_MASK) == 0)
318 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
319 	}
320 
321 	*(ap->a_vpp) = vp;
322 
323 	if (cnflags & MAKEENTRY)
324 		cache_enter(dvp, vp, cnp);
325 
326 unionfs_lookup_cleanup:
327 	if (uvp != NULLVP)
328 		vrele(uvp);
329 	if (lvp != NULLVP)
330 		vrele(lvp);
331 
332 	if (error == ENOENT && (cnflags & MAKEENTRY) != 0)
333 		cache_enter(dvp, NULLVP, cnp);
334 
335 unionfs_lookup_return:
336 
337 	UNIONFS_INTERNAL_DEBUG("unionfs_lookup: leave (%d)\n", error);
338 
339 	return (error);
340 }
341 
342 static int
343 unionfs_create(struct vop_create_args *ap)
344 {
345 	struct unionfs_node *dunp;
346 	struct componentname *cnp;
347 	struct vnode   *udvp;
348 	struct vnode   *vp;
349 	int		error;
350 
351 	UNIONFS_INTERNAL_DEBUG("unionfs_create: enter\n");
352 
353 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
354 
355 	dunp = VTOUNIONFS(ap->a_dvp);
356 	cnp = ap->a_cnp;
357 	udvp = dunp->un_uppervp;
358 	error = EROFS;
359 
360 	if (udvp != NULLVP) {
361 		int lkflags;
362 		bool vp_created = false;
363 		unionfs_forward_vop_start(udvp, &lkflags);
364 		error = VOP_CREATE(udvp, &vp, cnp, ap->a_vap);
365 		if (error == 0)
366 			vp_created = true;
367 		if (__predict_false(unionfs_forward_vop_finish(ap->a_dvp, udvp,
368 		    lkflags)) && error == 0) {
369 			error = ENOENT;
370 		}
371 		if (error == 0) {
372 			VOP_UNLOCK(vp);
373 			error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
374 			    ap->a_dvp, ap->a_vpp, cnp);
375 			vrele(vp);
376 		} else if (vp_created)
377 			vput(vp);
378 	}
379 
380 	UNIONFS_INTERNAL_DEBUG("unionfs_create: leave (%d)\n", error);
381 
382 	return (error);
383 }
384 
385 static int
386 unionfs_whiteout(struct vop_whiteout_args *ap)
387 {
388 	struct unionfs_node *dunp;
389 	struct componentname *cnp;
390 	struct vnode   *udvp;
391 	int		error;
392 
393 	UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: enter\n");
394 
395 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
396 
397 	dunp = VTOUNIONFS(ap->a_dvp);
398 	cnp = ap->a_cnp;
399 	udvp = dunp->un_uppervp;
400 	error = EOPNOTSUPP;
401 
402 	if (udvp != NULLVP) {
403 		int lkflags;
404 		switch (ap->a_flags) {
405 		case CREATE:
406 		case DELETE:
407 		case LOOKUP:
408 			unionfs_forward_vop_start(udvp, &lkflags);
409 			error = VOP_WHITEOUT(udvp, cnp, ap->a_flags);
410 			unionfs_forward_vop_finish(ap->a_dvp, udvp, lkflags);
411 			break;
412 		default:
413 			error = EINVAL;
414 			break;
415 		}
416 	}
417 
418 	UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: leave (%d)\n", error);
419 
420 	return (error);
421 }
422 
423 static int
424 unionfs_mknod(struct vop_mknod_args *ap)
425 {
426 	struct unionfs_node *dunp;
427 	struct componentname *cnp;
428 	struct vnode   *udvp;
429 	struct vnode   *vp;
430 	int		error;
431 
432 	UNIONFS_INTERNAL_DEBUG("unionfs_mknod: enter\n");
433 
434 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
435 
436 	dunp = VTOUNIONFS(ap->a_dvp);
437 	cnp = ap->a_cnp;
438 	udvp = dunp->un_uppervp;
439 	error = EROFS;
440 
441 	if (udvp != NULLVP) {
442 		int lkflags;
443 		bool vp_created = false;
444 		unionfs_forward_vop_start(udvp, &lkflags);
445 		error = VOP_MKNOD(udvp, &vp, cnp, ap->a_vap);
446 		if (error == 0)
447 			vp_created = true;
448 		if (__predict_false(unionfs_forward_vop_finish(ap->a_dvp, udvp,
449 		    lkflags)) && error == 0) {
450 			error = ENOENT;
451 		}
452 		if (error == 0) {
453 			VOP_UNLOCK(vp);
454 			error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
455 			    ap->a_dvp, ap->a_vpp, cnp);
456 			vrele(vp);
457 		} else if (vp_created)
458 			vput(vp);
459 	}
460 
461 	UNIONFS_INTERNAL_DEBUG("unionfs_mknod: leave (%d)\n", error);
462 
463 	return (error);
464 }
465 
466 enum unionfs_lkupgrade {
467 	UNIONFS_LKUPGRADE_SUCCESS, /* lock successfully upgraded */
468 	UNIONFS_LKUPGRADE_ALREADY, /* lock already held exclusive */
469 	UNIONFS_LKUPGRADE_DOOMED   /* lock was upgraded, but vnode reclaimed */
470 };
471 
472 static inline enum unionfs_lkupgrade
473 unionfs_upgrade_lock(struct vnode *vp)
474 {
475 	ASSERT_VOP_LOCKED(vp, __func__);
476 
477 	if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE)
478 		return (UNIONFS_LKUPGRADE_ALREADY);
479 
480 	if (vn_lock(vp, LK_UPGRADE) != 0) {
481 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
482 		if (VN_IS_DOOMED(vp))
483 			return (UNIONFS_LKUPGRADE_DOOMED);
484 	}
485 	return (UNIONFS_LKUPGRADE_SUCCESS);
486 }
487 
488 static inline void
489 unionfs_downgrade_lock(struct vnode *vp, enum unionfs_lkupgrade status)
490 {
491 	if (status != UNIONFS_LKUPGRADE_ALREADY)
492 		vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
493 }
494 
495 static int
496 unionfs_open(struct vop_open_args *ap)
497 {
498 	struct unionfs_node *unp;
499 	struct unionfs_node_status *unsp;
500 	struct vnode   *vp;
501 	struct vnode   *uvp;
502 	struct vnode   *lvp;
503 	struct vnode   *targetvp;
504 	struct ucred   *cred;
505 	struct thread  *td;
506 	int		error;
507 	enum unionfs_lkupgrade lkstatus;
508 
509 	UNIONFS_INTERNAL_DEBUG("unionfs_open: enter\n");
510 
511 	KASSERT_UNIONFS_VNODE(ap->a_vp);
512 
513 	error = 0;
514 	vp = ap->a_vp;
515 	targetvp = NULLVP;
516 	cred = ap->a_cred;
517 	td = ap->a_td;
518 
519 	/*
520 	 * The executable loader path may call this function with vp locked
521 	 * shared.  If the vnode is reclaimed while upgrading, we can't safely
522 	 * use unp or do anything else unionfs- specific.
523 	 */
524 	lkstatus = unionfs_upgrade_lock(vp);
525 	if (lkstatus == UNIONFS_LKUPGRADE_DOOMED) {
526 		error = ENOENT;
527 		goto unionfs_open_cleanup;
528 	}
529 
530 	unp = VTOUNIONFS(vp);
531 	uvp = unp->un_uppervp;
532 	lvp = unp->un_lowervp;
533 	unionfs_get_node_status(unp, td, &unsp);
534 
535 	if (unsp->uns_lower_opencnt > 0 || unsp->uns_upper_opencnt > 0) {
536 		/* vnode is already opend. */
537 		if (unsp->uns_upper_opencnt > 0)
538 			targetvp = uvp;
539 		else
540 			targetvp = lvp;
541 
542 		if (targetvp == lvp &&
543 		    (ap->a_mode & FWRITE) && lvp->v_type == VREG)
544 			targetvp = NULLVP;
545 	}
546 	if (targetvp == NULLVP) {
547 		if (uvp == NULLVP) {
548 			if ((ap->a_mode & FWRITE) && lvp->v_type == VREG) {
549 				error = unionfs_copyfile(unp,
550 				    !(ap->a_mode & O_TRUNC), cred, td);
551 				if (error != 0)
552 					goto unionfs_open_abort;
553 				targetvp = uvp = unp->un_uppervp;
554 			} else
555 				targetvp = lvp;
556 		} else
557 			targetvp = uvp;
558 	}
559 
560 	error = VOP_OPEN(targetvp, ap->a_mode, cred, td, ap->a_fp);
561 	if (error == 0) {
562 		if (targetvp == uvp) {
563 			if (uvp->v_type == VDIR && lvp != NULLVP &&
564 			    unsp->uns_lower_opencnt <= 0) {
565 				/* open lower for readdir */
566 				error = VOP_OPEN(lvp, FREAD, cred, td, NULL);
567 				if (error != 0) {
568 					VOP_CLOSE(uvp, ap->a_mode, cred, td);
569 					goto unionfs_open_abort;
570 				}
571 				unsp->uns_node_flag |= UNS_OPENL_4_READDIR;
572 				unsp->uns_lower_opencnt++;
573 			}
574 			unsp->uns_upper_opencnt++;
575 		} else {
576 			unsp->uns_lower_opencnt++;
577 			unsp->uns_lower_openmode = ap->a_mode;
578 		}
579 		vp->v_object = targetvp->v_object;
580 	}
581 
582 unionfs_open_abort:
583 	if (error != 0)
584 		unionfs_tryrem_node_status(unp, unsp);
585 
586 unionfs_open_cleanup:
587 	unionfs_downgrade_lock(vp, lkstatus);
588 
589 	UNIONFS_INTERNAL_DEBUG("unionfs_open: leave (%d)\n", error);
590 
591 	return (error);
592 }
593 
594 static int
595 unionfs_close(struct vop_close_args *ap)
596 {
597 	struct unionfs_node *unp;
598 	struct unionfs_node_status *unsp;
599 	struct ucred   *cred;
600 	struct thread  *td;
601 	struct vnode   *vp;
602 	struct vnode   *ovp;
603 	int		error;
604 	enum unionfs_lkupgrade lkstatus;
605 
606 	UNIONFS_INTERNAL_DEBUG("unionfs_close: enter\n");
607 
608 	KASSERT_UNIONFS_VNODE(ap->a_vp);
609 
610 	vp = ap->a_vp;
611 	cred = ap->a_cred;
612 	td = ap->a_td;
613 	error = 0;
614 
615 	/*
616 	 * If the vnode is reclaimed while upgrading, we can't safely use unp
617 	 * or do anything else unionfs- specific.
618 	 */
619 	lkstatus = unionfs_upgrade_lock(vp);
620 	if (lkstatus == UNIONFS_LKUPGRADE_DOOMED)
621 		goto unionfs_close_cleanup;
622 
623 	unp = VTOUNIONFS(vp);
624 	unionfs_get_node_status(unp, td, &unsp);
625 
626 	if (unsp->uns_lower_opencnt <= 0 && unsp->uns_upper_opencnt <= 0) {
627 #ifdef DIAGNOSTIC
628 		printf("unionfs_close: warning: open count is 0\n");
629 #endif
630 		if (unp->un_uppervp != NULLVP)
631 			ovp = unp->un_uppervp;
632 		else
633 			ovp = unp->un_lowervp;
634 	} else if (unsp->uns_upper_opencnt > 0)
635 		ovp = unp->un_uppervp;
636 	else
637 		ovp = unp->un_lowervp;
638 
639 	error = VOP_CLOSE(ovp, ap->a_fflag, cred, td);
640 
641 	if (error != 0)
642 		goto unionfs_close_abort;
643 
644 	vp->v_object = ovp->v_object;
645 
646 	if (ovp == unp->un_uppervp) {
647 		unsp->uns_upper_opencnt--;
648 		if (unsp->uns_upper_opencnt == 0) {
649 			if (unsp->uns_node_flag & UNS_OPENL_4_READDIR) {
650 				VOP_CLOSE(unp->un_lowervp, FREAD, cred, td);
651 				unsp->uns_node_flag &= ~UNS_OPENL_4_READDIR;
652 				unsp->uns_lower_opencnt--;
653 			}
654 			if (unsp->uns_lower_opencnt > 0)
655 				vp->v_object = unp->un_lowervp->v_object;
656 		}
657 	} else
658 		unsp->uns_lower_opencnt--;
659 
660 unionfs_close_abort:
661 	unionfs_tryrem_node_status(unp, unsp);
662 
663 unionfs_close_cleanup:
664 	unionfs_downgrade_lock(vp, lkstatus);
665 
666 	UNIONFS_INTERNAL_DEBUG("unionfs_close: leave (%d)\n", error);
667 
668 	return (error);
669 }
670 
671 /*
672  * Check the access mode toward shadow file/dir.
673  */
674 static int
675 unionfs_check_corrected_access(accmode_t accmode, struct vattr *va,
676     struct ucred *cred)
677 {
678 	uid_t		uid;	/* upper side vnode's uid */
679 	gid_t		gid;	/* upper side vnode's gid */
680 	u_short		vmode;	/* upper side vnode's mode */
681 	u_short		mask;
682 
683 	mask = 0;
684 	uid = va->va_uid;
685 	gid = va->va_gid;
686 	vmode = va->va_mode;
687 
688 	/* check owner */
689 	if (cred->cr_uid == uid) {
690 		if (accmode & VEXEC)
691 			mask |= S_IXUSR;
692 		if (accmode & VREAD)
693 			mask |= S_IRUSR;
694 		if (accmode & VWRITE)
695 			mask |= S_IWUSR;
696 		return ((vmode & mask) == mask ? 0 : EACCES);
697 	}
698 
699 	/* check group */
700 	if (groupmember(gid, cred)) {
701 		if (accmode & VEXEC)
702 			mask |= S_IXGRP;
703 		if (accmode & VREAD)
704 			mask |= S_IRGRP;
705 		if (accmode & VWRITE)
706 			mask |= S_IWGRP;
707 		return ((vmode & mask) == mask ? 0 : EACCES);
708 	}
709 
710 	/* check other */
711 	if (accmode & VEXEC)
712 		mask |= S_IXOTH;
713 	if (accmode & VREAD)
714 		mask |= S_IROTH;
715 	if (accmode & VWRITE)
716 		mask |= S_IWOTH;
717 
718 	return ((vmode & mask) == mask ? 0 : EACCES);
719 }
720 
721 static int
722 unionfs_access(struct vop_access_args *ap)
723 {
724 	struct unionfs_mount *ump;
725 	struct unionfs_node *unp;
726 	struct vnode   *uvp;
727 	struct vnode   *lvp;
728 	struct thread  *td;
729 	struct vattr	va;
730 	accmode_t	accmode;
731 	int		error;
732 
733 	UNIONFS_INTERNAL_DEBUG("unionfs_access: enter\n");
734 
735 	KASSERT_UNIONFS_VNODE(ap->a_vp);
736 
737 	ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
738 	unp = VTOUNIONFS(ap->a_vp);
739 	uvp = unp->un_uppervp;
740 	lvp = unp->un_lowervp;
741 	td = ap->a_td;
742 	accmode = ap->a_accmode;
743 	error = EACCES;
744 
745 	if ((accmode & VWRITE) &&
746 	    (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)) {
747 		switch (ap->a_vp->v_type) {
748 		case VREG:
749 		case VDIR:
750 		case VLNK:
751 			return (EROFS);
752 		default:
753 			break;
754 		}
755 	}
756 
757 	if (uvp != NULLVP) {
758 		error = VOP_ACCESS(uvp, accmode, ap->a_cred, td);
759 
760 		UNIONFS_INTERNAL_DEBUG("unionfs_access: leave (%d)\n", error);
761 
762 		return (error);
763 	}
764 
765 	if (lvp != NULLVP) {
766 		if (accmode & VWRITE) {
767 			if ((ump->um_uppermp->mnt_flag & MNT_RDONLY) != 0) {
768 				switch (ap->a_vp->v_type) {
769 				case VREG:
770 				case VDIR:
771 				case VLNK:
772 					return (EROFS);
773 				default:
774 					break;
775 				}
776 			} else if (ap->a_vp->v_type == VREG ||
777 			    ap->a_vp->v_type == VDIR) {
778 				/* check shadow file/dir */
779 				if (ump->um_copymode != UNIONFS_TRANSPARENT) {
780 					error = unionfs_create_uppervattr(ump,
781 					    lvp, &va, ap->a_cred, td);
782 					if (error != 0)
783 						return (error);
784 
785 					error = unionfs_check_corrected_access(
786 					    accmode, &va, ap->a_cred);
787 					if (error != 0)
788 						return (error);
789 				}
790 			}
791 			accmode &= ~(VWRITE | VAPPEND);
792 			accmode |= VREAD; /* will copy to upper */
793 		}
794 		error = VOP_ACCESS(lvp, accmode, ap->a_cred, td);
795 	}
796 
797 	UNIONFS_INTERNAL_DEBUG("unionfs_access: leave (%d)\n", error);
798 
799 	return (error);
800 }
801 
802 static int
803 unionfs_getattr(struct vop_getattr_args *ap)
804 {
805 	struct unionfs_node *unp;
806 	struct unionfs_mount *ump;
807 	struct vnode   *uvp;
808 	struct vnode   *lvp;
809 	struct thread  *td;
810 	struct vattr	va;
811 	int		error;
812 
813 	UNIONFS_INTERNAL_DEBUG("unionfs_getattr: enter\n");
814 
815 	KASSERT_UNIONFS_VNODE(ap->a_vp);
816 
817 	unp = VTOUNIONFS(ap->a_vp);
818 	ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
819 	uvp = unp->un_uppervp;
820 	lvp = unp->un_lowervp;
821 	td = curthread;
822 
823 	if (uvp != NULLVP) {
824 		if ((error = VOP_GETATTR(uvp, ap->a_vap, ap->a_cred)) == 0)
825 			ap->a_vap->va_fsid =
826 			    ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
827 
828 		UNIONFS_INTERNAL_DEBUG(
829 		    "unionfs_getattr: leave mode=%o, uid=%d, gid=%d (%d)\n",
830 		    ap->a_vap->va_mode, ap->a_vap->va_uid,
831 		    ap->a_vap->va_gid, error);
832 
833 		return (error);
834 	}
835 
836 	error = VOP_GETATTR(lvp, ap->a_vap, ap->a_cred);
837 
838 	if (error == 0 && (ump->um_uppermp->mnt_flag & MNT_RDONLY) == 0) {
839 		/* correct the attr toward shadow file/dir. */
840 		if (ap->a_vp->v_type == VREG || ap->a_vp->v_type == VDIR) {
841 			unionfs_create_uppervattr_core(ump, ap->a_vap, &va, td);
842 			ap->a_vap->va_mode = va.va_mode;
843 			ap->a_vap->va_uid = va.va_uid;
844 			ap->a_vap->va_gid = va.va_gid;
845 		}
846 	}
847 
848 	if (error == 0)
849 		ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
850 
851 	UNIONFS_INTERNAL_DEBUG(
852 	    "unionfs_getattr: leave mode=%o, uid=%d, gid=%d (%d)\n",
853 	    ap->a_vap->va_mode, ap->a_vap->va_uid, ap->a_vap->va_gid, error);
854 
855 	return (error);
856 }
857 
858 static int
859 unionfs_setattr(struct vop_setattr_args *ap)
860 {
861 	struct unionfs_node *unp;
862 	struct vnode   *uvp;
863 	struct vnode   *lvp;
864 	struct thread  *td;
865 	struct vattr   *vap;
866 	int		error;
867 
868 	UNIONFS_INTERNAL_DEBUG("unionfs_setattr: enter\n");
869 
870 	KASSERT_UNIONFS_VNODE(ap->a_vp);
871 
872 	error = EROFS;
873 	unp = VTOUNIONFS(ap->a_vp);
874 	uvp = unp->un_uppervp;
875 	lvp = unp->un_lowervp;
876 	td = curthread;
877 	vap = ap->a_vap;
878 
879 	if ((ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) &&
880 	    (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
881 	     vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
882 	     vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL))
883 		return (EROFS);
884 
885 	if (uvp == NULLVP && lvp->v_type == VREG) {
886 		error = unionfs_copyfile(unp, (vap->va_size != 0),
887 		    ap->a_cred, td);
888 		if (error != 0)
889 			return (error);
890 		uvp = unp->un_uppervp;
891 	}
892 
893 	if (uvp != NULLVP) {
894 		int lkflags;
895 		unionfs_forward_vop_start(uvp, &lkflags);
896 		error = VOP_SETATTR(uvp, vap, ap->a_cred);
897 		unionfs_forward_vop_finish(ap->a_vp, uvp, lkflags);
898 	}
899 
900 	UNIONFS_INTERNAL_DEBUG("unionfs_setattr: leave (%d)\n", error);
901 
902 	return (error);
903 }
904 
905 static int
906 unionfs_read(struct vop_read_args *ap)
907 {
908 	struct unionfs_node *unp;
909 	struct vnode   *tvp;
910 	int		error;
911 
912 	/* UNIONFS_INTERNAL_DEBUG("unionfs_read: enter\n"); */
913 
914 	KASSERT_UNIONFS_VNODE(ap->a_vp);
915 
916 	unp = VTOUNIONFS(ap->a_vp);
917 	tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
918 
919 	error = VOP_READ(tvp, ap->a_uio, ap->a_ioflag, ap->a_cred);
920 
921 	/* UNIONFS_INTERNAL_DEBUG("unionfs_read: leave (%d)\n", error); */
922 
923 	return (error);
924 }
925 
926 static int
927 unionfs_write(struct vop_write_args *ap)
928 {
929 	struct unionfs_node *unp;
930 	struct vnode   *tvp;
931 	int		error;
932 	int		lkflags;
933 
934 	/* UNIONFS_INTERNAL_DEBUG("unionfs_write: enter\n"); */
935 
936 	KASSERT_UNIONFS_VNODE(ap->a_vp);
937 
938 	unp = VTOUNIONFS(ap->a_vp);
939 	tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
940 
941 	unionfs_forward_vop_start(tvp, &lkflags);
942 	error = VOP_WRITE(tvp, ap->a_uio, ap->a_ioflag, ap->a_cred);
943 	unionfs_forward_vop_finish(ap->a_vp, tvp, lkflags);
944 
945 	/* UNIONFS_INTERNAL_DEBUG("unionfs_write: leave (%d)\n", error); */
946 
947 	return (error);
948 }
949 
950 static int
951 unionfs_ioctl(struct vop_ioctl_args *ap)
952 {
953 	struct unionfs_node *unp;
954 	struct unionfs_node_status *unsp;
955 	struct vnode   *ovp;
956 	int error;
957 
958 	UNIONFS_INTERNAL_DEBUG("unionfs_ioctl: enter\n");
959 
960 	KASSERT_UNIONFS_VNODE(ap->a_vp);
961 
962  	vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
963 	unp = VTOUNIONFS(ap->a_vp);
964 	unionfs_get_node_status(unp, ap->a_td, &unsp);
965 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
966 	unionfs_tryrem_node_status(unp, unsp);
967 	VOP_UNLOCK(ap->a_vp);
968 
969 	if (ovp == NULLVP)
970 		return (EBADF);
971 
972 	error = VOP_IOCTL(ovp, ap->a_command, ap->a_data, ap->a_fflag,
973 	    ap->a_cred, ap->a_td);
974 
975 	UNIONFS_INTERNAL_DEBUG("unionfs_ioctl: leave (%d)\n", error);
976 
977 	return (error);
978 }
979 
980 static int
981 unionfs_poll(struct vop_poll_args *ap)
982 {
983 	struct unionfs_node *unp;
984 	struct unionfs_node_status *unsp;
985 	struct vnode *ovp;
986 
987 	KASSERT_UNIONFS_VNODE(ap->a_vp);
988 
989  	vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
990 	unp = VTOUNIONFS(ap->a_vp);
991 	unionfs_get_node_status(unp, ap->a_td, &unsp);
992 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
993 	unionfs_tryrem_node_status(unp, unsp);
994 	VOP_UNLOCK(ap->a_vp);
995 
996 	if (ovp == NULLVP)
997 		return (EBADF);
998 
999 	return (VOP_POLL(ovp, ap->a_events, ap->a_cred, ap->a_td));
1000 }
1001 
1002 static int
1003 unionfs_fsync(struct vop_fsync_args *ap)
1004 {
1005 	struct unionfs_node *unp;
1006 	struct unionfs_node_status *unsp;
1007 	struct vnode *ovp;
1008 	enum unionfs_lkupgrade lkstatus;
1009 	int error, lkflags;
1010 
1011 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1012 
1013 	unp = VTOUNIONFS(ap->a_vp);
1014 	lkstatus = unionfs_upgrade_lock(ap->a_vp);
1015 	if (lkstatus == UNIONFS_LKUPGRADE_DOOMED) {
1016 		unionfs_downgrade_lock(ap->a_vp, lkstatus);
1017 		return (ENOENT);
1018 	}
1019 	unionfs_get_node_status(unp, ap->a_td, &unsp);
1020 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
1021 	unionfs_tryrem_node_status(unp, unsp);
1022 
1023 	unionfs_downgrade_lock(ap->a_vp, lkstatus);
1024 
1025 	if (ovp == NULLVP)
1026 		return (EBADF);
1027 
1028 	unionfs_forward_vop_start(ovp, &lkflags);
1029 	error = VOP_FSYNC(ovp, ap->a_waitfor, ap->a_td);
1030 	unionfs_forward_vop_finish(ap->a_vp, ovp, lkflags);
1031 
1032 	return (error);
1033 }
1034 
1035 static int
1036 unionfs_remove(struct vop_remove_args *ap)
1037 {
1038 	char	       *path;
1039 	struct unionfs_node *dunp;
1040 	struct unionfs_node *unp;
1041 	struct unionfs_mount *ump;
1042 	struct vnode   *udvp;
1043 	struct vnode   *uvp;
1044 	struct vnode   *lvp;
1045 	struct componentname *cnp;
1046 	struct thread  *td;
1047 	int		error;
1048 	int		pathlen;
1049 
1050 	UNIONFS_INTERNAL_DEBUG("unionfs_remove: enter\n");
1051 
1052 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
1053 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1054 
1055 	error = 0;
1056 	dunp = VTOUNIONFS(ap->a_dvp);
1057 	udvp = dunp->un_uppervp;
1058 	cnp = ap->a_cnp;
1059 	td = curthread;
1060 
1061 	ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
1062 	unp = VTOUNIONFS(ap->a_vp);
1063 	uvp = unp->un_uppervp;
1064 	lvp = unp->un_lowervp;
1065 	path = unp->un_path;
1066 	pathlen = unp->un_pathlen;
1067 
1068 	if (udvp == NULLVP)
1069 		return (EROFS);
1070 
1071 	if (uvp != NULLVP) {
1072 		int udvp_lkflags, uvp_lkflags;
1073 		if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS ||
1074 		    lvp != NULLVP)
1075 			cnp->cn_flags |= DOWHITEOUT;
1076 		unionfs_forward_vop_start_pair(udvp, &udvp_lkflags,
1077 		    uvp, &uvp_lkflags);
1078 		error = VOP_REMOVE(udvp, uvp, cnp);
1079 		unionfs_forward_vop_finish_pair(ap->a_dvp, udvp, udvp_lkflags,
1080 		    ap->a_vp, uvp, uvp_lkflags);
1081 	} else if (lvp != NULLVP)
1082 		error = unionfs_mkwhiteout(ap->a_dvp, udvp, cnp, td, path, pathlen);
1083 
1084 	UNIONFS_INTERNAL_DEBUG("unionfs_remove: leave (%d)\n", error);
1085 
1086 	return (error);
1087 }
1088 
1089 static int
1090 unionfs_link(struct vop_link_args *ap)
1091 {
1092 	struct unionfs_node *dunp;
1093 	struct unionfs_node *unp;
1094 	struct vnode   *udvp;
1095 	struct vnode   *uvp;
1096 	struct componentname *cnp;
1097 	struct thread  *td;
1098 	int		error;
1099 	int		needrelookup;
1100 
1101 	UNIONFS_INTERNAL_DEBUG("unionfs_link: enter\n");
1102 
1103 	KASSERT_UNIONFS_VNODE(ap->a_tdvp);
1104 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1105 
1106 	error = 0;
1107 	needrelookup = 0;
1108 	dunp = VTOUNIONFS(ap->a_tdvp);
1109 	unp = NULL;
1110 	udvp = dunp->un_uppervp;
1111 	uvp = NULLVP;
1112 	cnp = ap->a_cnp;
1113 	td = curthread;
1114 
1115 	if (udvp == NULLVP)
1116 		return (EROFS);
1117 
1118 	unp = VTOUNIONFS(ap->a_vp);
1119 
1120 	if (unp->un_uppervp == NULLVP) {
1121 		if (ap->a_vp->v_type != VREG)
1122 			return (EOPNOTSUPP);
1123 
1124 		error = unionfs_copyfile(unp, 1, cnp->cn_cred, td);
1125 		if (error != 0)
1126 			return (error);
1127 		needrelookup = 1;
1128 	}
1129 	uvp = unp->un_uppervp;
1130 
1131 	if (needrelookup != 0)
1132 		error = unionfs_relookup_for_create(ap->a_tdvp, cnp, td);
1133 
1134 	if (error == 0) {
1135 		int udvp_lkflags, uvp_lkflags;
1136 		unionfs_forward_vop_start_pair(udvp, &udvp_lkflags,
1137 		    uvp, &uvp_lkflags);
1138 		error = VOP_LINK(udvp, uvp, cnp);
1139 		unionfs_forward_vop_finish_pair(ap->a_tdvp, udvp, udvp_lkflags,
1140 		    ap->a_vp, uvp, uvp_lkflags);
1141 	}
1142 
1143 	UNIONFS_INTERNAL_DEBUG("unionfs_link: leave (%d)\n", error);
1144 
1145 	return (error);
1146 }
1147 
1148 static int
1149 unionfs_rename(struct vop_rename_args *ap)
1150 {
1151 	struct vnode   *fdvp;
1152 	struct vnode   *fvp;
1153 	struct componentname *fcnp;
1154 	struct vnode   *tdvp;
1155 	struct vnode   *tvp;
1156 	struct componentname *tcnp;
1157 	struct vnode   *ltdvp;
1158 	struct vnode   *ltvp;
1159 	struct thread  *td;
1160 
1161 	/* rename target vnodes */
1162 	struct vnode   *rfdvp;
1163 	struct vnode   *rfvp;
1164 	struct vnode   *rtdvp;
1165 	struct vnode   *rtvp;
1166 
1167 	struct unionfs_mount *ump;
1168 	struct unionfs_node *unp;
1169 	int		error;
1170 	int		needrelookup;
1171 
1172 	UNIONFS_INTERNAL_DEBUG("unionfs_rename: enter\n");
1173 
1174 	error = 0;
1175 	fdvp = ap->a_fdvp;
1176 	fvp = ap->a_fvp;
1177 	fcnp = ap->a_fcnp;
1178 	tdvp = ap->a_tdvp;
1179 	tvp = ap->a_tvp;
1180 	tcnp = ap->a_tcnp;
1181 	ltdvp = NULLVP;
1182 	ltvp = NULLVP;
1183 	td = curthread;
1184 	rfdvp = fdvp;
1185 	rfvp = fvp;
1186 	rtdvp = tdvp;
1187 	rtvp = tvp;
1188 	needrelookup = 0;
1189 
1190 	/* check for cross device rename */
1191 	if (fvp->v_mount != tdvp->v_mount ||
1192 	    (tvp != NULLVP && fvp->v_mount != tvp->v_mount)) {
1193 		if (fvp->v_op != &unionfs_vnodeops)
1194 			error = ENODEV;
1195 		else
1196 			error = EXDEV;
1197 		goto unionfs_rename_abort;
1198 	}
1199 
1200 	/* Renaming a file to itself has no effect. */
1201 	if (fvp == tvp)
1202 		goto unionfs_rename_abort;
1203 
1204 	/*
1205 	 * from/to vnode is unionfs node.
1206 	 */
1207 
1208 	KASSERT_UNIONFS_VNODE(fdvp);
1209 	KASSERT_UNIONFS_VNODE(fvp);
1210 	KASSERT_UNIONFS_VNODE(tdvp);
1211 	if (tvp != NULLVP)
1212 		KASSERT_UNIONFS_VNODE(tvp);
1213 
1214 	unp = VTOUNIONFS(fdvp);
1215 #ifdef UNIONFS_IDBG_RENAME
1216 	UNIONFS_INTERNAL_DEBUG("fdvp=%p, ufdvp=%p, lfdvp=%p\n",
1217 	    fdvp, unp->un_uppervp, unp->un_lowervp);
1218 #endif
1219 	if (unp->un_uppervp == NULLVP) {
1220 		error = ENODEV;
1221 		goto unionfs_rename_abort;
1222 	}
1223 	rfdvp = unp->un_uppervp;
1224 	vref(rfdvp);
1225 
1226 	unp = VTOUNIONFS(fvp);
1227 #ifdef UNIONFS_IDBG_RENAME
1228 	UNIONFS_INTERNAL_DEBUG("fvp=%p, ufvp=%p, lfvp=%p\n",
1229 	    fvp, unp->un_uppervp, unp->un_lowervp);
1230 #endif
1231 	ump = MOUNTTOUNIONFSMOUNT(fvp->v_mount);
1232 	if (unp->un_uppervp == NULLVP) {
1233 		switch (fvp->v_type) {
1234 		case VREG:
1235 			if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
1236 				goto unionfs_rename_abort;
1237 			error = unionfs_copyfile(unp, 1, fcnp->cn_cred, td);
1238 			VOP_UNLOCK(fvp);
1239 			if (error != 0)
1240 				goto unionfs_rename_abort;
1241 			break;
1242 		case VDIR:
1243 			if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
1244 				goto unionfs_rename_abort;
1245 			error = unionfs_mkshadowdir(ump, rfdvp, unp, fcnp, td);
1246 			VOP_UNLOCK(fvp);
1247 			if (error != 0)
1248 				goto unionfs_rename_abort;
1249 			break;
1250 		default:
1251 			error = ENODEV;
1252 			goto unionfs_rename_abort;
1253 		}
1254 
1255 		needrelookup = 1;
1256 	}
1257 
1258 	if (unp->un_lowervp != NULLVP)
1259 		fcnp->cn_flags |= DOWHITEOUT;
1260 	rfvp = unp->un_uppervp;
1261 	vref(rfvp);
1262 
1263 	unp = VTOUNIONFS(tdvp);
1264 #ifdef UNIONFS_IDBG_RENAME
1265 	UNIONFS_INTERNAL_DEBUG("tdvp=%p, utdvp=%p, ltdvp=%p\n",
1266 	    tdvp, unp->un_uppervp, unp->un_lowervp);
1267 #endif
1268 	if (unp->un_uppervp == NULLVP) {
1269 		error = ENODEV;
1270 		goto unionfs_rename_abort;
1271 	}
1272 	rtdvp = unp->un_uppervp;
1273 	ltdvp = unp->un_lowervp;
1274 	vref(rtdvp);
1275 
1276 	if (tdvp == tvp) {
1277 		rtvp = rtdvp;
1278 		vref(rtvp);
1279 	} else if (tvp != NULLVP) {
1280 		unp = VTOUNIONFS(tvp);
1281 #ifdef UNIONFS_IDBG_RENAME
1282 		UNIONFS_INTERNAL_DEBUG("tvp=%p, utvp=%p, ltvp=%p\n",
1283 		    tvp, unp->un_uppervp, unp->un_lowervp);
1284 #endif
1285 		if (unp->un_uppervp == NULLVP)
1286 			rtvp = NULLVP;
1287 		else {
1288 			if (tvp->v_type == VDIR) {
1289 				error = EINVAL;
1290 				goto unionfs_rename_abort;
1291 			}
1292 			rtvp = unp->un_uppervp;
1293 			ltvp = unp->un_lowervp;
1294 			vref(rtvp);
1295 		}
1296 	}
1297 
1298 	if (rfvp == rtvp)
1299 		goto unionfs_rename_abort;
1300 
1301 	if (needrelookup != 0) {
1302 		if ((error = vn_lock(fdvp, LK_EXCLUSIVE)) != 0)
1303 			goto unionfs_rename_abort;
1304 		error = unionfs_relookup_for_delete(fdvp, fcnp, td);
1305 		VOP_UNLOCK(fdvp);
1306 		if (error != 0)
1307 			goto unionfs_rename_abort;
1308 
1309 		/* Lock of tvp is canceled in order to avoid recursive lock. */
1310 		if (tvp != NULLVP && tvp != tdvp)
1311 			VOP_UNLOCK(tvp);
1312 		error = unionfs_relookup_for_rename(tdvp, tcnp, td);
1313 		if (tvp != NULLVP && tvp != tdvp)
1314 			vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY);
1315 		if (error != 0)
1316 			goto unionfs_rename_abort;
1317 	}
1318 
1319 	error = VOP_RENAME(rfdvp, rfvp, fcnp, rtdvp, rtvp, tcnp);
1320 
1321 	if (error == 0) {
1322 		if (rtvp != NULLVP && rtvp->v_type == VDIR)
1323 			cache_purge(tdvp);
1324 		if (fvp->v_type == VDIR && fdvp != tdvp)
1325 			cache_purge(fdvp);
1326 	}
1327 
1328 	if (ltdvp != NULLVP)
1329 		VOP_UNLOCK(ltdvp);
1330 	if (tdvp != rtdvp)
1331 		vrele(tdvp);
1332 	if (ltvp != NULLVP)
1333 		VOP_UNLOCK(ltvp);
1334 	if (tvp != rtvp && tvp != NULLVP) {
1335 		if (rtvp == NULLVP)
1336 			vput(tvp);
1337 		else
1338 			vrele(tvp);
1339 	}
1340 	if (fdvp != rfdvp)
1341 		vrele(fdvp);
1342 	if (fvp != rfvp)
1343 		vrele(fvp);
1344 
1345 	UNIONFS_INTERNAL_DEBUG("unionfs_rename: leave (%d)\n", error);
1346 
1347 	return (error);
1348 
1349 unionfs_rename_abort:
1350 	vput(tdvp);
1351 	if (tdvp != rtdvp)
1352 		vrele(rtdvp);
1353 	if (tvp != NULLVP) {
1354 		if (tdvp != tvp)
1355 			vput(tvp);
1356 		else
1357 			vrele(tvp);
1358 	}
1359 	if (tvp != rtvp && rtvp != NULLVP)
1360 		vrele(rtvp);
1361 	if (fdvp != rfdvp)
1362 		vrele(rfdvp);
1363 	if (fvp != rfvp)
1364 		vrele(rfvp);
1365 	vrele(fdvp);
1366 	vrele(fvp);
1367 
1368 	UNIONFS_INTERNAL_DEBUG("unionfs_rename: leave (%d)\n", error);
1369 
1370 	return (error);
1371 }
1372 
1373 static int
1374 unionfs_mkdir(struct vop_mkdir_args *ap)
1375 {
1376 	struct unionfs_node *dunp;
1377 	struct componentname *cnp;
1378 	struct vnode   *dvp;
1379 	struct vnode   *udvp;
1380 	struct vnode   *uvp;
1381 	struct vattr	va;
1382 	int		error;
1383 	int		lkflags;
1384 
1385 	UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: enter\n");
1386 
1387 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
1388 
1389 	error = EROFS;
1390 	dvp = ap->a_dvp;
1391 	dunp = VTOUNIONFS(dvp);
1392 	cnp = ap->a_cnp;
1393 	lkflags = cnp->cn_lkflags;
1394 	udvp = dunp->un_uppervp;
1395 
1396 	if (udvp != NULLVP) {
1397 		/* check opaque */
1398 		if (!(cnp->cn_flags & ISWHITEOUT)) {
1399 			error = VOP_GETATTR(udvp, &va, cnp->cn_cred);
1400 			if (error != 0)
1401 				goto unionfs_mkdir_cleanup;
1402 			if ((va.va_flags & OPAQUE) != 0)
1403 				cnp->cn_flags |= ISWHITEOUT;
1404 		}
1405 
1406 		int udvp_lkflags;
1407 		bool uvp_created = false;
1408 		unionfs_forward_vop_start(udvp, &udvp_lkflags);
1409 		error = VOP_MKDIR(udvp, &uvp, cnp, ap->a_vap);
1410 		if (error == 0)
1411 			uvp_created = true;
1412 		if (__predict_false(unionfs_forward_vop_finish(dvp, udvp,
1413 		    udvp_lkflags)) && error == 0)
1414 			error = ENOENT;
1415 		if (error == 0) {
1416 			VOP_UNLOCK(uvp);
1417 			cnp->cn_lkflags = LK_EXCLUSIVE;
1418 			error = unionfs_nodeget(dvp->v_mount, uvp, NULLVP,
1419 			    dvp, ap->a_vpp, cnp);
1420 			vrele(uvp);
1421 			cnp->cn_lkflags = lkflags;
1422 		} else if (uvp_created)
1423 			vput(uvp);
1424 	}
1425 
1426 unionfs_mkdir_cleanup:
1427 	UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: leave (%d)\n", error);
1428 
1429 	return (error);
1430 }
1431 
1432 static int
1433 unionfs_rmdir(struct vop_rmdir_args *ap)
1434 {
1435 	struct unionfs_node *dunp;
1436 	struct unionfs_node *unp;
1437 	struct unionfs_mount *ump;
1438 	struct componentname *cnp;
1439 	struct thread  *td;
1440 	struct vnode   *udvp;
1441 	struct vnode   *uvp;
1442 	struct vnode   *lvp;
1443 	int		error;
1444 
1445 	UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: enter\n");
1446 
1447 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
1448 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1449 
1450 	error = 0;
1451 	dunp = VTOUNIONFS(ap->a_dvp);
1452 	unp = VTOUNIONFS(ap->a_vp);
1453 	cnp = ap->a_cnp;
1454 	td = curthread;
1455 	udvp = dunp->un_uppervp;
1456 	uvp = unp->un_uppervp;
1457 	lvp = unp->un_lowervp;
1458 
1459 	if (udvp == NULLVP)
1460 		return (EROFS);
1461 
1462 	if (udvp == uvp)
1463 		return (EOPNOTSUPP);
1464 
1465 	if (uvp != NULLVP) {
1466 		if (lvp != NULLVP) {
1467 			error = unionfs_check_rmdir(ap->a_vp, cnp->cn_cred, td);
1468 			if (error != 0)
1469 				return (error);
1470 		}
1471 		ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
1472 		if (ump->um_whitemode == UNIONFS_WHITE_ALWAYS || lvp != NULLVP)
1473 			cnp->cn_flags |= DOWHITEOUT;
1474 		/*
1475 		 * The relookup path will need to relock the parent dvp and
1476 		 * possibly the vp as well.  Locking is expected to be done
1477 		 * in parent->child order; drop the lock on vp to avoid LOR
1478 		 * and potential recursion on vp's lock.
1479 		 * vp is expected to remain referenced during VOP_RMDIR(),
1480 		 * so vref/vrele should not be necessary here.
1481 		 */
1482 		VOP_UNLOCK(ap->a_vp);
1483 		VNPASS(vrefcnt(ap->a_vp) > 0, ap->a_vp);
1484 		error = unionfs_relookup_for_delete(ap->a_dvp, cnp, td);
1485 		vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1486 		/*
1487 		 * VOP_RMDIR is dispatched against udvp, so if uvp became
1488 		 * doomed while the lock was dropped above the target
1489 		 * filesystem may not be able to cope.
1490 		 */
1491 		if (error == 0 && VN_IS_DOOMED(uvp))
1492 			error = ENOENT;
1493 		if (error == 0) {
1494 			int udvp_lkflags, uvp_lkflags;
1495 			unionfs_forward_vop_start_pair(udvp, &udvp_lkflags,
1496 			    uvp, &uvp_lkflags);
1497 			error = VOP_RMDIR(udvp, uvp, cnp);
1498 			unionfs_forward_vop_finish_pair(ap->a_dvp, udvp, udvp_lkflags,
1499 			    ap->a_vp, uvp, uvp_lkflags);
1500 		}
1501 	} else if (lvp != NULLVP)
1502 		error = unionfs_mkwhiteout(ap->a_dvp, udvp, cnp, td,
1503 		    unp->un_path, unp->un_pathlen);
1504 
1505 	if (error == 0) {
1506 		cache_purge(ap->a_dvp);
1507 		cache_purge(ap->a_vp);
1508 	}
1509 
1510 	UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: leave (%d)\n", error);
1511 
1512 	return (error);
1513 }
1514 
1515 static int
1516 unionfs_symlink(struct vop_symlink_args *ap)
1517 {
1518 	struct unionfs_node *dunp;
1519 	struct componentname *cnp;
1520 	struct vnode   *udvp;
1521 	struct vnode   *uvp;
1522 	int		error;
1523 	int		lkflags;
1524 
1525 	UNIONFS_INTERNAL_DEBUG("unionfs_symlink: enter\n");
1526 
1527 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
1528 
1529 	error = EROFS;
1530 	dunp = VTOUNIONFS(ap->a_dvp);
1531 	cnp = ap->a_cnp;
1532 	lkflags = cnp->cn_lkflags;
1533 	udvp = dunp->un_uppervp;
1534 
1535 	if (udvp != NULLVP) {
1536 		int udvp_lkflags;
1537 		bool uvp_created = false;
1538 		unionfs_forward_vop_start(udvp, &udvp_lkflags);
1539 		error = VOP_SYMLINK(udvp, &uvp, cnp, ap->a_vap, ap->a_target);
1540 		if (error == 0)
1541 			uvp_created = true;
1542 		if (__predict_false(unionfs_forward_vop_finish(ap->a_dvp, udvp,
1543 		    udvp_lkflags)) && error == 0)
1544 			error = ENOENT;
1545 		if (error == 0) {
1546 			VOP_UNLOCK(uvp);
1547 			cnp->cn_lkflags = LK_EXCLUSIVE;
1548 			error = unionfs_nodeget(ap->a_dvp->v_mount, uvp, NULLVP,
1549 			    ap->a_dvp, ap->a_vpp, cnp);
1550 			vrele(uvp);
1551 			cnp->cn_lkflags = lkflags;
1552 		} else if (uvp_created)
1553 			vput(uvp);
1554 	}
1555 
1556 	UNIONFS_INTERNAL_DEBUG("unionfs_symlink: leave (%d)\n", error);
1557 
1558 	return (error);
1559 }
1560 
1561 static int
1562 unionfs_readdir(struct vop_readdir_args *ap)
1563 {
1564 	struct unionfs_node *unp;
1565 	struct unionfs_node_status *unsp;
1566 	struct uio     *uio;
1567 	struct vnode   *vp;
1568 	struct vnode   *uvp;
1569 	struct vnode   *lvp;
1570 	struct thread  *td;
1571 	struct vattr    va;
1572 
1573 	uint64_t	*cookies_bk;
1574 	int		error;
1575 	int		eofflag;
1576 	int		ncookies_bk;
1577 	int		uio_offset_bk;
1578 	enum unionfs_lkupgrade lkstatus;
1579 
1580 	UNIONFS_INTERNAL_DEBUG("unionfs_readdir: enter\n");
1581 
1582 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1583 
1584 	error = 0;
1585 	eofflag = 0;
1586 	uio_offset_bk = 0;
1587 	uio = ap->a_uio;
1588 	uvp = NULLVP;
1589 	lvp = NULLVP;
1590 	td = uio->uio_td;
1591 	ncookies_bk = 0;
1592 	cookies_bk = NULL;
1593 
1594 	vp = ap->a_vp;
1595 	if (vp->v_type != VDIR)
1596 		return (ENOTDIR);
1597 
1598 	/*
1599 	 * If the vnode is reclaimed while upgrading, we can't safely use unp
1600 	 * or do anything else unionfs- specific.
1601 	 */
1602 	lkstatus = unionfs_upgrade_lock(vp);
1603 	if (lkstatus == UNIONFS_LKUPGRADE_DOOMED)
1604 		error = EBADF;
1605 	if (error == 0) {
1606 		unp = VTOUNIONFS(vp);
1607 		uvp = unp->un_uppervp;
1608 		lvp = unp->un_lowervp;
1609 		/* check the open count. unionfs needs open before readdir. */
1610 		unionfs_get_node_status(unp, td, &unsp);
1611 		if ((uvp != NULLVP && unsp->uns_upper_opencnt <= 0) ||
1612 			(lvp != NULLVP && unsp->uns_lower_opencnt <= 0)) {
1613 			unionfs_tryrem_node_status(unp, unsp);
1614 			error = EBADF;
1615 		}
1616 	}
1617 	unionfs_downgrade_lock(vp, lkstatus);
1618 	if (error != 0)
1619 		goto unionfs_readdir_exit;
1620 
1621 	/* check opaque */
1622 	if (uvp != NULLVP && lvp != NULLVP) {
1623 		if ((error = VOP_GETATTR(uvp, &va, ap->a_cred)) != 0)
1624 			goto unionfs_readdir_exit;
1625 		if (va.va_flags & OPAQUE)
1626 			lvp = NULLVP;
1627 	}
1628 
1629 	/* upper only */
1630 	if (uvp != NULLVP && lvp == NULLVP) {
1631 		error = VOP_READDIR(uvp, uio, ap->a_cred, ap->a_eofflag,
1632 		    ap->a_ncookies, ap->a_cookies);
1633 		unsp->uns_readdir_status = 0;
1634 
1635 		goto unionfs_readdir_exit;
1636 	}
1637 
1638 	/* lower only */
1639 	if (uvp == NULLVP && lvp != NULLVP) {
1640 		error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag,
1641 		    ap->a_ncookies, ap->a_cookies);
1642 		unsp->uns_readdir_status = 2;
1643 
1644 		goto unionfs_readdir_exit;
1645 	}
1646 
1647 	/*
1648 	 * readdir upper and lower
1649 	 */
1650 	KASSERT(uvp != NULLVP, ("unionfs_readdir: null upper vp"));
1651 	KASSERT(lvp != NULLVP, ("unionfs_readdir: null lower vp"));
1652 	if (uio->uio_offset == 0)
1653 		unsp->uns_readdir_status = 0;
1654 
1655 	if (unsp->uns_readdir_status == 0) {
1656 		/* read upper */
1657 		error = VOP_READDIR(uvp, uio, ap->a_cred, &eofflag,
1658 				    ap->a_ncookies, ap->a_cookies);
1659 
1660 		if (error != 0 || eofflag == 0)
1661 			goto unionfs_readdir_exit;
1662 		unsp->uns_readdir_status = 1;
1663 
1664 		/*
1665 		 * UFS(and other FS) needs size of uio_resid larger than
1666 		 * DIRBLKSIZ.
1667 		 * size of DIRBLKSIZ equals DEV_BSIZE.
1668 		 * (see: ufs/ufs/ufs_vnops.c ufs_readdir func , ufs/ufs/dir.h)
1669 		 */
1670 		if (uio->uio_resid <= (uio->uio_resid & (DEV_BSIZE -1)))
1671 			goto unionfs_readdir_exit;
1672 
1673 		/*
1674 		 * Backup cookies.
1675 		 * It prepares to readdir in lower.
1676 		 */
1677 		if (ap->a_ncookies != NULL) {
1678 			ncookies_bk = *(ap->a_ncookies);
1679 			*(ap->a_ncookies) = 0;
1680 		}
1681 		if (ap->a_cookies != NULL) {
1682 			cookies_bk = *(ap->a_cookies);
1683 			*(ap->a_cookies) = NULL;
1684 		}
1685 	}
1686 
1687 	/* initialize for readdir in lower */
1688 	if (unsp->uns_readdir_status == 1) {
1689 		unsp->uns_readdir_status = 2;
1690 		/*
1691 		 * Backup uio_offset. See the comment after the
1692 		 * VOP_READDIR call on the lower layer.
1693 		 */
1694 		uio_offset_bk = uio->uio_offset;
1695 		uio->uio_offset = 0;
1696 	}
1697 
1698 	if (lvp == NULLVP) {
1699 		error = EBADF;
1700 		goto unionfs_readdir_exit;
1701 	}
1702 	/* read lower */
1703 	error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag,
1704 			    ap->a_ncookies, ap->a_cookies);
1705 
1706 	/*
1707 	 * We can't return an uio_offset of 0: this would trigger an
1708 	 * infinite loop, because the next call to unionfs_readdir would
1709 	 * always restart with the upper layer (uio_offset == 0) and
1710 	 * always return some data.
1711 	 *
1712 	 * This happens when the lower layer root directory is removed.
1713 	 * (A root directory deleting of unionfs should not be permitted.
1714 	 *  But current VFS can not do it.)
1715 	 */
1716 	if (uio->uio_offset == 0)
1717 		uio->uio_offset = uio_offset_bk;
1718 
1719 	if (cookies_bk != NULL) {
1720 		/* merge cookies */
1721 		int		size;
1722 		uint64_t         *newcookies, *pos;
1723 
1724 		size = *(ap->a_ncookies) + ncookies_bk;
1725 		newcookies = (uint64_t *) malloc(size * sizeof(*newcookies),
1726 		    M_TEMP, M_WAITOK);
1727 		pos = newcookies;
1728 
1729 		memcpy(pos, cookies_bk, ncookies_bk * sizeof(*newcookies));
1730 		pos += ncookies_bk;
1731 		memcpy(pos, *(ap->a_cookies),
1732 		    *(ap->a_ncookies) * sizeof(*newcookies));
1733 		free(cookies_bk, M_TEMP);
1734 		free(*(ap->a_cookies), M_TEMP);
1735 		*(ap->a_ncookies) = size;
1736 		*(ap->a_cookies) = newcookies;
1737 	}
1738 
1739 unionfs_readdir_exit:
1740 	if (error != 0 && ap->a_eofflag != NULL)
1741 		*(ap->a_eofflag) = 1;
1742 
1743 	UNIONFS_INTERNAL_DEBUG("unionfs_readdir: leave (%d)\n", error);
1744 
1745 	return (error);
1746 }
1747 
1748 static int
1749 unionfs_readlink(struct vop_readlink_args *ap)
1750 {
1751 	struct unionfs_node *unp;
1752 	struct vnode   *vp;
1753 	int error;
1754 
1755 	UNIONFS_INTERNAL_DEBUG("unionfs_readlink: enter\n");
1756 
1757 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1758 
1759 	unp = VTOUNIONFS(ap->a_vp);
1760 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
1761 
1762 	error = VOP_READLINK(vp, ap->a_uio, ap->a_cred);
1763 
1764 	UNIONFS_INTERNAL_DEBUG("unionfs_readlink: leave (%d)\n", error);
1765 
1766 	return (error);
1767 }
1768 
1769 static int
1770 unionfs_getwritemount(struct vop_getwritemount_args *ap)
1771 {
1772 	struct unionfs_node *unp;
1773 	struct vnode   *uvp;
1774 	struct vnode   *vp, *ovp;
1775 	int		error;
1776 
1777 	UNIONFS_INTERNAL_DEBUG("unionfs_getwritemount: enter\n");
1778 
1779 	error = 0;
1780 	vp = ap->a_vp;
1781 	uvp = NULLVP;
1782 
1783 	VI_LOCK(vp);
1784 	unp = VTOUNIONFS(vp);
1785 	if (unp != NULL)
1786 		uvp = unp->un_uppervp;
1787 
1788 	/*
1789 	 * If our node has no upper vnode, check the parent directory.
1790 	 * We may be initiating a write operation that will produce a
1791 	 * new upper vnode through CoW.
1792 	 */
1793 	if (uvp == NULLVP && unp != NULL) {
1794 		ovp = vp;
1795 		vp = unp->un_dvp;
1796 		/*
1797 		 * Only the root vnode should have an empty parent, but it
1798 		 * should not have an empty uppervp, so we shouldn't get here.
1799 		 */
1800 		VNASSERT(vp != NULL, ovp, ("%s: NULL parent vnode", __func__));
1801 		VI_UNLOCK(ovp);
1802 		VI_LOCK(vp);
1803 		unp = VTOUNIONFS(vp);
1804 		if (unp != NULL)
1805 			uvp = unp->un_uppervp;
1806 		if (uvp == NULLVP)
1807 			error = EACCES;
1808 	}
1809 
1810 	if (uvp != NULLVP) {
1811 		vholdnz(uvp);
1812 		VI_UNLOCK(vp);
1813 		error = VOP_GETWRITEMOUNT(uvp, ap->a_mpp);
1814 		vdrop(uvp);
1815 	} else {
1816 		VI_UNLOCK(vp);
1817 		*(ap->a_mpp) = NULL;
1818 	}
1819 
1820 	UNIONFS_INTERNAL_DEBUG("unionfs_getwritemount: leave (%d)\n", error);
1821 
1822 	return (error);
1823 }
1824 
1825 static int
1826 unionfs_inactive(struct vop_inactive_args *ap)
1827 {
1828 	ap->a_vp->v_object = NULL;
1829 	vrecycle(ap->a_vp);
1830 	return (0);
1831 }
1832 
1833 static int
1834 unionfs_reclaim(struct vop_reclaim_args *ap)
1835 {
1836 	/* UNIONFS_INTERNAL_DEBUG("unionfs_reclaim: enter\n"); */
1837 
1838 	unionfs_noderem(ap->a_vp);
1839 
1840 	/* UNIONFS_INTERNAL_DEBUG("unionfs_reclaim: leave\n"); */
1841 
1842 	return (0);
1843 }
1844 
1845 static int
1846 unionfs_print(struct vop_print_args *ap)
1847 {
1848 	struct unionfs_node *unp;
1849 	/* struct unionfs_node_status *unsp; */
1850 
1851 	unp = VTOUNIONFS(ap->a_vp);
1852 	/* unionfs_get_node_status(unp, curthread, &unsp); */
1853 
1854 	printf("unionfs_vp=%p, uppervp=%p, lowervp=%p\n",
1855 	    ap->a_vp, unp->un_uppervp, unp->un_lowervp);
1856 	/*
1857 	printf("unionfs opencnt: uppervp=%d, lowervp=%d\n",
1858 	    unsp->uns_upper_opencnt, unsp->uns_lower_opencnt);
1859 	*/
1860 
1861 	if (unp->un_uppervp != NULLVP)
1862 		vn_printf(unp->un_uppervp, "unionfs: upper ");
1863 	if (unp->un_lowervp != NULLVP)
1864 		vn_printf(unp->un_lowervp, "unionfs: lower ");
1865 
1866 	return (0);
1867 }
1868 
1869 static int
1870 unionfs_get_llt_revlock(struct vnode *vp, int flags)
1871 {
1872 	int revlock;
1873 
1874 	revlock = 0;
1875 
1876 	switch (flags & LK_TYPE_MASK) {
1877 	case LK_SHARED:
1878 		if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE)
1879 			revlock = LK_UPGRADE;
1880 		else
1881 			revlock = LK_RELEASE;
1882 		break;
1883 	case LK_EXCLUSIVE:
1884 	case LK_UPGRADE:
1885 		revlock = LK_RELEASE;
1886 		break;
1887 	case LK_DOWNGRADE:
1888 		revlock = LK_UPGRADE;
1889 		break;
1890 	default:
1891 		break;
1892 	}
1893 
1894 	return (revlock);
1895 }
1896 
1897 /*
1898  * The state of an acquired lock is adjusted similarly to
1899  * the time of error generating.
1900  * flags: LK_RELEASE or LK_UPGRADE
1901  */
1902 static void
1903 unionfs_revlock(struct vnode *vp, int flags)
1904 {
1905 	if (flags & LK_RELEASE)
1906 		VOP_UNLOCK_FLAGS(vp, flags);
1907 	else {
1908 		/* UPGRADE */
1909 		if (vn_lock(vp, flags) != 0)
1910 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1911 	}
1912 }
1913 
1914 static int
1915 unionfs_lock(struct vop_lock1_args *ap)
1916 {
1917 	struct unionfs_node *unp;
1918 	struct vnode   *vp;
1919 	struct vnode   *uvp;
1920 	struct vnode   *lvp;
1921 	int		error;
1922 	int		flags;
1923 	int		revlock;
1924 	int		interlock;
1925 	int		uhold;
1926 
1927 	/*
1928 	 * TODO: rework the unionfs locking scheme.
1929 	 * It's not guaranteed to be safe to blindly lock two vnodes on
1930 	 * different mounts as is done here.  Further, the entanglement
1931 	 * of locking both vnodes with the various options that can be
1932 	 * passed to VOP_LOCK() makes this code hard to reason about.
1933 	 * Instead, consider locking only the upper vnode, or the lower
1934 	 * vnode is the upper is not present, and taking separate measures
1935 	 * to lock both vnodes in the few cases when that is needed.
1936 	 */
1937 	error = 0;
1938 	interlock = 1;
1939 	uhold = 0;
1940 	flags = ap->a_flags;
1941 	vp = ap->a_vp;
1942 
1943 	if (LK_RELEASE == (flags & LK_TYPE_MASK) || !(flags & LK_TYPE_MASK))
1944 		return (VOP_UNLOCK_FLAGS(vp, flags | LK_RELEASE));
1945 
1946 	if ((flags & LK_INTERLOCK) == 0)
1947 		VI_LOCK(vp);
1948 
1949 	unp = VTOUNIONFS(vp);
1950 	if (unp == NULL)
1951 		goto unionfs_lock_null_vnode;
1952 
1953 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1954 
1955 	lvp = unp->un_lowervp;
1956 	uvp = unp->un_uppervp;
1957 
1958 	if ((revlock = unionfs_get_llt_revlock(vp, flags)) == 0)
1959 		panic("unknown lock type: 0x%x", flags & LK_TYPE_MASK);
1960 
1961 	/*
1962 	 * During unmount, the root vnode lock may be taken recursively,
1963 	 * because it may share the same v_vnlock field as the vnode covered by
1964 	 * the unionfs mount.  The covered vnode is locked across VFS_UNMOUNT(),
1965 	 * and the same lock may be taken recursively here during vflush()
1966 	 * issued by unionfs_unmount().
1967 	 */
1968 	if ((flags & LK_TYPE_MASK) == LK_EXCLUSIVE &&
1969 	    (vp->v_vflag & VV_ROOT) != 0)
1970 		flags |= LK_CANRECURSE;
1971 
1972 	if (lvp != NULLVP) {
1973 		if (uvp != NULLVP && flags & LK_UPGRADE) {
1974 			/*
1975 			 * Share Lock is once released and a deadlock is
1976 			 * avoided.
1977 			 */
1978 			vholdnz(uvp);
1979 			uhold = 1;
1980 			VOP_UNLOCK(uvp);
1981 		}
1982 		VI_LOCK_FLAGS(lvp, MTX_DUPOK);
1983 		flags |= LK_INTERLOCK;
1984 		vholdl(lvp);
1985 
1986 		VI_UNLOCK(vp);
1987 		ap->a_flags &= ~LK_INTERLOCK;
1988 
1989 		error = VOP_LOCK(lvp, flags);
1990 
1991 		VI_LOCK(vp);
1992 		unp = VTOUNIONFS(vp);
1993 		if (unp == NULL) {
1994 			/* vnode is released. */
1995 			VI_UNLOCK(vp);
1996 			if (error == 0)
1997 				VOP_UNLOCK(lvp);
1998 			vdrop(lvp);
1999 			if (uhold != 0)
2000 				vdrop(uvp);
2001 			goto unionfs_lock_fallback;
2002 		}
2003 	}
2004 
2005 	if (error == 0 && uvp != NULLVP) {
2006 		if (uhold && flags & LK_UPGRADE) {
2007 			flags &= ~LK_TYPE_MASK;
2008 			flags |= LK_EXCLUSIVE;
2009 		}
2010 		VI_LOCK_FLAGS(uvp, MTX_DUPOK);
2011 		flags |= LK_INTERLOCK;
2012 		if (uhold == 0) {
2013 			vholdl(uvp);
2014 			uhold = 1;
2015 		}
2016 
2017 		VI_UNLOCK(vp);
2018 		ap->a_flags &= ~LK_INTERLOCK;
2019 
2020 		error = VOP_LOCK(uvp, flags);
2021 
2022 		VI_LOCK(vp);
2023 		unp = VTOUNIONFS(vp);
2024 		if (unp == NULL) {
2025 			/* vnode is released. */
2026 			VI_UNLOCK(vp);
2027 			if (error == 0)
2028 				VOP_UNLOCK(uvp);
2029 			vdrop(uvp);
2030 			if (lvp != NULLVP) {
2031 				VOP_UNLOCK(lvp);
2032 				vdrop(lvp);
2033 			}
2034 			goto unionfs_lock_fallback;
2035 		}
2036 		if (error != 0 && lvp != NULLVP) {
2037 			/* rollback */
2038 			VI_UNLOCK(vp);
2039 			unionfs_revlock(lvp, revlock);
2040 			interlock = 0;
2041 		}
2042 	}
2043 
2044 	if (interlock)
2045 		VI_UNLOCK(vp);
2046 	if (lvp != NULLVP)
2047 		vdrop(lvp);
2048 	if (uhold != 0)
2049 		vdrop(uvp);
2050 
2051 	return (error);
2052 
2053 unionfs_lock_null_vnode:
2054 	ap->a_flags |= LK_INTERLOCK;
2055 	return (vop_stdlock(ap));
2056 
2057 unionfs_lock_fallback:
2058 	/*
2059 	 * If we reach this point, we've discovered the unionfs vnode
2060 	 * has been reclaimed while the upper/lower vnode locks were
2061 	 * temporarily dropped.  Such temporary droppage may happen
2062 	 * during the course of an LK_UPGRADE operation itself, and in
2063 	 * that case LK_UPGRADE must be cleared as the unionfs vnode's
2064 	 * lock has been reset to point to the standard v_lock field,
2065 	 * which has not previously been held.
2066 	 */
2067 	if (flags & LK_UPGRADE) {
2068 		ap->a_flags &= ~LK_TYPE_MASK;
2069 		ap->a_flags |= LK_EXCLUSIVE;
2070 	}
2071 	return (vop_stdlock(ap));
2072 }
2073 
2074 static int
2075 unionfs_unlock(struct vop_unlock_args *ap)
2076 {
2077 	struct vnode   *vp;
2078 	struct vnode   *lvp;
2079 	struct vnode   *uvp;
2080 	struct unionfs_node *unp;
2081 	int		error;
2082 	int		uhold;
2083 
2084 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2085 
2086 	error = 0;
2087 	uhold = 0;
2088 	vp = ap->a_vp;
2089 
2090 	unp = VTOUNIONFS(vp);
2091 	if (unp == NULL)
2092 		goto unionfs_unlock_null_vnode;
2093 	lvp = unp->un_lowervp;
2094 	uvp = unp->un_uppervp;
2095 
2096 	if (lvp != NULLVP) {
2097 		vholdnz(lvp);
2098 		error = VOP_UNLOCK(lvp);
2099 	}
2100 
2101 	if (error == 0 && uvp != NULLVP) {
2102 		vholdnz(uvp);
2103 		uhold = 1;
2104 		error = VOP_UNLOCK(uvp);
2105 	}
2106 
2107 	if (lvp != NULLVP)
2108 		vdrop(lvp);
2109 	if (uhold != 0)
2110 		vdrop(uvp);
2111 
2112 	return error;
2113 
2114 unionfs_unlock_null_vnode:
2115 	return (vop_stdunlock(ap));
2116 }
2117 
2118 static int
2119 unionfs_pathconf(struct vop_pathconf_args *ap)
2120 {
2121 	struct unionfs_node *unp;
2122 	struct vnode   *vp;
2123 
2124 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2125 
2126 	unp = VTOUNIONFS(ap->a_vp);
2127 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2128 
2129 	return (VOP_PATHCONF(vp, ap->a_name, ap->a_retval));
2130 }
2131 
2132 static int
2133 unionfs_advlock(struct vop_advlock_args *ap)
2134 {
2135 	struct unionfs_node *unp;
2136 	struct unionfs_node_status *unsp;
2137 	struct vnode   *vp;
2138 	struct vnode   *uvp;
2139 	struct thread  *td;
2140 	int error;
2141 
2142 	UNIONFS_INTERNAL_DEBUG("unionfs_advlock: enter\n");
2143 
2144 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2145 
2146 	vp = ap->a_vp;
2147 	td = curthread;
2148 
2149 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2150 
2151 	unp = VTOUNIONFS(ap->a_vp);
2152 	uvp = unp->un_uppervp;
2153 
2154 	if (uvp == NULLVP) {
2155 		error = unionfs_copyfile(unp, 1, td->td_ucred, td);
2156 		if (error != 0)
2157 			goto unionfs_advlock_abort;
2158 		uvp = unp->un_uppervp;
2159 
2160 		unionfs_get_node_status(unp, td, &unsp);
2161 		if (unsp->uns_lower_opencnt > 0) {
2162 			/* try reopen the vnode */
2163 			error = VOP_OPEN(uvp, unsp->uns_lower_openmode,
2164 				td->td_ucred, td, NULL);
2165 			if (error)
2166 				goto unionfs_advlock_abort;
2167 			unsp->uns_upper_opencnt++;
2168 			VOP_CLOSE(unp->un_lowervp, unsp->uns_lower_openmode,
2169 			    td->td_ucred, td);
2170 			unsp->uns_lower_opencnt--;
2171 		} else
2172 			unionfs_tryrem_node_status(unp, unsp);
2173 	}
2174 
2175 	VOP_UNLOCK(vp);
2176 
2177 	error = VOP_ADVLOCK(uvp, ap->a_id, ap->a_op, ap->a_fl, ap->a_flags);
2178 
2179 	UNIONFS_INTERNAL_DEBUG("unionfs_advlock: leave (%d)\n", error);
2180 
2181 	return error;
2182 
2183 unionfs_advlock_abort:
2184 	VOP_UNLOCK(vp);
2185 
2186 	UNIONFS_INTERNAL_DEBUG("unionfs_advlock: leave (%d)\n", error);
2187 
2188 	return error;
2189 }
2190 
2191 static int
2192 unionfs_strategy(struct vop_strategy_args *ap)
2193 {
2194 	struct unionfs_node *unp;
2195 	struct vnode   *vp;
2196 
2197 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2198 
2199 	unp = VTOUNIONFS(ap->a_vp);
2200 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2201 
2202 #ifdef DIAGNOSTIC
2203 	if (vp == NULLVP)
2204 		panic("unionfs_strategy: nullvp");
2205 
2206 	if (ap->a_bp->b_iocmd == BIO_WRITE && vp == unp->un_lowervp)
2207 		panic("unionfs_strategy: writing to lowervp");
2208 #endif
2209 
2210 	return (VOP_STRATEGY(vp, ap->a_bp));
2211 }
2212 
2213 static int
2214 unionfs_getacl(struct vop_getacl_args *ap)
2215 {
2216 	struct unionfs_node *unp;
2217 	struct vnode   *vp;
2218 	int		error;
2219 
2220 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2221 
2222 	unp = VTOUNIONFS(ap->a_vp);
2223 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2224 
2225 	UNIONFS_INTERNAL_DEBUG("unionfs_getacl: enter\n");
2226 
2227 	error = VOP_GETACL(vp, ap->a_type, ap->a_aclp, ap->a_cred, ap->a_td);
2228 
2229 	UNIONFS_INTERNAL_DEBUG("unionfs_getacl: leave (%d)\n", error);
2230 
2231 	return (error);
2232 }
2233 
2234 static int
2235 unionfs_setacl(struct vop_setacl_args *ap)
2236 {
2237 	struct unionfs_node *unp;
2238 	struct vnode   *uvp;
2239 	struct vnode   *lvp;
2240 	struct thread  *td;
2241 	int		error;
2242 
2243 	UNIONFS_INTERNAL_DEBUG("unionfs_setacl: enter\n");
2244 
2245 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2246 
2247 	error = EROFS;
2248 	unp = VTOUNIONFS(ap->a_vp);
2249 	uvp = unp->un_uppervp;
2250 	lvp = unp->un_lowervp;
2251 	td = ap->a_td;
2252 
2253 	if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
2254 		return (EROFS);
2255 
2256 	if (uvp == NULLVP && lvp->v_type == VREG) {
2257 		if ((error = unionfs_copyfile(unp, 1, ap->a_cred, td)) != 0)
2258 			return (error);
2259 		uvp = unp->un_uppervp;
2260 	}
2261 
2262 	if (uvp != NULLVP) {
2263 		int lkflags;
2264 		unionfs_forward_vop_start(uvp, &lkflags);
2265 		error = VOP_SETACL(uvp, ap->a_type, ap->a_aclp, ap->a_cred, td);
2266 		unionfs_forward_vop_finish(ap->a_vp, uvp, lkflags);
2267 	}
2268 
2269 	UNIONFS_INTERNAL_DEBUG("unionfs_setacl: leave (%d)\n", error);
2270 
2271 	return (error);
2272 }
2273 
2274 static int
2275 unionfs_aclcheck(struct vop_aclcheck_args *ap)
2276 {
2277 	struct unionfs_node *unp;
2278 	struct vnode   *vp;
2279 	int		error;
2280 
2281 	UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: enter\n");
2282 
2283 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2284 
2285 	unp = VTOUNIONFS(ap->a_vp);
2286 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2287 
2288 	error = VOP_ACLCHECK(vp, ap->a_type, ap->a_aclp, ap->a_cred, ap->a_td);
2289 
2290 	UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: leave (%d)\n", error);
2291 
2292 	return (error);
2293 }
2294 
2295 static int
2296 unionfs_openextattr(struct vop_openextattr_args *ap)
2297 {
2298 	struct unionfs_node *unp;
2299 	struct vnode   *vp;
2300 	struct vnode   *tvp;
2301 	int		error;
2302 
2303 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2304 
2305 	vp = ap->a_vp;
2306 	unp = VTOUNIONFS(vp);
2307 	tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2308 
2309 	if ((tvp == unp->un_uppervp && (unp->un_flag & UNIONFS_OPENEXTU)) ||
2310 	    (tvp == unp->un_lowervp && (unp->un_flag & UNIONFS_OPENEXTL)))
2311 		return (EBUSY);
2312 
2313 	error = VOP_OPENEXTATTR(tvp, ap->a_cred, ap->a_td);
2314 
2315 	if (error == 0) {
2316 		if (vn_lock(vp, LK_UPGRADE) != 0)
2317 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2318 		if (!VN_IS_DOOMED(vp)) {
2319 			if (tvp == unp->un_uppervp)
2320 				unp->un_flag |= UNIONFS_OPENEXTU;
2321 			else
2322 				unp->un_flag |= UNIONFS_OPENEXTL;
2323 		}
2324 		vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
2325 	}
2326 
2327 	return (error);
2328 }
2329 
2330 static int
2331 unionfs_closeextattr(struct vop_closeextattr_args *ap)
2332 {
2333 	struct unionfs_node *unp;
2334 	struct vnode   *vp;
2335 	struct vnode   *tvp;
2336 	int		error;
2337 
2338 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2339 
2340 	vp = ap->a_vp;
2341 	unp = VTOUNIONFS(vp);
2342 	tvp = NULLVP;
2343 
2344 	if (unp->un_flag & UNIONFS_OPENEXTU)
2345 		tvp = unp->un_uppervp;
2346 	else if (unp->un_flag & UNIONFS_OPENEXTL)
2347 		tvp = unp->un_lowervp;
2348 
2349 	if (tvp == NULLVP)
2350 		return (EOPNOTSUPP);
2351 
2352 	error = VOP_CLOSEEXTATTR(tvp, ap->a_commit, ap->a_cred, ap->a_td);
2353 
2354 	if (error == 0) {
2355 		if (vn_lock(vp, LK_UPGRADE) != 0)
2356 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2357 		if (!VN_IS_DOOMED(vp)) {
2358 			if (tvp == unp->un_uppervp)
2359 				unp->un_flag &= ~UNIONFS_OPENEXTU;
2360 			else
2361 				unp->un_flag &= ~UNIONFS_OPENEXTL;
2362 		}
2363 		vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
2364 	}
2365 
2366 	return (error);
2367 }
2368 
2369 static int
2370 unionfs_getextattr(struct vop_getextattr_args *ap)
2371 {
2372 	struct unionfs_node *unp;
2373 	struct vnode   *vp;
2374 
2375 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2376 
2377 	unp = VTOUNIONFS(ap->a_vp);
2378 	vp = NULLVP;
2379 
2380 	if (unp->un_flag & UNIONFS_OPENEXTU)
2381 		vp = unp->un_uppervp;
2382 	else if (unp->un_flag & UNIONFS_OPENEXTL)
2383 		vp = unp->un_lowervp;
2384 
2385 	if (vp == NULLVP)
2386 		return (EOPNOTSUPP);
2387 
2388 	return (VOP_GETEXTATTR(vp, ap->a_attrnamespace, ap->a_name,
2389 	    ap->a_uio, ap->a_size, ap->a_cred, ap->a_td));
2390 }
2391 
2392 static int
2393 unionfs_setextattr(struct vop_setextattr_args *ap)
2394 {
2395 	struct unionfs_node *unp;
2396 	struct vnode   *uvp;
2397 	struct vnode   *lvp;
2398 	struct vnode   *ovp;
2399 	struct ucred   *cred;
2400 	struct thread  *td;
2401 	int		error;
2402 
2403 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2404 
2405 	error = EROFS;
2406 	unp = VTOUNIONFS(ap->a_vp);
2407 	uvp = unp->un_uppervp;
2408 	lvp = unp->un_lowervp;
2409 	ovp = NULLVP;
2410 	cred = ap->a_cred;
2411 	td = ap->a_td;
2412 
2413 	UNIONFS_INTERNAL_DEBUG("unionfs_setextattr: enter (un_flag=%x)\n",
2414 	    unp->un_flag);
2415 
2416 	if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
2417 		return (EROFS);
2418 
2419 	if (unp->un_flag & UNIONFS_OPENEXTU)
2420 		ovp = unp->un_uppervp;
2421 	else if (unp->un_flag & UNIONFS_OPENEXTL)
2422 		ovp = unp->un_lowervp;
2423 
2424 	if (ovp == NULLVP)
2425 		return (EOPNOTSUPP);
2426 
2427 	if (ovp == lvp && lvp->v_type == VREG) {
2428 		VOP_CLOSEEXTATTR(lvp, 0, cred, td);
2429 		if (uvp == NULLVP &&
2430 		    (error = unionfs_copyfile(unp, 1, cred, td)) != 0) {
2431 unionfs_setextattr_reopen:
2432 			if ((unp->un_flag & UNIONFS_OPENEXTL) &&
2433 			    VOP_OPENEXTATTR(lvp, cred, td)) {
2434 #ifdef DIAGNOSTIC
2435 				panic("unionfs: VOP_OPENEXTATTR failed");
2436 #endif
2437 				unp->un_flag &= ~UNIONFS_OPENEXTL;
2438 			}
2439 			goto unionfs_setextattr_abort;
2440 		}
2441 		uvp = unp->un_uppervp;
2442 		if ((error = VOP_OPENEXTATTR(uvp, cred, td)) != 0)
2443 			goto unionfs_setextattr_reopen;
2444 		unp->un_flag &= ~UNIONFS_OPENEXTL;
2445 		unp->un_flag |= UNIONFS_OPENEXTU;
2446 		ovp = uvp;
2447 	}
2448 
2449 	if (ovp == uvp) {
2450 		int lkflags;
2451 		unionfs_forward_vop_start(ovp, &lkflags);
2452 		error = VOP_SETEXTATTR(ovp, ap->a_attrnamespace, ap->a_name,
2453 		    ap->a_uio, cred, td);
2454 		unionfs_forward_vop_finish(ap->a_vp, ovp, lkflags);
2455 	}
2456 
2457 unionfs_setextattr_abort:
2458 	UNIONFS_INTERNAL_DEBUG("unionfs_setextattr: leave (%d)\n", error);
2459 
2460 	return (error);
2461 }
2462 
2463 static int
2464 unionfs_listextattr(struct vop_listextattr_args *ap)
2465 {
2466 	struct unionfs_node *unp;
2467 	struct vnode *vp;
2468 
2469 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2470 
2471 	unp = VTOUNIONFS(ap->a_vp);
2472 	vp = NULLVP;
2473 
2474 	if (unp->un_flag & UNIONFS_OPENEXTU)
2475 		vp = unp->un_uppervp;
2476 	else if (unp->un_flag & UNIONFS_OPENEXTL)
2477 		vp = unp->un_lowervp;
2478 
2479 	if (vp == NULLVP)
2480 		return (EOPNOTSUPP);
2481 
2482 	return (VOP_LISTEXTATTR(vp, ap->a_attrnamespace, ap->a_uio,
2483 	    ap->a_size, ap->a_cred, ap->a_td));
2484 }
2485 
2486 static int
2487 unionfs_deleteextattr(struct vop_deleteextattr_args *ap)
2488 {
2489 	struct unionfs_node *unp;
2490 	struct vnode   *uvp;
2491 	struct vnode   *lvp;
2492 	struct vnode   *ovp;
2493 	struct ucred   *cred;
2494 	struct thread  *td;
2495 	int		error;
2496 
2497 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2498 
2499 	error = EROFS;
2500 	unp = VTOUNIONFS(ap->a_vp);
2501 	uvp = unp->un_uppervp;
2502 	lvp = unp->un_lowervp;
2503 	ovp = NULLVP;
2504 	cred = ap->a_cred;
2505 	td = ap->a_td;
2506 
2507 	UNIONFS_INTERNAL_DEBUG("unionfs_deleteextattr: enter (un_flag=%x)\n",
2508 	    unp->un_flag);
2509 
2510 	if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
2511 		return (EROFS);
2512 
2513 	if (unp->un_flag & UNIONFS_OPENEXTU)
2514 		ovp = unp->un_uppervp;
2515 	else if (unp->un_flag & UNIONFS_OPENEXTL)
2516 		ovp = unp->un_lowervp;
2517 
2518 	if (ovp == NULLVP)
2519 		return (EOPNOTSUPP);
2520 
2521 	if (ovp == lvp && lvp->v_type == VREG) {
2522 		VOP_CLOSEEXTATTR(lvp, 0, cred, td);
2523 		if (uvp == NULLVP &&
2524 		    (error = unionfs_copyfile(unp, 1, cred, td)) != 0) {
2525 unionfs_deleteextattr_reopen:
2526 			if ((unp->un_flag & UNIONFS_OPENEXTL) &&
2527 			    VOP_OPENEXTATTR(lvp, cred, td)) {
2528 #ifdef DIAGNOSTIC
2529 				panic("unionfs: VOP_OPENEXTATTR failed");
2530 #endif
2531 				unp->un_flag &= ~UNIONFS_OPENEXTL;
2532 			}
2533 			goto unionfs_deleteextattr_abort;
2534 		}
2535 		uvp = unp->un_uppervp;
2536 		if ((error = VOP_OPENEXTATTR(uvp, cred, td)) != 0)
2537 			goto unionfs_deleteextattr_reopen;
2538 		unp->un_flag &= ~UNIONFS_OPENEXTL;
2539 		unp->un_flag |= UNIONFS_OPENEXTU;
2540 		ovp = uvp;
2541 	}
2542 
2543 	if (ovp == uvp)
2544 		error = VOP_DELETEEXTATTR(ovp, ap->a_attrnamespace, ap->a_name,
2545 		    ap->a_cred, ap->a_td);
2546 
2547 unionfs_deleteextattr_abort:
2548 	UNIONFS_INTERNAL_DEBUG("unionfs_deleteextattr: leave (%d)\n", error);
2549 
2550 	return (error);
2551 }
2552 
2553 static int
2554 unionfs_setlabel(struct vop_setlabel_args *ap)
2555 {
2556 	struct unionfs_node *unp;
2557 	struct vnode   *uvp;
2558 	struct vnode   *lvp;
2559 	struct thread  *td;
2560 	int		error;
2561 
2562 	UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: enter\n");
2563 
2564 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2565 
2566 	error = EROFS;
2567 	unp = VTOUNIONFS(ap->a_vp);
2568 	uvp = unp->un_uppervp;
2569 	lvp = unp->un_lowervp;
2570 	td = ap->a_td;
2571 
2572 	if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
2573 		return (EROFS);
2574 
2575 	if (uvp == NULLVP && lvp->v_type == VREG) {
2576 		if ((error = unionfs_copyfile(unp, 1, ap->a_cred, td)) != 0)
2577 			return (error);
2578 		uvp = unp->un_uppervp;
2579 	}
2580 
2581 	if (uvp != NULLVP)
2582 		error = VOP_SETLABEL(uvp, ap->a_label, ap->a_cred, td);
2583 
2584 	UNIONFS_INTERNAL_DEBUG("unionfs_setlabel: leave (%d)\n", error);
2585 
2586 	return (error);
2587 }
2588 
2589 static int
2590 unionfs_vptofh(struct vop_vptofh_args *ap)
2591 {
2592 	return (EOPNOTSUPP);
2593 }
2594 
2595 static int
2596 unionfs_add_writecount(struct vop_add_writecount_args *ap)
2597 {
2598 	struct vnode *tvp, *vp;
2599 	struct unionfs_node *unp;
2600 	int error, writerefs __diagused;
2601 
2602 	vp = ap->a_vp;
2603 	unp = VTOUNIONFS(vp);
2604 	tvp = unp->un_uppervp;
2605 	KASSERT(tvp != NULL,
2606 	    ("%s: adding write ref without upper vnode", __func__));
2607 	error = VOP_ADD_WRITECOUNT(tvp, ap->a_inc);
2608 	if (error != 0)
2609 		return (error);
2610 	/*
2611 	 * We need to track the write refs we've passed to the underlying
2612 	 * vnodes so that we can undo them in case we are forcibly unmounted.
2613 	 */
2614 	writerefs = atomic_fetchadd_int(&vp->v_writecount, ap->a_inc);
2615 	/* text refs are bypassed to lowervp */
2616 	VNASSERT(writerefs >= 0, vp,
2617 	    ("%s: invalid write count %d", __func__, writerefs));
2618 	VNASSERT(writerefs + ap->a_inc >= 0, vp,
2619 	    ("%s: invalid write count inc %d + %d", __func__,
2620 	    writerefs, ap->a_inc));
2621 	return (0);
2622 }
2623 
2624 static int
2625 unionfs_vput_pair(struct vop_vput_pair_args *ap)
2626 {
2627 	struct mount *mp;
2628 	struct vnode *dvp, *vp, **vpp, *lvp, *ldvp, *uvp, *udvp, *tempvp;
2629 	struct unionfs_node *dunp, *unp;
2630 	int error, res;
2631 
2632 	dvp = ap->a_dvp;
2633 	vpp = ap->a_vpp;
2634 	vp = NULLVP;
2635 	lvp = NULLVP;
2636 	uvp = NULLVP;
2637 	unp = NULL;
2638 
2639 	dunp = VTOUNIONFS(dvp);
2640 	udvp = dunp->un_uppervp;
2641 	ldvp = dunp->un_lowervp;
2642 
2643 	/*
2644 	 * Underlying vnodes should be locked because the encompassing unionfs
2645 	 * node is locked, but will not be referenced, as the reference will
2646 	 * only be on the unionfs node.  Reference them now so that the vput()s
2647 	 * performed by VOP_VPUT_PAIR() will have a reference to drop.
2648 	 */
2649 	if (udvp != NULLVP)
2650 		vref(udvp);
2651 	if (ldvp != NULLVP)
2652 		vref(ldvp);
2653 
2654 	if (vpp != NULL)
2655 		vp = *vpp;
2656 
2657 	if (vp != NULLVP) {
2658 		unp = VTOUNIONFS(vp);
2659 		uvp = unp->un_uppervp;
2660 		lvp = unp->un_lowervp;
2661 		if (uvp != NULLVP)
2662 			vref(uvp);
2663 		if (lvp != NULLVP)
2664 			vref(lvp);
2665 
2666 		/*
2667 		 * If we're being asked to return a locked child vnode, then
2668 		 * we may need to create a replacement vnode in case the
2669 		 * original is reclaimed while the lock is dropped.  In that
2670 		 * case we'll need to ensure the mount and the underlying
2671 		 * vnodes aren't also recycled during that window.
2672 		 */
2673 		if (!ap->a_unlock_vp) {
2674 			vhold(vp);
2675 			if (uvp != NULLVP)
2676 				vhold(uvp);
2677 			if (lvp != NULLVP)
2678 				vhold(lvp);
2679 			mp = vp->v_mount;
2680 			vfs_ref(mp);
2681 		}
2682 	}
2683 
2684 	/*
2685 	 * TODO: Because unionfs_lock() locks both the lower and upper vnodes
2686 	 * (if available), we must also call VOP_VPUT_PAIR() on both the lower
2687 	 * and upper parent/child pairs.  If unionfs_lock() is reworked to lock
2688 	 * only a single vnode, this code will need to change to also only
2689 	 * operate on one vnode pair.
2690 	 */
2691 	ASSERT_VOP_LOCKED(ldvp, __func__);
2692 	ASSERT_VOP_LOCKED(udvp, __func__);
2693 	ASSERT_VOP_LOCKED(lvp, __func__);
2694 	ASSERT_VOP_LOCKED(uvp, __func__);
2695 
2696 	KASSERT(lvp == NULLVP || ldvp != NULLVP,
2697 	    ("%s: NULL ldvp with non-NULL lvp", __func__));
2698 	if (ldvp != NULLVP)
2699 		res = VOP_VPUT_PAIR(ldvp, lvp != NULLVP ? &lvp : NULL, true);
2700 	KASSERT(uvp == NULLVP || udvp != NULLVP,
2701 	    ("%s: NULL udvp with non-NULL uvp", __func__));
2702 	if (udvp != NULLVP)
2703 		res = VOP_VPUT_PAIR(udvp, uvp != NULLVP ? &uvp : NULL, true);
2704 
2705 	ASSERT_VOP_UNLOCKED(ldvp, __func__);
2706 	ASSERT_VOP_UNLOCKED(udvp, __func__);
2707 	ASSERT_VOP_UNLOCKED(lvp, __func__);
2708 	ASSERT_VOP_UNLOCKED(uvp, __func__);
2709 
2710 	/*
2711 	 * VOP_VPUT_PAIR() dropped the references we added to the underlying
2712 	 * vnodes, now drop the caller's reference to the unionfs vnodes.
2713 	 */
2714 	if (vp != NULLVP && ap->a_unlock_vp)
2715 		vrele(vp);
2716 	vrele(dvp);
2717 
2718 	if (vp == NULLVP || ap->a_unlock_vp)
2719 		return (res);
2720 
2721 	/*
2722 	 * We're being asked to return a locked vnode.  At this point, the
2723 	 * underlying vnodes have been unlocked, so vp may have been reclaimed.
2724 	 */
2725 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2726 	if (vp->v_data == NULL && vfs_busy(mp, MBF_NOWAIT) == 0) {
2727 		vput(vp);
2728 		error = unionfs_nodeget(mp, uvp, lvp, dvp, &tempvp, NULL);
2729 		if (error == 0) {
2730 			vn_lock(tempvp, LK_EXCLUSIVE | LK_RETRY);
2731 			*vpp = tempvp;
2732 		} else
2733 			vget(vp, LK_EXCLUSIVE | LK_RETRY);
2734 		vfs_unbusy(mp);
2735 	}
2736 	if (lvp != NULLVP)
2737 		vdrop(lvp);
2738 	if (uvp != NULLVP)
2739 		vdrop(uvp);
2740 	vdrop(vp);
2741 	vfs_rel(mp);
2742 
2743 	return (res);
2744 }
2745 
2746 static int
2747 unionfs_set_text(struct vop_set_text_args *ap)
2748 {
2749 	struct vnode *tvp;
2750 	struct unionfs_node *unp;
2751 	int error;
2752 
2753 	/*
2754 	 * We assume text refs are managed against lvp/uvp through the
2755 	 * executable mapping backed by its VM object.  We therefore don't
2756 	 * need to track leased text refs in the case of a forcible unmount.
2757 	 */
2758 	unp = VTOUNIONFS(ap->a_vp);
2759 	ASSERT_VOP_LOCKED(ap->a_vp, __func__);
2760 	tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp;
2761 	error = VOP_SET_TEXT(tvp);
2762 	return (error);
2763 }
2764 
2765 static int
2766 unionfs_unset_text(struct vop_unset_text_args *ap)
2767 {
2768 	struct vnode *tvp;
2769 	struct unionfs_node *unp;
2770 
2771 	ASSERT_VOP_LOCKED(ap->a_vp, __func__);
2772 	unp = VTOUNIONFS(ap->a_vp);
2773 	tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp;
2774 	VOP_UNSET_TEXT_CHECKED(tvp);
2775 	return (0);
2776 }
2777 
2778 static int
2779 unionfs_unp_bind(struct vop_unp_bind_args *ap)
2780 {
2781 	struct vnode *tvp;
2782 	struct unionfs_node *unp;
2783 
2784 	ASSERT_VOP_LOCKED(ap->a_vp, __func__);
2785 	unp = VTOUNIONFS(ap->a_vp);
2786 	tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp;
2787 	VOP_UNP_BIND(tvp, ap->a_unpcb);
2788 	return (0);
2789 }
2790 
2791 static int
2792 unionfs_unp_connect(struct vop_unp_connect_args *ap)
2793 {
2794 	struct vnode *tvp;
2795 	struct unionfs_node *unp;
2796 
2797 	ASSERT_VOP_LOCKED(ap->a_vp, __func__);
2798 	unp = VTOUNIONFS(ap->a_vp);
2799 	tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp;
2800 	VOP_UNP_CONNECT(tvp, ap->a_unpcb);
2801 	return (0);
2802 }
2803 
2804 static int
2805 unionfs_unp_detach(struct vop_unp_detach_args *ap)
2806 {
2807 	struct vnode *tvp;
2808 	struct unionfs_node *unp;
2809 
2810 	tvp = NULL;
2811 	/*
2812 	 * VOP_UNP_DETACH() is not guaranteed to be called with the unionfs
2813 	 * vnode locked, so we take the interlock to prevent a concurrent
2814 	 * unmount from freeing the unionfs private data.
2815 	 */
2816 	VI_LOCK(ap->a_vp);
2817 	unp = VTOUNIONFS(ap->a_vp);
2818 	if (unp != NULL) {
2819 		tvp = unp->un_uppervp != NULL ?
2820 		    unp->un_uppervp : unp->un_lowervp;
2821 		/*
2822 		 * Hold the target vnode to prevent a concurrent unionfs
2823 		 * unmount from causing it to be recycled once the interlock
2824 		 * is dropped.
2825 		 */
2826 		vholdnz(tvp);
2827 	}
2828 	VI_UNLOCK(ap->a_vp);
2829 	if (tvp != NULL) {
2830 		VOP_UNP_DETACH(tvp);
2831 		vdrop(tvp);
2832 	}
2833 	return (0);
2834 }
2835 
2836 struct vop_vector unionfs_vnodeops = {
2837 	.vop_default =		&default_vnodeops,
2838 
2839 	.vop_access =		unionfs_access,
2840 	.vop_aclcheck =		unionfs_aclcheck,
2841 	.vop_advlock =		unionfs_advlock,
2842 	.vop_bmap =		VOP_EOPNOTSUPP,
2843 	.vop_cachedlookup =	unionfs_lookup,
2844 	.vop_close =		unionfs_close,
2845 	.vop_closeextattr =	unionfs_closeextattr,
2846 	.vop_create =		unionfs_create,
2847 	.vop_deleteextattr =	unionfs_deleteextattr,
2848 	.vop_fsync =		unionfs_fsync,
2849 	.vop_getacl =		unionfs_getacl,
2850 	.vop_getattr =		unionfs_getattr,
2851 	.vop_getextattr =	unionfs_getextattr,
2852 	.vop_getwritemount =	unionfs_getwritemount,
2853 	.vop_inactive =		unionfs_inactive,
2854 	.vop_need_inactive =	vop_stdneed_inactive,
2855 	.vop_islocked =		vop_stdislocked,
2856 	.vop_ioctl =		unionfs_ioctl,
2857 	.vop_link =		unionfs_link,
2858 	.vop_listextattr =	unionfs_listextattr,
2859 	.vop_lock1 =		unionfs_lock,
2860 	.vop_lookup =		vfs_cache_lookup,
2861 	.vop_mkdir =		unionfs_mkdir,
2862 	.vop_mknod =		unionfs_mknod,
2863 	.vop_open =		unionfs_open,
2864 	.vop_openextattr =	unionfs_openextattr,
2865 	.vop_pathconf =		unionfs_pathconf,
2866 	.vop_poll =		unionfs_poll,
2867 	.vop_print =		unionfs_print,
2868 	.vop_read =		unionfs_read,
2869 	.vop_readdir =		unionfs_readdir,
2870 	.vop_readlink =		unionfs_readlink,
2871 	.vop_reclaim =		unionfs_reclaim,
2872 	.vop_remove =		unionfs_remove,
2873 	.vop_rename =		unionfs_rename,
2874 	.vop_rmdir =		unionfs_rmdir,
2875 	.vop_setacl =		unionfs_setacl,
2876 	.vop_setattr =		unionfs_setattr,
2877 	.vop_setextattr =	unionfs_setextattr,
2878 	.vop_setlabel =		unionfs_setlabel,
2879 	.vop_strategy =		unionfs_strategy,
2880 	.vop_symlink =		unionfs_symlink,
2881 	.vop_unlock =		unionfs_unlock,
2882 	.vop_whiteout =		unionfs_whiteout,
2883 	.vop_write =		unionfs_write,
2884 	.vop_vptofh =		unionfs_vptofh,
2885 	.vop_add_writecount =	unionfs_add_writecount,
2886 	.vop_vput_pair =	unionfs_vput_pair,
2887 	.vop_set_text =		unionfs_set_text,
2888 	.vop_unset_text = 	unionfs_unset_text,
2889 	.vop_unp_bind =		unionfs_unp_bind,
2890 	.vop_unp_connect =	unionfs_unp_connect,
2891 	.vop_unp_detach =	unionfs_unp_detach,
2892 };
2893 VFS_VOP_VECTOR_REGISTER(unionfs_vnodeops);
2894