xref: /freebsd/sys/fs/unionfs/union_vnops.c (revision 4b9d6057)
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;
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 		}
143 
144 		if (error == 0) {
145 			/*
146 			 * Exchange lock and reference from vp to
147 			 * dunp->un_dvp. vp is upper/lower vnode, but it
148 			 * will need to return the unionfs vnode.
149 			 */
150 			if (nameiop == DELETE  || nameiop == RENAME ||
151 			    (cnp->cn_lkflags & LK_TYPE_MASK))
152 				VOP_UNLOCK(vp);
153 			vrele(vp);
154 
155 			VOP_UNLOCK(dvp);
156 			*(ap->a_vpp) = dunp->un_dvp;
157 			vref(dunp->un_dvp);
158 
159 			if (nameiop == DELETE || nameiop == RENAME)
160 				vn_lock(dunp->un_dvp, LK_EXCLUSIVE | LK_RETRY);
161 			else if (cnp->cn_lkflags & LK_TYPE_MASK)
162 				vn_lock(dunp->un_dvp, cnp->cn_lkflags |
163 				    LK_RETRY);
164 
165 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
166 		} else if (error == ENOENT && (cnflags & MAKEENTRY) != 0)
167 			cache_enter(dvp, NULLVP, cnp);
168 
169 		goto unionfs_lookup_return;
170 	}
171 
172 	/*
173 	 * lookup upper layer
174 	 */
175 	if (udvp != NULLVP) {
176 		uerror = VOP_LOOKUP(udvp, &uvp, cnp);
177 
178 		if (uerror == 0) {
179 			if (udvp == uvp) {	/* is dot */
180 				vrele(uvp);
181 				*(ap->a_vpp) = dvp;
182 				vref(dvp);
183 
184 				error = uerror;
185 				goto unionfs_lookup_return;
186 			}
187 			if (nameiop == DELETE || nameiop == RENAME ||
188 			    (cnp->cn_lkflags & LK_TYPE_MASK))
189 				VOP_UNLOCK(uvp);
190 		}
191 
192 		/* check whiteout */
193 		if (uerror == ENOENT || uerror == EJUSTRETURN)
194 			if (cnp->cn_flags & ISWHITEOUT)
195 				iswhiteout = 1;	/* don't lookup lower */
196 		if (iswhiteout == 0 && ldvp != NULLVP)
197 			if (!VOP_GETATTR(udvp, &va, cnp->cn_cred) &&
198 			    (va.va_flags & OPAQUE))
199 				iswhiteout = 1;	/* don't lookup lower */
200 #if 0
201 		UNIONFS_INTERNAL_DEBUG(
202 		    "unionfs_lookup: debug: whiteout=%d, path=%s\n",
203 		    iswhiteout, cnp->cn_nameptr);
204 #endif
205 	}
206 
207 	/*
208 	 * lookup lower layer
209 	 */
210 	if (ldvp != NULLVP && !(cnflags & DOWHITEOUT) && iswhiteout == 0) {
211 		/* always op is LOOKUP */
212 		cnp->cn_nameiop = LOOKUP;
213 		cnflagsbk = cnp->cn_flags;
214 		cnp->cn_flags = cnflags;
215 
216 		lerror = VOP_LOOKUP(ldvp, &lvp, cnp);
217 
218 		cnp->cn_nameiop = nameiop;
219 		if (udvp != NULLVP && (uerror == 0 || uerror == EJUSTRETURN))
220 			cnp->cn_flags = cnflagsbk;
221 
222 		if (lerror == 0) {
223 			if (ldvp == lvp) {	/* is dot */
224 				if (uvp != NULLVP)
225 					vrele(uvp);	/* no need? */
226 				vrele(lvp);
227 				*(ap->a_vpp) = dvp;
228 				vref(dvp);
229 
230 				UNIONFS_INTERNAL_DEBUG(
231 				    "unionfs_lookup: leave (%d)\n", lerror);
232 
233 				return (lerror);
234 			}
235 			if (cnp->cn_lkflags & LK_TYPE_MASK)
236 				VOP_UNLOCK(lvp);
237 		}
238 	}
239 
240 	/*
241 	 * check lookup result
242 	 */
243 	if (uvp == NULLVP && lvp == NULLVP) {
244 		error = (udvp != NULLVP ? uerror : lerror);
245 		goto unionfs_lookup_return;
246 	}
247 
248 	/*
249 	 * check vnode type
250 	 */
251 	if (uvp != NULLVP && lvp != NULLVP && uvp->v_type != lvp->v_type) {
252 		vrele(lvp);
253 		lvp = NULLVP;
254 	}
255 
256 	/*
257 	 * check shadow dir
258 	 */
259 	if (uerror != 0 && uerror != EJUSTRETURN && udvp != NULLVP &&
260 	    lerror == 0 && lvp != NULLVP && lvp->v_type == VDIR &&
261 	    !(dvp->v_mount->mnt_flag & MNT_RDONLY) &&
262 	    (1 < cnp->cn_namelen || '.' != *(cnp->cn_nameptr))) {
263 		/* get unionfs vnode in order to create a new shadow dir. */
264 		error = unionfs_nodeget(dvp->v_mount, NULLVP, lvp, dvp, &vp,
265 		    cnp);
266 		if (error != 0)
267 			goto unionfs_lookup_cleanup;
268 
269 		if (LK_SHARED == (cnp->cn_lkflags & LK_TYPE_MASK))
270 			VOP_UNLOCK(vp);
271 		if (LK_EXCLUSIVE != VOP_ISLOCKED(vp)) {
272 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
273 			lockflag = 1;
274 		}
275 		error = unionfs_mkshadowdir(MOUNTTOUNIONFSMOUNT(dvp->v_mount),
276 		    udvp, VTOUNIONFS(vp), cnp, td);
277 		if (lockflag != 0)
278 			VOP_UNLOCK(vp);
279 		if (error != 0) {
280 			UNIONFSDEBUG(
281 			    "unionfs_lookup: Unable to create shadow dir.");
282 			if ((cnp->cn_lkflags & LK_TYPE_MASK) == LK_EXCLUSIVE)
283 				vput(vp);
284 			else
285 				vrele(vp);
286 			goto unionfs_lookup_cleanup;
287 		}
288 		if ((cnp->cn_lkflags & LK_TYPE_MASK) == LK_SHARED)
289 			vn_lock(vp, LK_SHARED | LK_RETRY);
290 	}
291 	/*
292 	 * get unionfs vnode.
293 	 */
294 	else {
295 		if (uvp != NULLVP)
296 			error = uerror;
297 		else
298 			error = lerror;
299 		if (error != 0)
300 			goto unionfs_lookup_cleanup;
301 		/*
302 		 * get socket vnode.
303 		 */
304 		if (uvp != NULLVP && uvp->v_type == VSOCK) {
305 			vp = uvp;
306 			vref(vp);
307 			if (cnp->cn_lkflags & LK_TYPE_MASK)
308 				vn_lock(vp, cnp->cn_lkflags | LK_RETRY);
309 		}
310 		else if (lvp != NULLVP && lvp->v_type == VSOCK) {
311 			vp = lvp;
312 			vref(vp);
313 			if (cnp->cn_lkflags & LK_TYPE_MASK)
314 				vn_lock(vp, cnp->cn_lkflags | LK_RETRY);
315 		}
316 		/*
317 		 * get unionfs vnode.
318 		 */
319 		else
320 			error = unionfs_nodeget(dvp->v_mount, uvp, lvp,
321 			    dvp, &vp, cnp);
322 		if (error != 0) {
323 			UNIONFSDEBUG(
324 			    "unionfs_lookup: Unable to create unionfs vnode.");
325 			goto unionfs_lookup_cleanup;
326 		}
327 		if ((nameiop == DELETE || nameiop == RENAME) &&
328 		    (cnp->cn_lkflags & LK_TYPE_MASK) == 0)
329 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
330 	}
331 
332 	*(ap->a_vpp) = vp;
333 
334 	if ((cnflags & MAKEENTRY) && vp->v_type != VSOCK)
335 		cache_enter(dvp, vp, cnp);
336 
337 unionfs_lookup_cleanup:
338 	if (uvp != NULLVP)
339 		vrele(uvp);
340 	if (lvp != NULLVP)
341 		vrele(lvp);
342 
343 	if (error == ENOENT && (cnflags & MAKEENTRY) != 0)
344 		cache_enter(dvp, NULLVP, cnp);
345 
346 unionfs_lookup_return:
347 
348 	UNIONFS_INTERNAL_DEBUG("unionfs_lookup: leave (%d)\n", error);
349 
350 	return (error);
351 }
352 
353 static int
354 unionfs_create(struct vop_create_args *ap)
355 {
356 	struct unionfs_node *dunp;
357 	struct componentname *cnp;
358 	struct vnode   *udvp;
359 	struct vnode   *vp;
360 	int		error;
361 
362 	UNIONFS_INTERNAL_DEBUG("unionfs_create: enter\n");
363 
364 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
365 
366 	dunp = VTOUNIONFS(ap->a_dvp);
367 	cnp = ap->a_cnp;
368 	udvp = dunp->un_uppervp;
369 	error = EROFS;
370 
371 	if (udvp != NULLVP) {
372 		error = VOP_CREATE(udvp, &vp, cnp, ap->a_vap);
373 		if (error != 0)
374 			goto unionfs_create_abort;
375 
376 		if (vp->v_type == VSOCK)
377 			*(ap->a_vpp) = vp;
378 		else {
379 			VOP_UNLOCK(vp);
380 			error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
381 			    ap->a_dvp, ap->a_vpp, cnp);
382 			vrele(vp);
383 		}
384 	}
385 
386 unionfs_create_abort:
387 	UNIONFS_INTERNAL_DEBUG("unionfs_create: leave (%d)\n", error);
388 
389 	return (error);
390 }
391 
392 static int
393 unionfs_whiteout(struct vop_whiteout_args *ap)
394 {
395 	struct unionfs_node *dunp;
396 	struct componentname *cnp;
397 	struct vnode   *udvp;
398 	int		error;
399 
400 	UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: enter\n");
401 
402 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
403 
404 	dunp = VTOUNIONFS(ap->a_dvp);
405 	cnp = ap->a_cnp;
406 	udvp = dunp->un_uppervp;
407 	error = EOPNOTSUPP;
408 
409 	if (udvp != NULLVP) {
410 		switch (ap->a_flags) {
411 		case CREATE:
412 		case DELETE:
413 		case LOOKUP:
414 			error = VOP_WHITEOUT(udvp, cnp, ap->a_flags);
415 			break;
416 		default:
417 			error = EINVAL;
418 			break;
419 		}
420 	}
421 
422 	UNIONFS_INTERNAL_DEBUG("unionfs_whiteout: leave (%d)\n", error);
423 
424 	return (error);
425 }
426 
427 static int
428 unionfs_mknod(struct vop_mknod_args *ap)
429 {
430 	struct unionfs_node *dunp;
431 	struct componentname *cnp;
432 	struct vnode   *udvp;
433 	struct vnode   *vp;
434 	int		error;
435 
436 	UNIONFS_INTERNAL_DEBUG("unionfs_mknod: enter\n");
437 
438 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
439 
440 	dunp = VTOUNIONFS(ap->a_dvp);
441 	cnp = ap->a_cnp;
442 	udvp = dunp->un_uppervp;
443 	error = EROFS;
444 
445 	if (udvp != NULLVP) {
446 		error = VOP_MKNOD(udvp, &vp, cnp, ap->a_vap);
447 		if (error != 0)
448 			goto unionfs_mknod_abort;
449 
450 		if (vp->v_type == VSOCK)
451 			*(ap->a_vpp) = vp;
452 		else {
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 		}
458 	}
459 
460 unionfs_mknod_abort:
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_uppervp->v_mount->mnt_flag & MNT_RDONLY) {
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_uppervp->v_mount->mnt_flag & MNT_RDONLY)) {
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 		error = VOP_SETATTR(uvp, vap, ap->a_cred);
895 
896 	UNIONFS_INTERNAL_DEBUG("unionfs_setattr: leave (%d)\n", error);
897 
898 	return (error);
899 }
900 
901 static int
902 unionfs_read(struct vop_read_args *ap)
903 {
904 	struct unionfs_node *unp;
905 	struct vnode   *tvp;
906 	int		error;
907 
908 	/* UNIONFS_INTERNAL_DEBUG("unionfs_read: enter\n"); */
909 
910 	KASSERT_UNIONFS_VNODE(ap->a_vp);
911 
912 	unp = VTOUNIONFS(ap->a_vp);
913 	tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
914 
915 	error = VOP_READ(tvp, ap->a_uio, ap->a_ioflag, ap->a_cred);
916 
917 	/* UNIONFS_INTERNAL_DEBUG("unionfs_read: leave (%d)\n", error); */
918 
919 	return (error);
920 }
921 
922 static int
923 unionfs_write(struct vop_write_args *ap)
924 {
925 	struct unionfs_node *unp;
926 	struct vnode   *tvp;
927 	int		error;
928 
929 	/* UNIONFS_INTERNAL_DEBUG("unionfs_write: enter\n"); */
930 
931 	KASSERT_UNIONFS_VNODE(ap->a_vp);
932 
933 	unp = VTOUNIONFS(ap->a_vp);
934 	tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
935 
936 	error = VOP_WRITE(tvp, ap->a_uio, ap->a_ioflag, ap->a_cred);
937 
938 	/* UNIONFS_INTERNAL_DEBUG("unionfs_write: leave (%d)\n", error); */
939 
940 	return (error);
941 }
942 
943 static int
944 unionfs_ioctl(struct vop_ioctl_args *ap)
945 {
946 	struct unionfs_node *unp;
947 	struct unionfs_node_status *unsp;
948 	struct vnode   *ovp;
949 	int error;
950 
951 	UNIONFS_INTERNAL_DEBUG("unionfs_ioctl: enter\n");
952 
953 	KASSERT_UNIONFS_VNODE(ap->a_vp);
954 
955  	vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
956 	unp = VTOUNIONFS(ap->a_vp);
957 	unionfs_get_node_status(unp, ap->a_td, &unsp);
958 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
959 	unionfs_tryrem_node_status(unp, unsp);
960 	VOP_UNLOCK(ap->a_vp);
961 
962 	if (ovp == NULLVP)
963 		return (EBADF);
964 
965 	error = VOP_IOCTL(ovp, ap->a_command, ap->a_data, ap->a_fflag,
966 	    ap->a_cred, ap->a_td);
967 
968 	UNIONFS_INTERNAL_DEBUG("unionfs_ioctl: leave (%d)\n", error);
969 
970 	return (error);
971 }
972 
973 static int
974 unionfs_poll(struct vop_poll_args *ap)
975 {
976 	struct unionfs_node *unp;
977 	struct unionfs_node_status *unsp;
978 	struct vnode *ovp;
979 
980 	KASSERT_UNIONFS_VNODE(ap->a_vp);
981 
982  	vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
983 	unp = VTOUNIONFS(ap->a_vp);
984 	unionfs_get_node_status(unp, ap->a_td, &unsp);
985 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
986 	unionfs_tryrem_node_status(unp, unsp);
987 	VOP_UNLOCK(ap->a_vp);
988 
989 	if (ovp == NULLVP)
990 		return (EBADF);
991 
992 	return (VOP_POLL(ovp, ap->a_events, ap->a_cred, ap->a_td));
993 }
994 
995 static int
996 unionfs_fsync(struct vop_fsync_args *ap)
997 {
998 	struct unionfs_node *unp;
999 	struct unionfs_node_status *unsp;
1000 	struct vnode *ovp;
1001 
1002 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1003 
1004 	unp = VTOUNIONFS(ap->a_vp);
1005 	unionfs_get_node_status(unp, ap->a_td, &unsp);
1006 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
1007 	unionfs_tryrem_node_status(unp, unsp);
1008 
1009 	if (ovp == NULLVP)
1010 		return (EBADF);
1011 
1012 	return (VOP_FSYNC(ovp, ap->a_waitfor, ap->a_td));
1013 }
1014 
1015 static int
1016 unionfs_remove(struct vop_remove_args *ap)
1017 {
1018 	char	       *path;
1019 	struct unionfs_node *dunp;
1020 	struct unionfs_node *unp;
1021 	struct unionfs_mount *ump;
1022 	struct vnode   *udvp;
1023 	struct vnode   *uvp;
1024 	struct vnode   *lvp;
1025 	struct vnode   *vp;
1026 	struct componentname *cnp;
1027 	struct componentname cn;
1028 	struct thread  *td;
1029 	int		error;
1030 	int		pathlen;
1031 
1032 	UNIONFS_INTERNAL_DEBUG("unionfs_remove: enter\n");
1033 
1034 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
1035 
1036 	error = 0;
1037 	dunp = VTOUNIONFS(ap->a_dvp);
1038 	udvp = dunp->un_uppervp;
1039 	cnp = ap->a_cnp;
1040 	td = curthread;
1041 
1042 	if (ap->a_vp->v_op != &unionfs_vnodeops) {
1043 		if (ap->a_vp->v_type != VSOCK)
1044 			return (EINVAL);
1045 		ump = NULL;
1046 		vp = uvp = lvp = NULLVP;
1047 		/* search vnode */
1048 		VOP_UNLOCK(ap->a_vp);
1049 		error = unionfs_relookup(udvp, &vp, cnp, &cn, td,
1050 		    cnp->cn_nameptr, cnp->cn_namelen, DELETE);
1051 		if (error != 0 && error != ENOENT) {
1052 			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1053 			return (error);
1054 		}
1055 
1056 		if (error == 0 && vp == ap->a_vp) {
1057 			/* target vnode in upper */
1058 			uvp = vp;
1059 			vrele(vp);
1060 		} else {
1061 			/* target vnode in lower */
1062 			if (vp != NULLVP) {
1063 				if (udvp == vp)
1064 					vrele(vp);
1065 				else
1066 					vput(vp);
1067 			}
1068 			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1069 			lvp = ap->a_vp;
1070 		}
1071 		path = cnp->cn_nameptr;
1072 		pathlen = cnp->cn_namelen;
1073 	} else {
1074 		ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
1075 		unp = VTOUNIONFS(ap->a_vp);
1076 		uvp = unp->un_uppervp;
1077 		lvp = unp->un_lowervp;
1078 		path = unp->un_path;
1079 		pathlen = unp->un_pathlen;
1080 	}
1081 
1082 	if (udvp == NULLVP)
1083 		return (EROFS);
1084 
1085 	if (uvp != NULLVP) {
1086 		/*
1087 		 * XXX: if the vnode type is VSOCK, it will create whiteout
1088 		 *      after remove.
1089 		 */
1090 		if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS ||
1091 		    lvp != NULLVP)
1092 			cnp->cn_flags |= DOWHITEOUT;
1093 		error = VOP_REMOVE(udvp, uvp, cnp);
1094 	} else if (lvp != NULLVP)
1095 		error = unionfs_mkwhiteout(udvp, cnp, td, path, pathlen);
1096 
1097 	UNIONFS_INTERNAL_DEBUG("unionfs_remove: leave (%d)\n", error);
1098 
1099 	return (error);
1100 }
1101 
1102 static int
1103 unionfs_link(struct vop_link_args *ap)
1104 {
1105 	struct unionfs_node *dunp;
1106 	struct unionfs_node *unp;
1107 	struct vnode   *udvp;
1108 	struct vnode   *uvp;
1109 	struct componentname *cnp;
1110 	struct thread  *td;
1111 	int		error;
1112 	int		needrelookup;
1113 
1114 	UNIONFS_INTERNAL_DEBUG("unionfs_link: enter\n");
1115 
1116 	KASSERT_UNIONFS_VNODE(ap->a_tdvp);
1117 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1118 
1119 	error = 0;
1120 	needrelookup = 0;
1121 	dunp = VTOUNIONFS(ap->a_tdvp);
1122 	unp = NULL;
1123 	udvp = dunp->un_uppervp;
1124 	uvp = NULLVP;
1125 	cnp = ap->a_cnp;
1126 	td = curthread;
1127 
1128 	if (udvp == NULLVP)
1129 		return (EROFS);
1130 
1131 	if (ap->a_vp->v_op != &unionfs_vnodeops)
1132 		uvp = ap->a_vp;
1133 	else {
1134 		unp = VTOUNIONFS(ap->a_vp);
1135 
1136 		if (unp->un_uppervp == NULLVP) {
1137 			if (ap->a_vp->v_type != VREG)
1138 				return (EOPNOTSUPP);
1139 
1140 			error = unionfs_copyfile(unp, 1, cnp->cn_cred, td);
1141 			if (error != 0)
1142 				return (error);
1143 			needrelookup = 1;
1144 		}
1145 		uvp = unp->un_uppervp;
1146 	}
1147 
1148 	if (needrelookup != 0)
1149 		error = unionfs_relookup_for_create(ap->a_tdvp, cnp, td);
1150 
1151 	if (error == 0)
1152 		error = VOP_LINK(udvp, uvp, cnp);
1153 
1154 	UNIONFS_INTERNAL_DEBUG("unionfs_link: leave (%d)\n", error);
1155 
1156 	return (error);
1157 }
1158 
1159 static int
1160 unionfs_rename(struct vop_rename_args *ap)
1161 {
1162 	struct vnode   *fdvp;
1163 	struct vnode   *fvp;
1164 	struct componentname *fcnp;
1165 	struct vnode   *tdvp;
1166 	struct vnode   *tvp;
1167 	struct componentname *tcnp;
1168 	struct vnode   *ltdvp;
1169 	struct vnode   *ltvp;
1170 	struct thread  *td;
1171 
1172 	/* rename target vnodes */
1173 	struct vnode   *rfdvp;
1174 	struct vnode   *rfvp;
1175 	struct vnode   *rtdvp;
1176 	struct vnode   *rtvp;
1177 
1178 	struct unionfs_mount *ump;
1179 	struct unionfs_node *unp;
1180 	int		error;
1181 	int		needrelookup;
1182 
1183 	UNIONFS_INTERNAL_DEBUG("unionfs_rename: enter\n");
1184 
1185 	error = 0;
1186 	fdvp = ap->a_fdvp;
1187 	fvp = ap->a_fvp;
1188 	fcnp = ap->a_fcnp;
1189 	tdvp = ap->a_tdvp;
1190 	tvp = ap->a_tvp;
1191 	tcnp = ap->a_tcnp;
1192 	ltdvp = NULLVP;
1193 	ltvp = NULLVP;
1194 	td = curthread;
1195 	rfdvp = fdvp;
1196 	rfvp = fvp;
1197 	rtdvp = tdvp;
1198 	rtvp = tvp;
1199 	needrelookup = 0;
1200 
1201 	/* check for cross device rename */
1202 	if (fvp->v_mount != tdvp->v_mount ||
1203 	    (tvp != NULLVP && fvp->v_mount != tvp->v_mount)) {
1204 		if (fvp->v_op != &unionfs_vnodeops)
1205 			error = ENODEV;
1206 		else
1207 			error = EXDEV;
1208 		goto unionfs_rename_abort;
1209 	}
1210 
1211 	/* Renaming a file to itself has no effect. */
1212 	if (fvp == tvp)
1213 		goto unionfs_rename_abort;
1214 
1215 	/*
1216 	 * from/to vnode is unionfs node.
1217 	 */
1218 
1219 	KASSERT_UNIONFS_VNODE(fdvp);
1220 	KASSERT_UNIONFS_VNODE(fvp);
1221 	KASSERT_UNIONFS_VNODE(tdvp);
1222 	if (tvp != NULLVP)
1223 		KASSERT_UNIONFS_VNODE(tvp);
1224 
1225 	unp = VTOUNIONFS(fdvp);
1226 #ifdef UNIONFS_IDBG_RENAME
1227 	UNIONFS_INTERNAL_DEBUG("fdvp=%p, ufdvp=%p, lfdvp=%p\n",
1228 	    fdvp, unp->un_uppervp, unp->un_lowervp);
1229 #endif
1230 	if (unp->un_uppervp == NULLVP) {
1231 		error = ENODEV;
1232 		goto unionfs_rename_abort;
1233 	}
1234 	rfdvp = unp->un_uppervp;
1235 	vref(rfdvp);
1236 
1237 	unp = VTOUNIONFS(fvp);
1238 #ifdef UNIONFS_IDBG_RENAME
1239 	UNIONFS_INTERNAL_DEBUG("fvp=%p, ufvp=%p, lfvp=%p\n",
1240 	    fvp, unp->un_uppervp, unp->un_lowervp);
1241 #endif
1242 	ump = MOUNTTOUNIONFSMOUNT(fvp->v_mount);
1243 	if (unp->un_uppervp == NULLVP) {
1244 		switch (fvp->v_type) {
1245 		case VREG:
1246 			if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
1247 				goto unionfs_rename_abort;
1248 			error = unionfs_copyfile(unp, 1, fcnp->cn_cred, td);
1249 			VOP_UNLOCK(fvp);
1250 			if (error != 0)
1251 				goto unionfs_rename_abort;
1252 			break;
1253 		case VDIR:
1254 			if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
1255 				goto unionfs_rename_abort;
1256 			error = unionfs_mkshadowdir(ump, rfdvp, unp, fcnp, td);
1257 			VOP_UNLOCK(fvp);
1258 			if (error != 0)
1259 				goto unionfs_rename_abort;
1260 			break;
1261 		default:
1262 			error = ENODEV;
1263 			goto unionfs_rename_abort;
1264 		}
1265 
1266 		needrelookup = 1;
1267 	}
1268 
1269 	if (unp->un_lowervp != NULLVP)
1270 		fcnp->cn_flags |= DOWHITEOUT;
1271 	rfvp = unp->un_uppervp;
1272 	vref(rfvp);
1273 
1274 	unp = VTOUNIONFS(tdvp);
1275 #ifdef UNIONFS_IDBG_RENAME
1276 	UNIONFS_INTERNAL_DEBUG("tdvp=%p, utdvp=%p, ltdvp=%p\n",
1277 	    tdvp, unp->un_uppervp, unp->un_lowervp);
1278 #endif
1279 	if (unp->un_uppervp == NULLVP) {
1280 		error = ENODEV;
1281 		goto unionfs_rename_abort;
1282 	}
1283 	rtdvp = unp->un_uppervp;
1284 	ltdvp = unp->un_lowervp;
1285 	vref(rtdvp);
1286 
1287 	if (tdvp == tvp) {
1288 		rtvp = rtdvp;
1289 		vref(rtvp);
1290 	} else if (tvp != NULLVP) {
1291 		unp = VTOUNIONFS(tvp);
1292 #ifdef UNIONFS_IDBG_RENAME
1293 		UNIONFS_INTERNAL_DEBUG("tvp=%p, utvp=%p, ltvp=%p\n",
1294 		    tvp, unp->un_uppervp, unp->un_lowervp);
1295 #endif
1296 		if (unp->un_uppervp == NULLVP)
1297 			rtvp = NULLVP;
1298 		else {
1299 			if (tvp->v_type == VDIR) {
1300 				error = EINVAL;
1301 				goto unionfs_rename_abort;
1302 			}
1303 			rtvp = unp->un_uppervp;
1304 			ltvp = unp->un_lowervp;
1305 			vref(rtvp);
1306 		}
1307 	}
1308 
1309 	if (rfvp == rtvp)
1310 		goto unionfs_rename_abort;
1311 
1312 	if (needrelookup != 0) {
1313 		if ((error = vn_lock(fdvp, LK_EXCLUSIVE)) != 0)
1314 			goto unionfs_rename_abort;
1315 		error = unionfs_relookup_for_delete(fdvp, fcnp, td);
1316 		VOP_UNLOCK(fdvp);
1317 		if (error != 0)
1318 			goto unionfs_rename_abort;
1319 
1320 		/* Lock of tvp is canceled in order to avoid recursive lock. */
1321 		if (tvp != NULLVP && tvp != tdvp)
1322 			VOP_UNLOCK(tvp);
1323 		error = unionfs_relookup_for_rename(tdvp, tcnp, td);
1324 		if (tvp != NULLVP && tvp != tdvp)
1325 			vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY);
1326 		if (error != 0)
1327 			goto unionfs_rename_abort;
1328 	}
1329 
1330 	error = VOP_RENAME(rfdvp, rfvp, fcnp, rtdvp, rtvp, tcnp);
1331 
1332 	if (error == 0) {
1333 		if (rtvp != NULLVP && rtvp->v_type == VDIR)
1334 			cache_purge(tdvp);
1335 		if (fvp->v_type == VDIR && fdvp != tdvp)
1336 			cache_purge(fdvp);
1337 	}
1338 
1339 	if (ltdvp != NULLVP)
1340 		VOP_UNLOCK(ltdvp);
1341 	if (tdvp != rtdvp)
1342 		vrele(tdvp);
1343 	if (ltvp != NULLVP)
1344 		VOP_UNLOCK(ltvp);
1345 	if (tvp != rtvp && tvp != NULLVP) {
1346 		if (rtvp == NULLVP)
1347 			vput(tvp);
1348 		else
1349 			vrele(tvp);
1350 	}
1351 	if (fdvp != rfdvp)
1352 		vrele(fdvp);
1353 	if (fvp != rfvp)
1354 		vrele(fvp);
1355 
1356 	UNIONFS_INTERNAL_DEBUG("unionfs_rename: leave (%d)\n", error);
1357 
1358 	return (error);
1359 
1360 unionfs_rename_abort:
1361 	vput(tdvp);
1362 	if (tdvp != rtdvp)
1363 		vrele(rtdvp);
1364 	if (tvp != NULLVP) {
1365 		if (tdvp != tvp)
1366 			vput(tvp);
1367 		else
1368 			vrele(tvp);
1369 	}
1370 	if (tvp != rtvp && rtvp != NULLVP)
1371 		vrele(rtvp);
1372 	if (fdvp != rfdvp)
1373 		vrele(rfdvp);
1374 	if (fvp != rfvp)
1375 		vrele(rfvp);
1376 	vrele(fdvp);
1377 	vrele(fvp);
1378 
1379 	UNIONFS_INTERNAL_DEBUG("unionfs_rename: leave (%d)\n", error);
1380 
1381 	return (error);
1382 }
1383 
1384 static int
1385 unionfs_mkdir(struct vop_mkdir_args *ap)
1386 {
1387 	struct unionfs_node *dunp;
1388 	struct componentname *cnp;
1389 	struct vnode   *dvp;
1390 	struct vnode   *udvp;
1391 	struct vnode   *uvp;
1392 	struct vattr	va;
1393 	int		error;
1394 	int		lkflags;
1395 
1396 	UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: enter\n");
1397 
1398 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
1399 
1400 	error = EROFS;
1401 	dvp = ap->a_dvp;
1402 	dunp = VTOUNIONFS(dvp);
1403 	cnp = ap->a_cnp;
1404 	lkflags = cnp->cn_lkflags;
1405 	udvp = dunp->un_uppervp;
1406 
1407 	if (udvp != NULLVP) {
1408 		vref(udvp);
1409 		/* check opaque */
1410 		if (!(cnp->cn_flags & ISWHITEOUT)) {
1411 			error = VOP_GETATTR(udvp, &va, cnp->cn_cred);
1412 			if (error != 0)
1413 				goto unionfs_mkdir_cleanup;
1414 			if ((va.va_flags & OPAQUE) != 0)
1415 				cnp->cn_flags |= ISWHITEOUT;
1416 		}
1417 
1418 		if ((error = VOP_MKDIR(udvp, &uvp, cnp, ap->a_vap)) == 0) {
1419 			VOP_UNLOCK(uvp);
1420 			cnp->cn_lkflags = LK_EXCLUSIVE;
1421 			/*
1422 			 * The underlying VOP_MKDIR() implementation may have
1423 			 * temporarily dropped the parent directory vnode lock.
1424 			 * Because the unionfs vnode ordinarily shares that
1425 			 * lock, this may allow the unionfs vnode to be reclaimed
1426 			 * and its lock field reset.  In that case, the unionfs
1427 			 * vnode is effectively no longer locked, and we must
1428 			 * explicitly lock it before returning in order to meet
1429 			 * the locking requirements of VOP_MKDIR().
1430 			 */
1431 			if (__predict_false(VTOUNIONFS(dvp) == NULL)) {
1432 				error = ENOENT;
1433 				goto unionfs_mkdir_cleanup;
1434 			}
1435 			error = unionfs_nodeget(dvp->v_mount, uvp, NULLVP,
1436 			    dvp, ap->a_vpp, cnp);
1437 			cnp->cn_lkflags = lkflags;
1438 			vrele(uvp);
1439 		}
1440 	}
1441 
1442 unionfs_mkdir_cleanup:
1443 
1444 	if (__predict_false(VTOUNIONFS(dvp) == NULL)) {
1445 		vput(udvp);
1446 		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
1447 	} else if (udvp != NULLVP)
1448 		vrele(udvp);
1449 
1450 	UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: leave (%d)\n", error);
1451 
1452 	return (error);
1453 }
1454 
1455 static int
1456 unionfs_rmdir(struct vop_rmdir_args *ap)
1457 {
1458 	struct unionfs_node *dunp;
1459 	struct unionfs_node *unp;
1460 	struct unionfs_mount *ump;
1461 	struct componentname *cnp;
1462 	struct thread  *td;
1463 	struct vnode   *udvp;
1464 	struct vnode   *uvp;
1465 	struct vnode   *lvp;
1466 	int		error;
1467 
1468 	UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: enter\n");
1469 
1470 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
1471 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1472 
1473 	error = 0;
1474 	dunp = VTOUNIONFS(ap->a_dvp);
1475 	unp = VTOUNIONFS(ap->a_vp);
1476 	cnp = ap->a_cnp;
1477 	td = curthread;
1478 	udvp = dunp->un_uppervp;
1479 	uvp = unp->un_uppervp;
1480 	lvp = unp->un_lowervp;
1481 
1482 	if (udvp == NULLVP)
1483 		return (EROFS);
1484 
1485 	if (udvp == uvp)
1486 		return (EOPNOTSUPP);
1487 
1488 	if (uvp != NULLVP) {
1489 		if (lvp != NULLVP) {
1490 			error = unionfs_check_rmdir(ap->a_vp, cnp->cn_cred, td);
1491 			if (error != 0)
1492 				return (error);
1493 		}
1494 		ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
1495 		if (ump->um_whitemode == UNIONFS_WHITE_ALWAYS || lvp != NULLVP)
1496 			cnp->cn_flags |= DOWHITEOUT;
1497 		/*
1498 		 * The relookup path will need to relock the parent dvp and
1499 		 * possibly the vp as well.  Locking is expected to be done
1500 		 * in parent->child order; drop the lock on vp to avoid LOR
1501 		 * and potential recursion on vp's lock.
1502 		 * vp is expected to remain referenced during VOP_RMDIR(),
1503 		 * so vref/vrele should not be necessary here.
1504 		 */
1505 		VOP_UNLOCK(ap->a_vp);
1506 		VNPASS(vrefcnt(ap->a_vp) > 0, ap->a_vp);
1507 		error = unionfs_relookup_for_delete(ap->a_dvp, cnp, td);
1508 		vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1509 		/*
1510 		 * VOP_RMDIR is dispatched against udvp, so if uvp became
1511 		 * doomed while the lock was dropped above the target
1512 		 * filesystem may not be able to cope.
1513 		 */
1514 		if (error == 0 && VN_IS_DOOMED(uvp))
1515 			error = ENOENT;
1516 		if (error == 0)
1517 			error = VOP_RMDIR(udvp, uvp, cnp);
1518 	} else if (lvp != NULLVP)
1519 		error = unionfs_mkwhiteout(udvp, cnp, td,
1520 		    unp->un_path, unp->un_pathlen);
1521 
1522 	if (error == 0) {
1523 		cache_purge(ap->a_dvp);
1524 		cache_purge(ap->a_vp);
1525 	}
1526 
1527 	UNIONFS_INTERNAL_DEBUG("unionfs_rmdir: leave (%d)\n", error);
1528 
1529 	return (error);
1530 }
1531 
1532 static int
1533 unionfs_symlink(struct vop_symlink_args *ap)
1534 {
1535 	struct unionfs_node *dunp;
1536 	struct componentname *cnp;
1537 	struct vnode   *udvp;
1538 	struct vnode   *uvp;
1539 	int		error;
1540 	int		lkflags;
1541 
1542 	UNIONFS_INTERNAL_DEBUG("unionfs_symlink: enter\n");
1543 
1544 	KASSERT_UNIONFS_VNODE(ap->a_dvp);
1545 
1546 	error = EROFS;
1547 	dunp = VTOUNIONFS(ap->a_dvp);
1548 	cnp = ap->a_cnp;
1549 	lkflags = cnp->cn_lkflags;
1550 	udvp = dunp->un_uppervp;
1551 
1552 	if (udvp != NULLVP) {
1553 		error = VOP_SYMLINK(udvp, &uvp, cnp, ap->a_vap, ap->a_target);
1554 		if (error == 0) {
1555 			VOP_UNLOCK(uvp);
1556 			cnp->cn_lkflags = LK_EXCLUSIVE;
1557 			error = unionfs_nodeget(ap->a_dvp->v_mount, uvp, NULLVP,
1558 			    ap->a_dvp, ap->a_vpp, cnp);
1559 			cnp->cn_lkflags = lkflags;
1560 			vrele(uvp);
1561 		}
1562 	}
1563 
1564 	UNIONFS_INTERNAL_DEBUG("unionfs_symlink: leave (%d)\n", error);
1565 
1566 	return (error);
1567 }
1568 
1569 static int
1570 unionfs_readdir(struct vop_readdir_args *ap)
1571 {
1572 	struct unionfs_node *unp;
1573 	struct unionfs_node_status *unsp;
1574 	struct uio     *uio;
1575 	struct vnode   *vp;
1576 	struct vnode   *uvp;
1577 	struct vnode   *lvp;
1578 	struct thread  *td;
1579 	struct vattr    va;
1580 
1581 	uint64_t	*cookies_bk;
1582 	int		error;
1583 	int		eofflag;
1584 	int		ncookies_bk;
1585 	int		uio_offset_bk;
1586 	enum unionfs_lkupgrade lkstatus;
1587 
1588 	UNIONFS_INTERNAL_DEBUG("unionfs_readdir: enter\n");
1589 
1590 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1591 
1592 	error = 0;
1593 	eofflag = 0;
1594 	uio_offset_bk = 0;
1595 	uio = ap->a_uio;
1596 	uvp = NULLVP;
1597 	lvp = NULLVP;
1598 	td = uio->uio_td;
1599 	ncookies_bk = 0;
1600 	cookies_bk = NULL;
1601 
1602 	vp = ap->a_vp;
1603 	if (vp->v_type != VDIR)
1604 		return (ENOTDIR);
1605 
1606 	/*
1607 	 * If the vnode is reclaimed while upgrading, we can't safely use unp
1608 	 * or do anything else unionfs- specific.
1609 	 */
1610 	lkstatus = unionfs_upgrade_lock(vp);
1611 	if (lkstatus == UNIONFS_LKUPGRADE_DOOMED)
1612 		error = EBADF;
1613 	if (error == 0) {
1614 		unp = VTOUNIONFS(vp);
1615 		uvp = unp->un_uppervp;
1616 		lvp = unp->un_lowervp;
1617 		/* check the open count. unionfs needs open before readdir. */
1618 		unionfs_get_node_status(unp, td, &unsp);
1619 		if ((uvp != NULLVP && unsp->uns_upper_opencnt <= 0) ||
1620 			(lvp != NULLVP && unsp->uns_lower_opencnt <= 0)) {
1621 			unionfs_tryrem_node_status(unp, unsp);
1622 			error = EBADF;
1623 		}
1624 	}
1625 	unionfs_downgrade_lock(vp, lkstatus);
1626 	if (error != 0)
1627 		goto unionfs_readdir_exit;
1628 
1629 	/* check opaque */
1630 	if (uvp != NULLVP && lvp != NULLVP) {
1631 		if ((error = VOP_GETATTR(uvp, &va, ap->a_cred)) != 0)
1632 			goto unionfs_readdir_exit;
1633 		if (va.va_flags & OPAQUE)
1634 			lvp = NULLVP;
1635 	}
1636 
1637 	/* upper only */
1638 	if (uvp != NULLVP && lvp == NULLVP) {
1639 		error = VOP_READDIR(uvp, uio, ap->a_cred, ap->a_eofflag,
1640 		    ap->a_ncookies, ap->a_cookies);
1641 		unsp->uns_readdir_status = 0;
1642 
1643 		goto unionfs_readdir_exit;
1644 	}
1645 
1646 	/* lower only */
1647 	if (uvp == NULLVP && lvp != NULLVP) {
1648 		error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag,
1649 		    ap->a_ncookies, ap->a_cookies);
1650 		unsp->uns_readdir_status = 2;
1651 
1652 		goto unionfs_readdir_exit;
1653 	}
1654 
1655 	/*
1656 	 * readdir upper and lower
1657 	 */
1658 	KASSERT(uvp != NULLVP, ("unionfs_readdir: null upper vp"));
1659 	KASSERT(lvp != NULLVP, ("unionfs_readdir: null lower vp"));
1660 	if (uio->uio_offset == 0)
1661 		unsp->uns_readdir_status = 0;
1662 
1663 	if (unsp->uns_readdir_status == 0) {
1664 		/* read upper */
1665 		error = VOP_READDIR(uvp, uio, ap->a_cred, &eofflag,
1666 				    ap->a_ncookies, ap->a_cookies);
1667 
1668 		if (error != 0 || eofflag == 0)
1669 			goto unionfs_readdir_exit;
1670 		unsp->uns_readdir_status = 1;
1671 
1672 		/*
1673 		 * UFS(and other FS) needs size of uio_resid larger than
1674 		 * DIRBLKSIZ.
1675 		 * size of DIRBLKSIZ equals DEV_BSIZE.
1676 		 * (see: ufs/ufs/ufs_vnops.c ufs_readdir func , ufs/ufs/dir.h)
1677 		 */
1678 		if (uio->uio_resid <= (uio->uio_resid & (DEV_BSIZE -1)))
1679 			goto unionfs_readdir_exit;
1680 
1681 		/*
1682 		 * Backup cookies.
1683 		 * It prepares to readdir in lower.
1684 		 */
1685 		if (ap->a_ncookies != NULL) {
1686 			ncookies_bk = *(ap->a_ncookies);
1687 			*(ap->a_ncookies) = 0;
1688 		}
1689 		if (ap->a_cookies != NULL) {
1690 			cookies_bk = *(ap->a_cookies);
1691 			*(ap->a_cookies) = NULL;
1692 		}
1693 	}
1694 
1695 	/* initialize for readdir in lower */
1696 	if (unsp->uns_readdir_status == 1) {
1697 		unsp->uns_readdir_status = 2;
1698 		/*
1699 		 * Backup uio_offset. See the comment after the
1700 		 * VOP_READDIR call on the lower layer.
1701 		 */
1702 		uio_offset_bk = uio->uio_offset;
1703 		uio->uio_offset = 0;
1704 	}
1705 
1706 	if (lvp == NULLVP) {
1707 		error = EBADF;
1708 		goto unionfs_readdir_exit;
1709 	}
1710 	/* read lower */
1711 	error = VOP_READDIR(lvp, uio, ap->a_cred, ap->a_eofflag,
1712 			    ap->a_ncookies, ap->a_cookies);
1713 
1714 	/*
1715 	 * We can't return an uio_offset of 0: this would trigger an
1716 	 * infinite loop, because the next call to unionfs_readdir would
1717 	 * always restart with the upper layer (uio_offset == 0) and
1718 	 * always return some data.
1719 	 *
1720 	 * This happens when the lower layer root directory is removed.
1721 	 * (A root directory deleting of unionfs should not be permitted.
1722 	 *  But current VFS can not do it.)
1723 	 */
1724 	if (uio->uio_offset == 0)
1725 		uio->uio_offset = uio_offset_bk;
1726 
1727 	if (cookies_bk != NULL) {
1728 		/* merge cookies */
1729 		int		size;
1730 		uint64_t         *newcookies, *pos;
1731 
1732 		size = *(ap->a_ncookies) + ncookies_bk;
1733 		newcookies = (uint64_t *) malloc(size * sizeof(*newcookies),
1734 		    M_TEMP, M_WAITOK);
1735 		pos = newcookies;
1736 
1737 		memcpy(pos, cookies_bk, ncookies_bk * sizeof(*newcookies));
1738 		pos += ncookies_bk;
1739 		memcpy(pos, *(ap->a_cookies),
1740 		    *(ap->a_ncookies) * sizeof(*newcookies));
1741 		free(cookies_bk, M_TEMP);
1742 		free(*(ap->a_cookies), M_TEMP);
1743 		*(ap->a_ncookies) = size;
1744 		*(ap->a_cookies) = newcookies;
1745 	}
1746 
1747 unionfs_readdir_exit:
1748 	if (error != 0 && ap->a_eofflag != NULL)
1749 		*(ap->a_eofflag) = 1;
1750 
1751 	UNIONFS_INTERNAL_DEBUG("unionfs_readdir: leave (%d)\n", error);
1752 
1753 	return (error);
1754 }
1755 
1756 static int
1757 unionfs_readlink(struct vop_readlink_args *ap)
1758 {
1759 	struct unionfs_node *unp;
1760 	struct vnode   *vp;
1761 	int error;
1762 
1763 	UNIONFS_INTERNAL_DEBUG("unionfs_readlink: enter\n");
1764 
1765 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1766 
1767 	unp = VTOUNIONFS(ap->a_vp);
1768 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
1769 
1770 	error = VOP_READLINK(vp, ap->a_uio, ap->a_cred);
1771 
1772 	UNIONFS_INTERNAL_DEBUG("unionfs_readlink: leave (%d)\n", error);
1773 
1774 	return (error);
1775 }
1776 
1777 static int
1778 unionfs_getwritemount(struct vop_getwritemount_args *ap)
1779 {
1780 	struct unionfs_node *unp;
1781 	struct vnode   *uvp;
1782 	struct vnode   *vp, *ovp;
1783 	int		error;
1784 
1785 	UNIONFS_INTERNAL_DEBUG("unionfs_getwritemount: enter\n");
1786 
1787 	error = 0;
1788 	vp = ap->a_vp;
1789 	uvp = NULLVP;
1790 
1791 	VI_LOCK(vp);
1792 	unp = VTOUNIONFS(vp);
1793 	if (unp != NULL)
1794 		uvp = unp->un_uppervp;
1795 
1796 	/*
1797 	 * If our node has no upper vnode, check the parent directory.
1798 	 * We may be initiating a write operation that will produce a
1799 	 * new upper vnode through CoW.
1800 	 */
1801 	if (uvp == NULLVP && unp != NULL) {
1802 		ovp = vp;
1803 		vp = unp->un_dvp;
1804 		/*
1805 		 * Only the root vnode should have an empty parent, but it
1806 		 * should not have an empty uppervp, so we shouldn't get here.
1807 		 */
1808 		VNASSERT(vp != NULL, ovp, ("%s: NULL parent vnode", __func__));
1809 		VI_UNLOCK(ovp);
1810 		VI_LOCK(vp);
1811 		unp = VTOUNIONFS(vp);
1812 		if (unp != NULL)
1813 			uvp = unp->un_uppervp;
1814 		if (uvp == NULLVP)
1815 			error = EACCES;
1816 	}
1817 
1818 	if (uvp != NULLVP) {
1819 		vholdnz(uvp);
1820 		VI_UNLOCK(vp);
1821 		error = VOP_GETWRITEMOUNT(uvp, ap->a_mpp);
1822 		vdrop(uvp);
1823 	} else {
1824 		VI_UNLOCK(vp);
1825 		*(ap->a_mpp) = NULL;
1826 	}
1827 
1828 	UNIONFS_INTERNAL_DEBUG("unionfs_getwritemount: leave (%d)\n", error);
1829 
1830 	return (error);
1831 }
1832 
1833 static int
1834 unionfs_inactive(struct vop_inactive_args *ap)
1835 {
1836 	ap->a_vp->v_object = NULL;
1837 	vrecycle(ap->a_vp);
1838 	return (0);
1839 }
1840 
1841 static int
1842 unionfs_reclaim(struct vop_reclaim_args *ap)
1843 {
1844 	/* UNIONFS_INTERNAL_DEBUG("unionfs_reclaim: enter\n"); */
1845 
1846 	unionfs_noderem(ap->a_vp);
1847 
1848 	/* UNIONFS_INTERNAL_DEBUG("unionfs_reclaim: leave\n"); */
1849 
1850 	return (0);
1851 }
1852 
1853 static int
1854 unionfs_print(struct vop_print_args *ap)
1855 {
1856 	struct unionfs_node *unp;
1857 	/* struct unionfs_node_status *unsp; */
1858 
1859 	unp = VTOUNIONFS(ap->a_vp);
1860 	/* unionfs_get_node_status(unp, curthread, &unsp); */
1861 
1862 	printf("unionfs_vp=%p, uppervp=%p, lowervp=%p\n",
1863 	    ap->a_vp, unp->un_uppervp, unp->un_lowervp);
1864 	/*
1865 	printf("unionfs opencnt: uppervp=%d, lowervp=%d\n",
1866 	    unsp->uns_upper_opencnt, unsp->uns_lower_opencnt);
1867 	*/
1868 
1869 	if (unp->un_uppervp != NULLVP)
1870 		vn_printf(unp->un_uppervp, "unionfs: upper ");
1871 	if (unp->un_lowervp != NULLVP)
1872 		vn_printf(unp->un_lowervp, "unionfs: lower ");
1873 
1874 	return (0);
1875 }
1876 
1877 static int
1878 unionfs_get_llt_revlock(struct vnode *vp, int flags)
1879 {
1880 	int revlock;
1881 
1882 	revlock = 0;
1883 
1884 	switch (flags & LK_TYPE_MASK) {
1885 	case LK_SHARED:
1886 		if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE)
1887 			revlock = LK_UPGRADE;
1888 		else
1889 			revlock = LK_RELEASE;
1890 		break;
1891 	case LK_EXCLUSIVE:
1892 	case LK_UPGRADE:
1893 		revlock = LK_RELEASE;
1894 		break;
1895 	case LK_DOWNGRADE:
1896 		revlock = LK_UPGRADE;
1897 		break;
1898 	default:
1899 		break;
1900 	}
1901 
1902 	return (revlock);
1903 }
1904 
1905 /*
1906  * The state of an acquired lock is adjusted similarly to
1907  * the time of error generating.
1908  * flags: LK_RELEASE or LK_UPGRADE
1909  */
1910 static void
1911 unionfs_revlock(struct vnode *vp, int flags)
1912 {
1913 	if (flags & LK_RELEASE)
1914 		VOP_UNLOCK_FLAGS(vp, flags);
1915 	else {
1916 		/* UPGRADE */
1917 		if (vn_lock(vp, flags) != 0)
1918 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1919 	}
1920 }
1921 
1922 static int
1923 unionfs_lock(struct vop_lock1_args *ap)
1924 {
1925 	struct unionfs_node *unp;
1926 	struct vnode   *vp;
1927 	struct vnode   *uvp;
1928 	struct vnode   *lvp;
1929 	int		error;
1930 	int		flags;
1931 	int		revlock;
1932 	int		interlock;
1933 	int		uhold;
1934 
1935 	/*
1936 	 * TODO: rework the unionfs locking scheme.
1937 	 * It's not guaranteed to be safe to blindly lock two vnodes on
1938 	 * different mounts as is done here.  Further, the entanglement
1939 	 * of locking both vnodes with the various options that can be
1940 	 * passed to VOP_LOCK() makes this code hard to reason about.
1941 	 * Instead, consider locking only the upper vnode, or the lower
1942 	 * vnode is the upper is not present, and taking separate measures
1943 	 * to lock both vnodes in the few cases when that is needed.
1944 	 */
1945 	error = 0;
1946 	interlock = 1;
1947 	uhold = 0;
1948 	flags = ap->a_flags;
1949 	vp = ap->a_vp;
1950 
1951 	if (LK_RELEASE == (flags & LK_TYPE_MASK) || !(flags & LK_TYPE_MASK))
1952 		return (VOP_UNLOCK_FLAGS(vp, flags | LK_RELEASE));
1953 
1954 	if ((flags & LK_INTERLOCK) == 0)
1955 		VI_LOCK(vp);
1956 
1957 	unp = VTOUNIONFS(vp);
1958 	if (unp == NULL)
1959 		goto unionfs_lock_null_vnode;
1960 
1961 	KASSERT_UNIONFS_VNODE(ap->a_vp);
1962 
1963 	lvp = unp->un_lowervp;
1964 	uvp = unp->un_uppervp;
1965 
1966 	if ((revlock = unionfs_get_llt_revlock(vp, flags)) == 0)
1967 		panic("unknown lock type: 0x%x", flags & LK_TYPE_MASK);
1968 
1969 	/*
1970 	 * During unmount, the root vnode lock may be taken recursively,
1971 	 * because it may share the same v_vnlock field as the vnode covered by
1972 	 * the unionfs mount.  The covered vnode is locked across VFS_UNMOUNT(),
1973 	 * and the same lock may be taken recursively here during vflush()
1974 	 * issued by unionfs_unmount().
1975 	 */
1976 	if ((flags & LK_TYPE_MASK) == LK_EXCLUSIVE &&
1977 	    (vp->v_vflag & VV_ROOT) != 0)
1978 		flags |= LK_CANRECURSE;
1979 
1980 	if (lvp != NULLVP) {
1981 		if (uvp != NULLVP && flags & LK_UPGRADE) {
1982 			/*
1983 			 * Share Lock is once released and a deadlock is
1984 			 * avoided.
1985 			 */
1986 			vholdnz(uvp);
1987 			uhold = 1;
1988 			VOP_UNLOCK(uvp);
1989 		}
1990 		VI_LOCK_FLAGS(lvp, MTX_DUPOK);
1991 		flags |= LK_INTERLOCK;
1992 		vholdl(lvp);
1993 
1994 		VI_UNLOCK(vp);
1995 		ap->a_flags &= ~LK_INTERLOCK;
1996 
1997 		error = VOP_LOCK(lvp, flags);
1998 
1999 		VI_LOCK(vp);
2000 		unp = VTOUNIONFS(vp);
2001 		if (unp == NULL) {
2002 			/* vnode is released. */
2003 			VI_UNLOCK(vp);
2004 			if (error == 0)
2005 				VOP_UNLOCK(lvp);
2006 			vdrop(lvp);
2007 			if (uhold != 0)
2008 				vdrop(uvp);
2009 			goto unionfs_lock_fallback;
2010 		}
2011 	}
2012 
2013 	if (error == 0 && uvp != NULLVP) {
2014 		if (uhold && flags & LK_UPGRADE) {
2015 			flags &= ~LK_TYPE_MASK;
2016 			flags |= LK_EXCLUSIVE;
2017 		}
2018 		VI_LOCK_FLAGS(uvp, MTX_DUPOK);
2019 		flags |= LK_INTERLOCK;
2020 		if (uhold == 0) {
2021 			vholdl(uvp);
2022 			uhold = 1;
2023 		}
2024 
2025 		VI_UNLOCK(vp);
2026 		ap->a_flags &= ~LK_INTERLOCK;
2027 
2028 		error = VOP_LOCK(uvp, flags);
2029 
2030 		VI_LOCK(vp);
2031 		unp = VTOUNIONFS(vp);
2032 		if (unp == NULL) {
2033 			/* vnode is released. */
2034 			VI_UNLOCK(vp);
2035 			if (error == 0)
2036 				VOP_UNLOCK(uvp);
2037 			vdrop(uvp);
2038 			if (lvp != NULLVP) {
2039 				VOP_UNLOCK(lvp);
2040 				vdrop(lvp);
2041 			}
2042 			goto unionfs_lock_fallback;
2043 		}
2044 		if (error != 0 && lvp != NULLVP) {
2045 			/* rollback */
2046 			VI_UNLOCK(vp);
2047 			unionfs_revlock(lvp, revlock);
2048 			interlock = 0;
2049 		}
2050 	}
2051 
2052 	if (interlock)
2053 		VI_UNLOCK(vp);
2054 	if (lvp != NULLVP)
2055 		vdrop(lvp);
2056 	if (uhold != 0)
2057 		vdrop(uvp);
2058 
2059 	return (error);
2060 
2061 unionfs_lock_null_vnode:
2062 	ap->a_flags |= LK_INTERLOCK;
2063 	return (vop_stdlock(ap));
2064 
2065 unionfs_lock_fallback:
2066 	/*
2067 	 * If we reach this point, we've discovered the unionfs vnode
2068 	 * has been reclaimed while the upper/lower vnode locks were
2069 	 * temporarily dropped.  Such temporary droppage may happen
2070 	 * during the course of an LK_UPGRADE operation itself, and in
2071 	 * that case LK_UPGRADE must be cleared as the unionfs vnode's
2072 	 * lock has been reset to point to the standard v_lock field,
2073 	 * which has not previously been held.
2074 	 */
2075 	if (flags & LK_UPGRADE) {
2076 		ap->a_flags &= ~LK_TYPE_MASK;
2077 		ap->a_flags |= LK_EXCLUSIVE;
2078 	}
2079 	return (vop_stdlock(ap));
2080 }
2081 
2082 static int
2083 unionfs_unlock(struct vop_unlock_args *ap)
2084 {
2085 	struct vnode   *vp;
2086 	struct vnode   *lvp;
2087 	struct vnode   *uvp;
2088 	struct unionfs_node *unp;
2089 	int		error;
2090 	int		uhold;
2091 
2092 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2093 
2094 	error = 0;
2095 	uhold = 0;
2096 	vp = ap->a_vp;
2097 
2098 	unp = VTOUNIONFS(vp);
2099 	if (unp == NULL)
2100 		goto unionfs_unlock_null_vnode;
2101 	lvp = unp->un_lowervp;
2102 	uvp = unp->un_uppervp;
2103 
2104 	if (lvp != NULLVP) {
2105 		vholdnz(lvp);
2106 		error = VOP_UNLOCK(lvp);
2107 	}
2108 
2109 	if (error == 0 && uvp != NULLVP) {
2110 		vholdnz(uvp);
2111 		uhold = 1;
2112 		error = VOP_UNLOCK(uvp);
2113 	}
2114 
2115 	if (lvp != NULLVP)
2116 		vdrop(lvp);
2117 	if (uhold != 0)
2118 		vdrop(uvp);
2119 
2120 	return error;
2121 
2122 unionfs_unlock_null_vnode:
2123 	return (vop_stdunlock(ap));
2124 }
2125 
2126 static int
2127 unionfs_pathconf(struct vop_pathconf_args *ap)
2128 {
2129 	struct unionfs_node *unp;
2130 	struct vnode   *vp;
2131 
2132 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2133 
2134 	unp = VTOUNIONFS(ap->a_vp);
2135 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2136 
2137 	return (VOP_PATHCONF(vp, ap->a_name, ap->a_retval));
2138 }
2139 
2140 static int
2141 unionfs_advlock(struct vop_advlock_args *ap)
2142 {
2143 	struct unionfs_node *unp;
2144 	struct unionfs_node_status *unsp;
2145 	struct vnode   *vp;
2146 	struct vnode   *uvp;
2147 	struct thread  *td;
2148 	int error;
2149 
2150 	UNIONFS_INTERNAL_DEBUG("unionfs_advlock: enter\n");
2151 
2152 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2153 
2154 	vp = ap->a_vp;
2155 	td = curthread;
2156 
2157 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2158 
2159 	unp = VTOUNIONFS(ap->a_vp);
2160 	uvp = unp->un_uppervp;
2161 
2162 	if (uvp == NULLVP) {
2163 		error = unionfs_copyfile(unp, 1, td->td_ucred, td);
2164 		if (error != 0)
2165 			goto unionfs_advlock_abort;
2166 		uvp = unp->un_uppervp;
2167 
2168 		unionfs_get_node_status(unp, td, &unsp);
2169 		if (unsp->uns_lower_opencnt > 0) {
2170 			/* try reopen the vnode */
2171 			error = VOP_OPEN(uvp, unsp->uns_lower_openmode,
2172 				td->td_ucred, td, NULL);
2173 			if (error)
2174 				goto unionfs_advlock_abort;
2175 			unsp->uns_upper_opencnt++;
2176 			VOP_CLOSE(unp->un_lowervp, unsp->uns_lower_openmode,
2177 			    td->td_ucred, td);
2178 			unsp->uns_lower_opencnt--;
2179 		} else
2180 			unionfs_tryrem_node_status(unp, unsp);
2181 	}
2182 
2183 	VOP_UNLOCK(vp);
2184 
2185 	error = VOP_ADVLOCK(uvp, ap->a_id, ap->a_op, ap->a_fl, ap->a_flags);
2186 
2187 	UNIONFS_INTERNAL_DEBUG("unionfs_advlock: leave (%d)\n", error);
2188 
2189 	return error;
2190 
2191 unionfs_advlock_abort:
2192 	VOP_UNLOCK(vp);
2193 
2194 	UNIONFS_INTERNAL_DEBUG("unionfs_advlock: leave (%d)\n", error);
2195 
2196 	return error;
2197 }
2198 
2199 static int
2200 unionfs_strategy(struct vop_strategy_args *ap)
2201 {
2202 	struct unionfs_node *unp;
2203 	struct vnode   *vp;
2204 
2205 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2206 
2207 	unp = VTOUNIONFS(ap->a_vp);
2208 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2209 
2210 #ifdef DIAGNOSTIC
2211 	if (vp == NULLVP)
2212 		panic("unionfs_strategy: nullvp");
2213 
2214 	if (ap->a_bp->b_iocmd == BIO_WRITE && vp == unp->un_lowervp)
2215 		panic("unionfs_strategy: writing to lowervp");
2216 #endif
2217 
2218 	return (VOP_STRATEGY(vp, ap->a_bp));
2219 }
2220 
2221 static int
2222 unionfs_getacl(struct vop_getacl_args *ap)
2223 {
2224 	struct unionfs_node *unp;
2225 	struct vnode   *vp;
2226 	int		error;
2227 
2228 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2229 
2230 	unp = VTOUNIONFS(ap->a_vp);
2231 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2232 
2233 	UNIONFS_INTERNAL_DEBUG("unionfs_getacl: enter\n");
2234 
2235 	error = VOP_GETACL(vp, ap->a_type, ap->a_aclp, ap->a_cred, ap->a_td);
2236 
2237 	UNIONFS_INTERNAL_DEBUG("unionfs_getacl: leave (%d)\n", error);
2238 
2239 	return (error);
2240 }
2241 
2242 static int
2243 unionfs_setacl(struct vop_setacl_args *ap)
2244 {
2245 	struct unionfs_node *unp;
2246 	struct vnode   *uvp;
2247 	struct vnode   *lvp;
2248 	struct thread  *td;
2249 	int		error;
2250 
2251 	UNIONFS_INTERNAL_DEBUG("unionfs_setacl: enter\n");
2252 
2253 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2254 
2255 	error = EROFS;
2256 	unp = VTOUNIONFS(ap->a_vp);
2257 	uvp = unp->un_uppervp;
2258 	lvp = unp->un_lowervp;
2259 	td = ap->a_td;
2260 
2261 	if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
2262 		return (EROFS);
2263 
2264 	if (uvp == NULLVP && lvp->v_type == VREG) {
2265 		if ((error = unionfs_copyfile(unp, 1, ap->a_cred, td)) != 0)
2266 			return (error);
2267 		uvp = unp->un_uppervp;
2268 	}
2269 
2270 	if (uvp != NULLVP)
2271 		error = VOP_SETACL(uvp, ap->a_type, ap->a_aclp, ap->a_cred, td);
2272 
2273 	UNIONFS_INTERNAL_DEBUG("unionfs_setacl: leave (%d)\n", error);
2274 
2275 	return (error);
2276 }
2277 
2278 static int
2279 unionfs_aclcheck(struct vop_aclcheck_args *ap)
2280 {
2281 	struct unionfs_node *unp;
2282 	struct vnode   *vp;
2283 	int		error;
2284 
2285 	UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: enter\n");
2286 
2287 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2288 
2289 	unp = VTOUNIONFS(ap->a_vp);
2290 	vp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2291 
2292 	error = VOP_ACLCHECK(vp, ap->a_type, ap->a_aclp, ap->a_cred, ap->a_td);
2293 
2294 	UNIONFS_INTERNAL_DEBUG("unionfs_aclcheck: leave (%d)\n", error);
2295 
2296 	return (error);
2297 }
2298 
2299 static int
2300 unionfs_openextattr(struct vop_openextattr_args *ap)
2301 {
2302 	struct unionfs_node *unp;
2303 	struct vnode   *vp;
2304 	struct vnode   *tvp;
2305 	int		error;
2306 
2307 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2308 
2309 	vp = ap->a_vp;
2310 	unp = VTOUNIONFS(vp);
2311 	tvp = (unp->un_uppervp != NULLVP ? unp->un_uppervp : unp->un_lowervp);
2312 
2313 	if ((tvp == unp->un_uppervp && (unp->un_flag & UNIONFS_OPENEXTU)) ||
2314 	    (tvp == unp->un_lowervp && (unp->un_flag & UNIONFS_OPENEXTL)))
2315 		return (EBUSY);
2316 
2317 	error = VOP_OPENEXTATTR(tvp, ap->a_cred, ap->a_td);
2318 
2319 	if (error == 0) {
2320 		if (vn_lock(vp, LK_UPGRADE) != 0)
2321 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2322 		if (!VN_IS_DOOMED(vp)) {
2323 			if (tvp == unp->un_uppervp)
2324 				unp->un_flag |= UNIONFS_OPENEXTU;
2325 			else
2326 				unp->un_flag |= UNIONFS_OPENEXTL;
2327 		}
2328 		vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
2329 	}
2330 
2331 	return (error);
2332 }
2333 
2334 static int
2335 unionfs_closeextattr(struct vop_closeextattr_args *ap)
2336 {
2337 	struct unionfs_node *unp;
2338 	struct vnode   *vp;
2339 	struct vnode   *tvp;
2340 	int		error;
2341 
2342 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2343 
2344 	vp = ap->a_vp;
2345 	unp = VTOUNIONFS(vp);
2346 	tvp = NULLVP;
2347 
2348 	if (unp->un_flag & UNIONFS_OPENEXTU)
2349 		tvp = unp->un_uppervp;
2350 	else if (unp->un_flag & UNIONFS_OPENEXTL)
2351 		tvp = unp->un_lowervp;
2352 
2353 	if (tvp == NULLVP)
2354 		return (EOPNOTSUPP);
2355 
2356 	error = VOP_CLOSEEXTATTR(tvp, ap->a_commit, ap->a_cred, ap->a_td);
2357 
2358 	if (error == 0) {
2359 		if (vn_lock(vp, LK_UPGRADE) != 0)
2360 			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2361 		if (!VN_IS_DOOMED(vp)) {
2362 			if (tvp == unp->un_uppervp)
2363 				unp->un_flag &= ~UNIONFS_OPENEXTU;
2364 			else
2365 				unp->un_flag &= ~UNIONFS_OPENEXTL;
2366 		}
2367 		vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
2368 	}
2369 
2370 	return (error);
2371 }
2372 
2373 static int
2374 unionfs_getextattr(struct vop_getextattr_args *ap)
2375 {
2376 	struct unionfs_node *unp;
2377 	struct vnode   *vp;
2378 
2379 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2380 
2381 	unp = VTOUNIONFS(ap->a_vp);
2382 	vp = NULLVP;
2383 
2384 	if (unp->un_flag & UNIONFS_OPENEXTU)
2385 		vp = unp->un_uppervp;
2386 	else if (unp->un_flag & UNIONFS_OPENEXTL)
2387 		vp = unp->un_lowervp;
2388 
2389 	if (vp == NULLVP)
2390 		return (EOPNOTSUPP);
2391 
2392 	return (VOP_GETEXTATTR(vp, ap->a_attrnamespace, ap->a_name,
2393 	    ap->a_uio, ap->a_size, ap->a_cred, ap->a_td));
2394 }
2395 
2396 static int
2397 unionfs_setextattr(struct vop_setextattr_args *ap)
2398 {
2399 	struct unionfs_node *unp;
2400 	struct vnode   *uvp;
2401 	struct vnode   *lvp;
2402 	struct vnode   *ovp;
2403 	struct ucred   *cred;
2404 	struct thread  *td;
2405 	int		error;
2406 
2407 	KASSERT_UNIONFS_VNODE(ap->a_vp);
2408 
2409 	error = EROFS;
2410 	unp = VTOUNIONFS(ap->a_vp);
2411 	uvp = unp->un_uppervp;
2412 	lvp = unp->un_lowervp;
2413 	ovp = NULLVP;
2414 	cred = ap->a_cred;
2415 	td = ap->a_td;
2416 
2417 	UNIONFS_INTERNAL_DEBUG("unionfs_setextattr: enter (un_flag=%x)\n",
2418 	    unp->un_flag);
2419 
2420 	if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
2421 		return (EROFS);
2422 
2423 	if (unp->un_flag & UNIONFS_OPENEXTU)
2424 		ovp = unp->un_uppervp;
2425 	else if (unp->un_flag & UNIONFS_OPENEXTL)
2426 		ovp = unp->un_lowervp;
2427 
2428 	if (ovp == NULLVP)
2429 		return (EOPNOTSUPP);
2430 
2431 	if (ovp == lvp && lvp->v_type == VREG) {
2432 		VOP_CLOSEEXTATTR(lvp, 0, cred, td);
2433 		if (uvp == NULLVP &&
2434 		    (error = unionfs_copyfile(unp, 1, cred, td)) != 0) {
2435 unionfs_setextattr_reopen:
2436 			if ((unp->un_flag & UNIONFS_OPENEXTL) &&
2437 			    VOP_OPENEXTATTR(lvp, cred, td)) {
2438 #ifdef DIAGNOSTIC
2439 				panic("unionfs: VOP_OPENEXTATTR failed");
2440 #endif
2441 				unp->un_flag &= ~UNIONFS_OPENEXTL;
2442 			}
2443 			goto unionfs_setextattr_abort;
2444 		}
2445 		uvp = unp->un_uppervp;
2446 		if ((error = VOP_OPENEXTATTR(uvp, cred, td)) != 0)
2447 			goto unionfs_setextattr_reopen;
2448 		unp->un_flag &= ~UNIONFS_OPENEXTL;
2449 		unp->un_flag |= UNIONFS_OPENEXTU;
2450 		ovp = uvp;
2451 	}
2452 
2453 	if (ovp == uvp)
2454 		error = VOP_SETEXTATTR(ovp, ap->a_attrnamespace, ap->a_name,
2455 		    ap->a_uio, cred, td);
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 struct vop_vector unionfs_vnodeops = {
2779 	.vop_default =		&default_vnodeops,
2780 
2781 	.vop_access =		unionfs_access,
2782 	.vop_aclcheck =		unionfs_aclcheck,
2783 	.vop_advlock =		unionfs_advlock,
2784 	.vop_bmap =		VOP_EOPNOTSUPP,
2785 	.vop_cachedlookup =	unionfs_lookup,
2786 	.vop_close =		unionfs_close,
2787 	.vop_closeextattr =	unionfs_closeextattr,
2788 	.vop_create =		unionfs_create,
2789 	.vop_deleteextattr =	unionfs_deleteextattr,
2790 	.vop_fsync =		unionfs_fsync,
2791 	.vop_getacl =		unionfs_getacl,
2792 	.vop_getattr =		unionfs_getattr,
2793 	.vop_getextattr =	unionfs_getextattr,
2794 	.vop_getwritemount =	unionfs_getwritemount,
2795 	.vop_inactive =		unionfs_inactive,
2796 	.vop_need_inactive =	vop_stdneed_inactive,
2797 	.vop_islocked =		vop_stdislocked,
2798 	.vop_ioctl =		unionfs_ioctl,
2799 	.vop_link =		unionfs_link,
2800 	.vop_listextattr =	unionfs_listextattr,
2801 	.vop_lock1 =		unionfs_lock,
2802 	.vop_lookup =		vfs_cache_lookup,
2803 	.vop_mkdir =		unionfs_mkdir,
2804 	.vop_mknod =		unionfs_mknod,
2805 	.vop_open =		unionfs_open,
2806 	.vop_openextattr =	unionfs_openextattr,
2807 	.vop_pathconf =		unionfs_pathconf,
2808 	.vop_poll =		unionfs_poll,
2809 	.vop_print =		unionfs_print,
2810 	.vop_read =		unionfs_read,
2811 	.vop_readdir =		unionfs_readdir,
2812 	.vop_readlink =		unionfs_readlink,
2813 	.vop_reclaim =		unionfs_reclaim,
2814 	.vop_remove =		unionfs_remove,
2815 	.vop_rename =		unionfs_rename,
2816 	.vop_rmdir =		unionfs_rmdir,
2817 	.vop_setacl =		unionfs_setacl,
2818 	.vop_setattr =		unionfs_setattr,
2819 	.vop_setextattr =	unionfs_setextattr,
2820 	.vop_setlabel =		unionfs_setlabel,
2821 	.vop_strategy =		unionfs_strategy,
2822 	.vop_symlink =		unionfs_symlink,
2823 	.vop_unlock =		unionfs_unlock,
2824 	.vop_whiteout =		unionfs_whiteout,
2825 	.vop_write =		unionfs_write,
2826 	.vop_vptofh =		unionfs_vptofh,
2827 	.vop_add_writecount =	unionfs_add_writecount,
2828 	.vop_vput_pair =	unionfs_vput_pair,
2829 	.vop_set_text =		unionfs_set_text,
2830 	.vop_unset_text = 	unionfs_unset_text,
2831 };
2832 VFS_VOP_VECTOR_REGISTER(unionfs_vnodeops);
2833