xref: /freebsd/sys/fs/unionfs/union_subr.c (revision 6c6c03be2ddb04c54e455122799923deaefa4114)
1 /*-
2  * Copyright (c) 1994 Jan-Simon Pendry
3  * Copyright (c) 1994
4  *	The Regents of the University of California.  All rights reserved.
5  * Copyright (c) 2005, 2006 Masanori Ozawa <ozawa@ongs.co.jp>, ONGS Inc.
6  * Copyright (c) 2006 Daichi Goto <daichi@freebsd.org>
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Jan-Simon Pendry.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)union_subr.c	8.20 (Berkeley) 5/20/95
36  * $FreeBSD$
37  */
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/lock.h>
43 #include <sys/mutex.h>
44 #include <sys/malloc.h>
45 #include <sys/mount.h>
46 #include <sys/namei.h>
47 #include <sys/proc.h>
48 #include <sys/vnode.h>
49 #include <sys/dirent.h>
50 #include <sys/fcntl.h>
51 #include <sys/filedesc.h>
52 #include <sys/stat.h>
53 #include <sys/resourcevar.h>
54 
55 #ifdef MAC
56 #include <sys/mac.h>
57 #endif
58 
59 #include <vm/uma.h>
60 
61 #include <fs/unionfs/union.h>
62 
63 #define NUNIONFSNODECACHE 16
64 
65 static MALLOC_DEFINE(M_UNIONFSHASH, "UNIONFS hash", "UNIONFS hash table");
66 MALLOC_DEFINE(M_UNIONFSNODE, "UNIONFS node", "UNIONFS vnode private part");
67 MALLOC_DEFINE(M_UNIONFSPATH, "UNIONFS path", "UNIONFS path private part");
68 
69 /*
70  * Initialize
71  */
72 int
73 unionfs_init(struct vfsconf *vfsp)
74 {
75 	UNIONFSDEBUG("unionfs_init\n");	/* printed during system boot */
76 	return (0);
77 }
78 
79 /*
80  * Uninitialize
81  */
82 int
83 unionfs_uninit(struct vfsconf *vfsp)
84 {
85 	return (0);
86 }
87 
88 static struct unionfs_node_hashhead *
89 unionfs_get_hashhead(struct vnode *dvp, char *path)
90 {
91 	int		count;
92 	char		hash;
93 	struct unionfs_node *unp;
94 
95 	hash = 0;
96 	unp = VTOUNIONFS(dvp);
97 	if (path != NULL) {
98 		for (count = 0; path[count]; count++)
99 			hash += path[count];
100 	}
101 
102 	return (&(unp->un_hashtbl[hash & (unp->un_hashmask)]));
103 }
104 
105 /*
106  * Get the cached vnode.
107  */
108 static struct vnode *
109 unionfs_get_cached_vnode(struct vnode *uvp, struct vnode *lvp,
110 			struct vnode *dvp, char *path)
111 {
112 	struct unionfs_node_hashhead *hd;
113 	struct unionfs_node *unp;
114 	struct vnode   *vp;
115 
116 	KASSERT((uvp == NULLVP || uvp->v_type == VDIR || uvp->v_type == VSOCK),
117 	    ("unionfs_get_cached_vnode: v_type != VDIR/VSOCK"));
118 	KASSERT((lvp == NULLVP || lvp->v_type == VDIR || lvp->v_type == VSOCK),
119 	    ("unionfs_get_cached_vnode: v_type != VDIR/VSOCK"));
120 
121 	VI_LOCK(dvp);
122 	hd = unionfs_get_hashhead(dvp, path);
123 	LIST_FOREACH(unp, hd, un_hash) {
124 		if (!strcmp(unp->un_path, path)) {
125 			vp = UNIONFSTOV(unp);
126 			VI_LOCK_FLAGS(vp, MTX_DUPOK);
127 			VI_UNLOCK(dvp);
128 			vp->v_iflag &= ~VI_OWEINACT;
129 			if ((vp->v_iflag & (VI_DOOMED | VI_DOINGINACT)) != 0) {
130 				VI_UNLOCK(vp);
131 				vp = NULLVP;
132 			} else
133 				VI_UNLOCK(vp);
134 			return (vp);
135 		}
136 	}
137 	VI_UNLOCK(dvp);
138 
139 	return (NULLVP);
140 }
141 
142 /*
143  * Add the new vnode into cache.
144  */
145 static struct vnode *
146 unionfs_ins_cached_vnode(struct unionfs_node *uncp,
147 			struct vnode *dvp, char *path)
148 {
149 	struct unionfs_node_hashhead *hd;
150 	struct unionfs_node *unp;
151 	struct vnode   *vp;
152 
153 	KASSERT((uncp->un_uppervp==NULLVP || uncp->un_uppervp->v_type==VDIR ||
154 	    uncp->un_uppervp->v_type==VSOCK),
155 	    ("unionfs_ins_cached_vnode: v_type != VDIR/VSOCK"));
156 	KASSERT((uncp->un_lowervp==NULLVP || uncp->un_lowervp->v_type==VDIR ||
157 	    uncp->un_lowervp->v_type==VSOCK),
158 	    ("unionfs_ins_cached_vnode: v_type != VDIR/VSOCK"));
159 
160 	VI_LOCK(dvp);
161 	hd = unionfs_get_hashhead(dvp, path);
162 	LIST_FOREACH(unp, hd, un_hash) {
163 		if (!strcmp(unp->un_path, path)) {
164 			vp = UNIONFSTOV(unp);
165 			VI_LOCK_FLAGS(vp, MTX_DUPOK);
166 			vp->v_iflag &= ~VI_OWEINACT;
167 			if ((vp->v_iflag & (VI_DOOMED | VI_DOINGINACT)) != 0) {
168 				LIST_INSERT_HEAD(hd, uncp, un_hash);
169 				VI_UNLOCK(vp);
170 				vp = NULLVP;
171 			} else
172 				VI_UNLOCK(vp);
173 			VI_UNLOCK(dvp);
174 			return (vp);
175 		}
176 	}
177 
178 	LIST_INSERT_HEAD(hd, uncp, un_hash);
179 	VI_UNLOCK(dvp);
180 
181 	return (NULLVP);
182 }
183 
184 /*
185  * Remove the vnode.
186  */
187 static void
188 unionfs_rem_cached_vnode(struct unionfs_node *unp, struct vnode *dvp)
189 {
190 	KASSERT((unp != NULL), ("unionfs_rem_cached_vnode: null node"));
191 	KASSERT((dvp != NULLVP),
192 	    ("unionfs_rem_cached_vnode: null parent vnode"));
193 	KASSERT((unp->un_hash.le_prev != NULL),
194 	    ("unionfs_rem_cached_vnode: null hash"));
195 
196 	VI_LOCK(dvp);
197 	LIST_REMOVE(unp, un_hash);
198 	unp->un_hash.le_next = NULL;
199 	unp->un_hash.le_prev = NULL;
200 	VI_UNLOCK(dvp);
201 }
202 
203 /*
204  * Make a new or get existing unionfs node.
205  *
206  * uppervp and lowervp should be unlocked. Because if new unionfs vnode is
207  * locked, uppervp or lowervp is locked too. In order to prevent dead lock,
208  * you should not lock plurality simultaneously.
209  */
210 int
211 unionfs_nodeget(struct mount *mp, struct vnode *uppervp,
212 		struct vnode *lowervp, struct vnode *dvp,
213 		struct vnode **vpp, struct componentname *cnp,
214 		struct thread *td)
215 {
216 	struct unionfs_mount *ump;
217 	struct unionfs_node *unp;
218 	struct vnode   *vp;
219 	int		error;
220 	int		lkflags;
221 	enum vtype	vt;
222 	char	       *path;
223 
224 	ump = MOUNTTOUNIONFSMOUNT(mp);
225 	lkflags = (cnp ? cnp->cn_lkflags : 0);
226 	path = (cnp ? cnp->cn_nameptr : NULL);
227 	*vpp = NULLVP;
228 
229 	if (uppervp == NULLVP && lowervp == NULLVP)
230 		panic("unionfs_nodeget: upper and lower is null");
231 
232 	vt = (uppervp != NULLVP ? uppervp->v_type : lowervp->v_type);
233 
234 	/* If it has no ISLASTCN flag, path check is skipped. */
235 	if (cnp && !(cnp->cn_flags & ISLASTCN))
236 		path = NULL;
237 
238 	/* check the cache */
239 	if (path != NULL && dvp != NULLVP && (vt == VDIR || vt == VSOCK)) {
240 		vp = unionfs_get_cached_vnode(uppervp, lowervp, dvp, path);
241 		if (vp != NULLVP) {
242 			vref(vp);
243 			*vpp = vp;
244 			goto unionfs_nodeget_out;
245 		}
246 	}
247 
248 	if ((uppervp == NULLVP || ump->um_uppervp != uppervp) ||
249 	    (lowervp == NULLVP || ump->um_lowervp != lowervp)) {
250 		/* dvp will be NULLVP only in case of root vnode. */
251 		if (dvp == NULLVP)
252 			return (EINVAL);
253 	}
254 
255 	/*
256 	 * Do the MALLOC before the getnewvnode since doing so afterward
257 	 * might cause a bogus v_data pointer to get dereferenced elsewhere
258 	 * if MALLOC should block.
259 	 */
260 	unp = malloc(sizeof(struct unionfs_node),
261 	    M_UNIONFSNODE, M_WAITOK | M_ZERO);
262 
263 	error = getnewvnode("unionfs", mp, &unionfs_vnodeops, &vp);
264 	if (error != 0) {
265 		free(unp, M_UNIONFSNODE);
266 		return (error);
267 	}
268 	error = insmntque(vp, mp);	/* XXX: Too early for mpsafe fs */
269 	if (error != 0) {
270 		free(unp, M_UNIONFSNODE);
271 		return (error);
272 	}
273 	if (dvp != NULLVP)
274 		vref(dvp);
275 	if (uppervp != NULLVP)
276 		vref(uppervp);
277 	if (lowervp != NULLVP)
278 		vref(lowervp);
279 
280 	switch (vt) {
281 	case VDIR:
282 		unp->un_hashtbl = hashinit(NUNIONFSNODECACHE, M_UNIONFSHASH,
283 		    &(unp->un_hashmask));
284 		break;
285 	case VSOCK:
286 		if (uppervp != NULLVP)
287 			vp->v_socket = uppervp->v_socket;
288 		else
289 			vp->v_socket = lowervp->v_socket;
290 		break;
291 	default:
292 		break;
293 	}
294 
295 	unp->un_vnode = vp;
296 	unp->un_uppervp = uppervp;
297 	unp->un_lowervp = lowervp;
298 	unp->un_dvp = dvp;
299 	if (uppervp != NULLVP)
300 		vp->v_vnlock = uppervp->v_vnlock;
301 	else
302 		vp->v_vnlock = lowervp->v_vnlock;
303 
304 	if (path != NULL) {
305 		unp->un_path = (char *)
306 		    malloc(cnp->cn_namelen +1, M_UNIONFSPATH, M_WAITOK|M_ZERO);
307 		bcopy(cnp->cn_nameptr, unp->un_path, cnp->cn_namelen);
308 		unp->un_path[cnp->cn_namelen] = '\0';
309 	}
310 	vp->v_type = vt;
311 	vp->v_data = unp;
312 
313 	if ((uppervp != NULLVP && ump->um_uppervp == uppervp) &&
314 	    (lowervp != NULLVP && ump->um_lowervp == lowervp))
315 		vp->v_vflag |= VV_ROOT;
316 
317 	if (path != NULL && dvp != NULLVP && (vt == VDIR || vt == VSOCK))
318 		*vpp = unionfs_ins_cached_vnode(unp, dvp, path);
319 	if ((*vpp) != NULLVP) {
320 		if (dvp != NULLVP)
321 			vrele(dvp);
322 		if (uppervp != NULLVP)
323 			vrele(uppervp);
324 		if (lowervp != NULLVP)
325 			vrele(lowervp);
326 
327 		unp->un_uppervp = NULLVP;
328 		unp->un_lowervp = NULLVP;
329 		unp->un_dvp = NULLVP;
330 		vrele(vp);
331 		vp = *vpp;
332 		vref(vp);
333 	} else
334 		*vpp = vp;
335 
336 unionfs_nodeget_out:
337 	if (lkflags & LK_TYPE_MASK)
338 		vn_lock(vp, lkflags | LK_RETRY);
339 
340 	return (0);
341 }
342 
343 /*
344  * Clean up the unionfs node.
345  */
346 void
347 unionfs_noderem(struct vnode *vp, struct thread *td)
348 {
349 	int		vfslocked;
350 	int		count;
351 	struct unionfs_node *unp, *unp_t1, *unp_t2;
352 	struct unionfs_node_hashhead *hd;
353 	struct unionfs_node_status *unsp, *unsp_tmp;
354 	struct vnode   *lvp;
355 	struct vnode   *uvp;
356 	struct vnode   *dvp;
357 
358 	/*
359 	 * Use the interlock to protect the clearing of v_data to
360 	 * prevent faults in unionfs_lock().
361 	 */
362 	VI_LOCK(vp);
363 	unp = VTOUNIONFS(vp);
364 	lvp = unp->un_lowervp;
365 	uvp = unp->un_uppervp;
366 	dvp = unp->un_dvp;
367 	unp->un_lowervp = unp->un_uppervp = NULLVP;
368 
369 	vp->v_vnlock = &(vp->v_lock);
370 	vp->v_data = NULL;
371 	lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_INTERLOCK, VI_MTX(vp));
372 	if (lvp != NULLVP)
373 		VOP_UNLOCK(lvp, 0);
374 	if (uvp != NULLVP)
375 		VOP_UNLOCK(uvp, 0);
376 	vp->v_object = NULL;
377 
378 	if (dvp != NULLVP && unp->un_hash.le_prev != NULL)
379 		unionfs_rem_cached_vnode(unp, dvp);
380 
381 	if (lvp != NULLVP) {
382 		vfslocked = VFS_LOCK_GIANT(lvp->v_mount);
383 		vrele(lvp);
384 		VFS_UNLOCK_GIANT(vfslocked);
385 	}
386 	if (uvp != NULLVP) {
387 		vfslocked = VFS_LOCK_GIANT(uvp->v_mount);
388 		vrele(uvp);
389 		VFS_UNLOCK_GIANT(vfslocked);
390 	}
391 	if (dvp != NULLVP) {
392 		vfslocked = VFS_LOCK_GIANT(dvp->v_mount);
393 		vrele(dvp);
394 		VFS_UNLOCK_GIANT(vfslocked);
395 		unp->un_dvp = NULLVP;
396 	}
397 	if (unp->un_path != NULL) {
398 		free(unp->un_path, M_UNIONFSPATH);
399 		unp->un_path = NULL;
400 	}
401 
402 	if (unp->un_hashtbl != NULL) {
403 		for (count = 0; count <= unp->un_hashmask; count++) {
404 			hd = unp->un_hashtbl + count;
405 			LIST_FOREACH_SAFE(unp_t1, hd, un_hash, unp_t2) {
406 				LIST_REMOVE(unp_t1, un_hash);
407 				unp_t1->un_hash.le_next = NULL;
408 				unp_t1->un_hash.le_prev = NULL;
409 			}
410 		}
411 		hashdestroy(unp->un_hashtbl, M_UNIONFSHASH, unp->un_hashmask);
412 	}
413 
414 	LIST_FOREACH_SAFE(unsp, &(unp->un_unshead), uns_list, unsp_tmp) {
415 		LIST_REMOVE(unsp, uns_list);
416 		free(unsp, M_TEMP);
417 	}
418 	free(unp, M_UNIONFSNODE);
419 }
420 
421 /*
422  * Get the unionfs node status.
423  * You need exclusive lock this vnode.
424  */
425 void
426 unionfs_get_node_status(struct unionfs_node *unp, struct thread *td,
427 			struct unionfs_node_status **unspp)
428 {
429 	struct unionfs_node_status *unsp;
430 	pid_t pid = td->td_proc->p_pid;
431 
432 	KASSERT(NULL != unspp, ("null pointer"));
433 	ASSERT_VOP_ELOCKED(UNIONFSTOV(unp), "unionfs_get_node_status");
434 
435 	LIST_FOREACH(unsp, &(unp->un_unshead), uns_list) {
436 		if (unsp->uns_pid == pid) {
437 			*unspp = unsp;
438 			return;
439 		}
440 	}
441 
442 	/* create a new unionfs node status */
443 	unsp = malloc(sizeof(struct unionfs_node_status),
444 	    M_TEMP, M_WAITOK | M_ZERO);
445 
446 	unsp->uns_pid = pid;
447 	LIST_INSERT_HEAD(&(unp->un_unshead), unsp, uns_list);
448 
449 	*unspp = unsp;
450 }
451 
452 /*
453  * Remove the unionfs node status, if you can.
454  * You need exclusive lock this vnode.
455  */
456 void
457 unionfs_tryrem_node_status(struct unionfs_node *unp,
458 			   struct unionfs_node_status *unsp)
459 {
460 	KASSERT(NULL != unsp, ("null pointer"));
461 	ASSERT_VOP_ELOCKED(UNIONFSTOV(unp), "unionfs_get_node_status");
462 
463 	if (0 < unsp->uns_lower_opencnt || 0 < unsp->uns_upper_opencnt)
464 		return;
465 
466 	LIST_REMOVE(unsp, uns_list);
467 	free(unsp, M_TEMP);
468 }
469 
470 /*
471  * Create upper node attr.
472  */
473 void
474 unionfs_create_uppervattr_core(struct unionfs_mount *ump,
475 			       struct vattr *lva,
476 			       struct vattr *uva,
477 			       struct thread *td)
478 {
479 	VATTR_NULL(uva);
480 	uva->va_type = lva->va_type;
481 	uva->va_atime = lva->va_atime;
482 	uva->va_mtime = lva->va_mtime;
483 	uva->va_ctime = lva->va_ctime;
484 
485 	switch (ump->um_copymode) {
486 	case UNIONFS_TRANSPARENT:
487 		uva->va_mode = lva->va_mode;
488 		uva->va_uid = lva->va_uid;
489 		uva->va_gid = lva->va_gid;
490 		break;
491 	case UNIONFS_MASQUERADE:
492 		if (ump->um_uid == lva->va_uid) {
493 			uva->va_mode = lva->va_mode & 077077;
494 			uva->va_mode |= (lva->va_type == VDIR ? ump->um_udir : ump->um_ufile) & 0700;
495 			uva->va_uid = lva->va_uid;
496 			uva->va_gid = lva->va_gid;
497 		} else {
498 			uva->va_mode = (lva->va_type == VDIR ? ump->um_udir : ump->um_ufile);
499 			uva->va_uid = ump->um_uid;
500 			uva->va_gid = ump->um_gid;
501 		}
502 		break;
503 	default:		/* UNIONFS_TRADITIONAL */
504 		FILEDESC_SLOCK(td->td_proc->p_fd);
505 		uva->va_mode = 0777 & ~td->td_proc->p_fd->fd_cmask;
506 		FILEDESC_SUNLOCK(td->td_proc->p_fd);
507 		uva->va_uid = ump->um_uid;
508 		uva->va_gid = ump->um_gid;
509 		break;
510 	}
511 }
512 
513 /*
514  * Create upper node attr.
515  */
516 int
517 unionfs_create_uppervattr(struct unionfs_mount *ump,
518 			  struct vnode *lvp,
519 			  struct vattr *uva,
520 			  struct ucred *cred,
521 			  struct thread *td)
522 {
523 	int		error;
524 	struct vattr	lva;
525 
526 	if ((error = VOP_GETATTR(lvp, &lva, cred)))
527 		return (error);
528 
529 	unionfs_create_uppervattr_core(ump, &lva, uva, td);
530 
531 	return (error);
532 }
533 
534 /*
535  * relookup
536  *
537  * dvp should be locked on entry and will be locked on return.
538  *
539  * If an error is returned, *vpp will be invalid, otherwise it will hold a
540  * locked, referenced vnode. If *vpp == dvp then remember that only one
541  * LK_EXCLUSIVE lock is held.
542  */
543 static int
544 unionfs_relookup(struct vnode *dvp, struct vnode **vpp,
545 		 struct componentname *cnp, struct componentname *cn,
546 		 struct thread *td, char *path, int pathlen, u_long nameiop)
547 {
548 	int	error;
549 
550 	cn->cn_namelen = pathlen;
551 	cn->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
552 	bcopy(path, cn->cn_pnbuf, pathlen);
553 	cn->cn_pnbuf[pathlen] = '\0';
554 
555 	cn->cn_nameiop = nameiop;
556 	cn->cn_flags = (LOCKPARENT | LOCKLEAF | HASBUF | SAVENAME | ISLASTCN);
557 	cn->cn_lkflags = LK_EXCLUSIVE;
558 	cn->cn_thread = td;
559 	cn->cn_cred = cnp->cn_cred;
560 
561 	cn->cn_nameptr = cn->cn_pnbuf;
562 	cn->cn_consume = cnp->cn_consume;
563 
564 	if (nameiop == DELETE)
565 		cn->cn_flags |= (cnp->cn_flags & (DOWHITEOUT | SAVESTART));
566 	else if (RENAME == nameiop)
567 		cn->cn_flags |= (cnp->cn_flags & SAVESTART);
568 
569 	vref(dvp);
570 	VOP_UNLOCK(dvp, 0);
571 
572 	if ((error = relookup(dvp, vpp, cn))) {
573 		uma_zfree(namei_zone, cn->cn_pnbuf);
574 		cn->cn_flags &= ~HASBUF;
575 		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
576 	} else
577 		vrele(dvp);
578 
579 	return (error);
580 }
581 
582 /*
583  * relookup for CREATE namei operation.
584  *
585  * dvp is unionfs vnode. dvp should be locked.
586  *
587  * If it called 'unionfs_copyfile' function by unionfs_link etc,
588  * VOP_LOOKUP information is broken.
589  * So it need relookup in order to create link etc.
590  */
591 int
592 unionfs_relookup_for_create(struct vnode *dvp, struct componentname *cnp,
593 			    struct thread *td)
594 {
595 	int	error;
596 	struct vnode *udvp;
597 	struct vnode *vp;
598 	struct componentname cn;
599 
600 	udvp = UNIONFSVPTOUPPERVP(dvp);
601 	vp = NULLVP;
602 
603 	error = unionfs_relookup(udvp, &vp, cnp, &cn, td, cnp->cn_nameptr,
604 	    strlen(cnp->cn_nameptr), CREATE);
605 	if (error)
606 		return (error);
607 
608 	if (vp != NULLVP) {
609 		if (udvp == vp)
610 			vrele(vp);
611 		else
612 			vput(vp);
613 
614 		error = EEXIST;
615 	}
616 
617 	if (cn.cn_flags & HASBUF) {
618 		uma_zfree(namei_zone, cn.cn_pnbuf);
619 		cn.cn_flags &= ~HASBUF;
620 	}
621 
622 	if (!error) {
623 		cn.cn_flags |= (cnp->cn_flags & HASBUF);
624 		cnp->cn_flags = cn.cn_flags;
625 	}
626 
627 	return (error);
628 }
629 
630 /*
631  * relookup for DELETE namei operation.
632  *
633  * dvp is unionfs vnode. dvp should be locked.
634  */
635 int
636 unionfs_relookup_for_delete(struct vnode *dvp, struct componentname *cnp,
637 			    struct thread *td)
638 {
639 	int	error;
640 	struct vnode *udvp;
641 	struct vnode *vp;
642 	struct componentname cn;
643 
644 	udvp = UNIONFSVPTOUPPERVP(dvp);
645 	vp = NULLVP;
646 
647 	error = unionfs_relookup(udvp, &vp, cnp, &cn, td, cnp->cn_nameptr,
648 	    strlen(cnp->cn_nameptr), DELETE);
649 	if (error)
650 		return (error);
651 
652 	if (vp == NULLVP)
653 		error = ENOENT;
654 	else {
655 		if (udvp == vp)
656 			vrele(vp);
657 		else
658 			vput(vp);
659 	}
660 
661 	if (cn.cn_flags & HASBUF) {
662 		uma_zfree(namei_zone, cn.cn_pnbuf);
663 		cn.cn_flags &= ~HASBUF;
664 	}
665 
666 	if (!error) {
667 		cn.cn_flags |= (cnp->cn_flags & HASBUF);
668 		cnp->cn_flags = cn.cn_flags;
669 	}
670 
671 	return (error);
672 }
673 
674 /*
675  * relookup for RENAME namei operation.
676  *
677  * dvp is unionfs vnode. dvp should be locked.
678  */
679 int
680 unionfs_relookup_for_rename(struct vnode *dvp, struct componentname *cnp,
681 			    struct thread *td)
682 {
683 	int error;
684 	struct vnode *udvp;
685 	struct vnode *vp;
686 	struct componentname cn;
687 
688 	udvp = UNIONFSVPTOUPPERVP(dvp);
689 	vp = NULLVP;
690 
691 	error = unionfs_relookup(udvp, &vp, cnp, &cn, td, cnp->cn_nameptr,
692 	    strlen(cnp->cn_nameptr), RENAME);
693 	if (error)
694 		return (error);
695 
696 	if (vp != NULLVP) {
697 		if (udvp == vp)
698 			vrele(vp);
699 		else
700 			vput(vp);
701 	}
702 
703 	if (cn.cn_flags & HASBUF) {
704 		uma_zfree(namei_zone, cn.cn_pnbuf);
705 		cn.cn_flags &= ~HASBUF;
706 	}
707 
708 	if (!error) {
709 		cn.cn_flags |= (cnp->cn_flags & HASBUF);
710 		cnp->cn_flags = cn.cn_flags;
711 	}
712 
713 	return (error);
714 
715 }
716 
717 /*
718  * Update the unionfs_node.
719  *
720  * uvp is new locked upper vnode. unionfs vnode's lock will be exchanged to the
721  * uvp's lock and lower's lock will be unlocked.
722  */
723 static void
724 unionfs_node_update(struct unionfs_node *unp, struct vnode *uvp,
725 		    struct thread *td)
726 {
727 	unsigned	count, lockrec;
728 	struct vnode   *vp;
729 	struct vnode   *lvp;
730 	struct vnode   *dvp;
731 
732 	vp = UNIONFSTOV(unp);
733 	lvp = unp->un_lowervp;
734 	ASSERT_VOP_ELOCKED(lvp, "unionfs_node_update");
735 	dvp = unp->un_dvp;
736 
737 	/*
738 	 * lock update
739 	 */
740 	VI_LOCK(vp);
741 	unp->un_uppervp = uvp;
742 	vp->v_vnlock = uvp->v_vnlock;
743 	VI_UNLOCK(vp);
744 	lockrec = lvp->v_vnlock->lk_recurse;
745 	for (count = 0; count < lockrec; count++)
746 		vn_lock(uvp, LK_EXCLUSIVE | LK_CANRECURSE | LK_RETRY);
747 
748 	/*
749 	 * cache update
750 	 */
751 	if (unp->un_path != NULL && dvp != NULLVP &&
752 	    (vp->v_type == VDIR || vp->v_type == VSOCK)) {
753 		static struct unionfs_node_hashhead *hd;
754 
755 		VI_LOCK(dvp);
756 		hd = unionfs_get_hashhead(dvp, unp->un_path);
757 		LIST_REMOVE(unp, un_hash);
758 		LIST_INSERT_HEAD(hd, unp, un_hash);
759 		VI_UNLOCK(dvp);
760 	}
761 }
762 
763 /*
764  * Create a new shadow dir.
765  *
766  * udvp should be locked on entry and will be locked on return.
767  *
768  * If no error returned, unp will be updated.
769  */
770 int
771 unionfs_mkshadowdir(struct unionfs_mount *ump, struct vnode *udvp,
772 		    struct unionfs_node *unp, struct componentname *cnp,
773 		    struct thread *td)
774 {
775 	int		error;
776 	struct vnode   *lvp;
777 	struct vnode   *uvp;
778 	struct vattr	va;
779 	struct vattr	lva;
780 	struct componentname cn;
781 	struct mount   *mp;
782 	struct ucred   *cred;
783 	struct ucred   *credbk;
784 	struct uidinfo *rootinfo;
785 
786 	if (unp->un_uppervp != NULLVP)
787 		return (EEXIST);
788 
789 	lvp = unp->un_lowervp;
790 	uvp = NULLVP;
791 	credbk = cnp->cn_cred;
792 
793 	/* Authority change to root */
794 	rootinfo = uifind((uid_t)0);
795 	cred = crdup(cnp->cn_cred);
796 	chgproccnt(cred->cr_ruidinfo, 1, 0);
797 	change_euid(cred, rootinfo);
798 	change_ruid(cred, rootinfo);
799 	change_svuid(cred, (uid_t)0);
800 	uifree(rootinfo);
801 	cnp->cn_cred = cred;
802 
803 	memset(&cn, 0, sizeof(cn));
804 
805 	if ((error = VOP_GETATTR(lvp, &lva, cnp->cn_cred)))
806 		goto unionfs_mkshadowdir_abort;
807 
808 	if ((error = unionfs_relookup(udvp, &uvp, cnp, &cn, td, cnp->cn_nameptr, cnp->cn_namelen, CREATE)))
809 		goto unionfs_mkshadowdir_abort;
810 	if (uvp != NULLVP) {
811 		if (udvp == uvp)
812 			vrele(uvp);
813 		else
814 			vput(uvp);
815 
816 		error = EEXIST;
817 		goto unionfs_mkshadowdir_free_out;
818 	}
819 
820 	if ((error = vn_start_write(udvp, &mp, V_WAIT | PCATCH)))
821 		goto unionfs_mkshadowdir_free_out;
822 	if ((error = VOP_LEASE(udvp, td, cn.cn_cred, LEASE_WRITE))) {
823 		vn_finished_write(mp);
824 		goto unionfs_mkshadowdir_free_out;
825 	}
826 	unionfs_create_uppervattr_core(ump, &lva, &va, td);
827 
828 	error = VOP_MKDIR(udvp, &uvp, &cn, &va);
829 
830 	if (!error) {
831 		unionfs_node_update(unp, uvp, td);
832 
833 		/*
834 		 * XXX The bug which cannot set uid/gid was corrected.
835 		 * Ignore errors.
836 		 */
837 		va.va_type = VNON;
838 		VOP_SETATTR(uvp, &va, cn.cn_cred);
839 	}
840 	vn_finished_write(mp);
841 
842 unionfs_mkshadowdir_free_out:
843 	if (cn.cn_flags & HASBUF) {
844 		uma_zfree(namei_zone, cn.cn_pnbuf);
845 		cn.cn_flags &= ~HASBUF;
846 	}
847 
848 unionfs_mkshadowdir_abort:
849 	cnp->cn_cred = credbk;
850 	chgproccnt(cred->cr_ruidinfo, -1, 0);
851 	crfree(cred);
852 
853 	return (error);
854 }
855 
856 /*
857  * Create a new whiteout.
858  *
859  * dvp should be locked on entry and will be locked on return.
860  */
861 int
862 unionfs_mkwhiteout(struct vnode *dvp, struct componentname *cnp,
863 		   struct thread *td, char *path)
864 {
865 	int		error;
866 	struct vnode   *wvp;
867 	struct componentname cn;
868 	struct mount   *mp;
869 
870 	if (path == NULL)
871 		path = cnp->cn_nameptr;
872 
873 	wvp = NULLVP;
874 	if ((error = unionfs_relookup(dvp, &wvp, cnp, &cn, td, path, strlen(path), CREATE)))
875 		return (error);
876 	if (wvp != NULLVP) {
877 		if (cn.cn_flags & HASBUF) {
878 			uma_zfree(namei_zone, cn.cn_pnbuf);
879 			cn.cn_flags &= ~HASBUF;
880 		}
881 		if (dvp == wvp)
882 			vrele(wvp);
883 		else
884 			vput(wvp);
885 
886 		return (EEXIST);
887 	}
888 
889 	if ((error = vn_start_write(dvp, &mp, V_WAIT | PCATCH)))
890 		goto unionfs_mkwhiteout_free_out;
891 	if (!(error = VOP_LEASE(dvp, td, td->td_ucred, LEASE_WRITE)))
892 		error = VOP_WHITEOUT(dvp, &cn, CREATE);
893 
894 	vn_finished_write(mp);
895 
896 unionfs_mkwhiteout_free_out:
897 	if (cn.cn_flags & HASBUF) {
898 		uma_zfree(namei_zone, cn.cn_pnbuf);
899 		cn.cn_flags &= ~HASBUF;
900 	}
901 
902 	return (error);
903 }
904 
905 /*
906  * Create a new vnode for create a new shadow file.
907  *
908  * If an error is returned, *vpp will be invalid, otherwise it will hold a
909  * locked, referenced and opened vnode.
910  *
911  * unp is never updated.
912  */
913 static int
914 unionfs_vn_create_on_upper(struct vnode **vpp, struct vnode *udvp,
915 			   struct unionfs_node *unp, struct vattr *uvap,
916 			   struct thread *td)
917 {
918 	struct unionfs_mount *ump;
919 	struct vnode   *vp;
920 	struct vnode   *lvp;
921 	struct ucred   *cred;
922 	struct vattr	lva;
923 	int		fmode;
924 	int		error;
925 	struct componentname cn;
926 
927 	ump = MOUNTTOUNIONFSMOUNT(UNIONFSTOV(unp)->v_mount);
928 	vp = NULLVP;
929 	lvp = unp->un_lowervp;
930 	cred = td->td_ucred;
931 	fmode = FFLAGS(O_WRONLY | O_CREAT | O_TRUNC | O_EXCL);
932 	error = 0;
933 
934 	if ((error = VOP_GETATTR(lvp, &lva, cred)) != 0)
935 		return (error);
936 	unionfs_create_uppervattr_core(ump, &lva, uvap, td);
937 
938 	if (unp->un_path == NULL)
939 		panic("unionfs: un_path is null");
940 
941 	cn.cn_namelen = strlen(unp->un_path);
942 	cn.cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
943 	bcopy(unp->un_path, cn.cn_pnbuf, cn.cn_namelen + 1);
944 	cn.cn_nameiop = CREATE;
945 	cn.cn_flags = (LOCKPARENT | LOCKLEAF | HASBUF | SAVENAME | ISLASTCN);
946 	cn.cn_lkflags = LK_EXCLUSIVE;
947 	cn.cn_thread = td;
948 	cn.cn_cred = cred;
949 	cn.cn_nameptr = cn.cn_pnbuf;
950 	cn.cn_consume = 0;
951 
952 	vref(udvp);
953 	if ((error = relookup(udvp, &vp, &cn)) != 0)
954 		goto unionfs_vn_create_on_upper_free_out2;
955 	vrele(udvp);
956 
957 	if (vp != NULLVP) {
958 		if (vp == udvp)
959 			vrele(vp);
960 		else
961 			vput(vp);
962 		error = EEXIST;
963 		goto unionfs_vn_create_on_upper_free_out1;
964 	}
965 
966 	if ((error = VOP_LEASE(udvp, td, cred, LEASE_WRITE)) != 0)
967 		goto unionfs_vn_create_on_upper_free_out1;
968 
969 	if ((error = VOP_CREATE(udvp, &vp, &cn, uvap)) != 0)
970 		goto unionfs_vn_create_on_upper_free_out1;
971 
972 	if ((error = VOP_OPEN(vp, fmode, cred, td, NULL)) != 0) {
973 		vput(vp);
974 		goto unionfs_vn_create_on_upper_free_out1;
975 	}
976 	vp->v_writecount++;
977 	*vpp = vp;
978 
979 unionfs_vn_create_on_upper_free_out1:
980 	VOP_UNLOCK(udvp, 0);
981 
982 unionfs_vn_create_on_upper_free_out2:
983 	if (cn.cn_flags & HASBUF) {
984 		uma_zfree(namei_zone, cn.cn_pnbuf);
985 		cn.cn_flags &= ~HASBUF;
986 	}
987 
988 	return (error);
989 }
990 
991 /*
992  * Copy from lvp to uvp.
993  *
994  * lvp and uvp should be locked and opened on entry and will be locked and
995  * opened on return.
996  */
997 static int
998 unionfs_copyfile_core(struct vnode *lvp, struct vnode *uvp,
999 		      struct ucred *cred, struct thread *td)
1000 {
1001 	int		error;
1002 	off_t		offset;
1003 	int		count;
1004 	int		bufoffset;
1005 	char           *buf;
1006 	struct uio	uio;
1007 	struct iovec	iov;
1008 
1009 	error = 0;
1010 	memset(&uio, 0, sizeof(uio));
1011 
1012 	uio.uio_td = td;
1013 	uio.uio_segflg = UIO_SYSSPACE;
1014 	uio.uio_offset = 0;
1015 
1016 	if ((error = VOP_LEASE(lvp, td, cred, LEASE_READ)) != 0)
1017 		return (error);
1018 	if ((error = VOP_LEASE(uvp, td, cred, LEASE_WRITE)) != 0)
1019 		return (error);
1020 	buf = malloc(MAXBSIZE, M_TEMP, M_WAITOK);
1021 
1022 	while (error == 0) {
1023 		offset = uio.uio_offset;
1024 
1025 		uio.uio_iov = &iov;
1026 		uio.uio_iovcnt = 1;
1027 		iov.iov_base = buf;
1028 		iov.iov_len = MAXBSIZE;
1029 		uio.uio_resid = iov.iov_len;
1030 		uio.uio_rw = UIO_READ;
1031 
1032 		if ((error = VOP_READ(lvp, &uio, 0, cred)) != 0)
1033 			break;
1034 		if ((count = MAXBSIZE - uio.uio_resid) == 0)
1035 			break;
1036 
1037 		bufoffset = 0;
1038 		while (bufoffset < count) {
1039 			uio.uio_iov = &iov;
1040 			uio.uio_iovcnt = 1;
1041 			iov.iov_base = buf + bufoffset;
1042 			iov.iov_len = count - bufoffset;
1043 			uio.uio_offset = offset + bufoffset;
1044 			uio.uio_resid = iov.iov_len;
1045 			uio.uio_rw = UIO_WRITE;
1046 
1047 			if ((error = VOP_WRITE(uvp, &uio, 0, cred)) != 0)
1048 				break;
1049 
1050 			bufoffset += (count - bufoffset) - uio.uio_resid;
1051 		}
1052 
1053 		uio.uio_offset = offset + bufoffset;
1054 	}
1055 
1056 	free(buf, M_TEMP);
1057 
1058 	return (error);
1059 }
1060 
1061 /*
1062  * Copy file from lower to upper.
1063  *
1064  * If you need copy of the contents, set 1 to docopy. Otherwise, set 0 to
1065  * docopy.
1066  *
1067  * If no error returned, unp will be updated.
1068  */
1069 int
1070 unionfs_copyfile(struct unionfs_node *unp, int docopy, struct ucred *cred,
1071 		 struct thread *td)
1072 {
1073 	int		error;
1074 	struct mount   *mp;
1075 	struct vnode   *udvp;
1076 	struct vnode   *lvp;
1077 	struct vnode   *uvp;
1078 	struct vattr	uva;
1079 
1080 	lvp = unp->un_lowervp;
1081 	uvp = NULLVP;
1082 
1083 	if ((UNIONFSTOV(unp)->v_mount->mnt_flag & MNT_RDONLY))
1084 		return (EROFS);
1085 	if (unp->un_dvp == NULLVP)
1086 		return (EINVAL);
1087 	if (unp->un_uppervp != NULLVP)
1088 		return (EEXIST);
1089 	udvp = VTOUNIONFS(unp->un_dvp)->un_uppervp;
1090 	if (udvp == NULLVP)
1091 		return (EROFS);
1092 	if ((udvp->v_mount->mnt_flag & MNT_RDONLY))
1093 		return (EROFS);
1094 
1095 	error = VOP_ACCESS(lvp, VREAD, cred, td);
1096 	if (error != 0)
1097 		return (error);
1098 
1099 	if ((error = vn_start_write(udvp, &mp, V_WAIT | PCATCH)) != 0)
1100 		return (error);
1101 	error = unionfs_vn_create_on_upper(&uvp, udvp, unp, &uva, td);
1102 	if (error != 0) {
1103 		vn_finished_write(mp);
1104 		return (error);
1105 	}
1106 
1107 	if (docopy != 0) {
1108 		error = VOP_OPEN(lvp, FREAD, cred, td, NULL);
1109 		if (error == 0) {
1110 			error = unionfs_copyfile_core(lvp, uvp, cred, td);
1111 			VOP_CLOSE(lvp, FREAD, cred, td);
1112 		}
1113 	}
1114 	VOP_CLOSE(uvp, FWRITE, cred, td);
1115 	uvp->v_writecount--;
1116 
1117 	vn_finished_write(mp);
1118 
1119 	if (error == 0) {
1120 		/* Reset the attributes. Ignore errors. */
1121 		uva.va_type = VNON;
1122 		VOP_SETATTR(uvp, &uva, cred);
1123 	}
1124 
1125 	unionfs_node_update(unp, uvp, td);
1126 
1127 	return (error);
1128 }
1129 
1130 /*
1131  * It checks whether vp can rmdir. (check empty)
1132  *
1133  * vp is unionfs vnode.
1134  * vp should be locked.
1135  */
1136 int
1137 unionfs_check_rmdir(struct vnode *vp, struct ucred *cred, struct thread *td)
1138 {
1139 	int		error;
1140 	int		eofflag;
1141 	int		lookuperr;
1142 	struct vnode   *uvp;
1143 	struct vnode   *lvp;
1144 	struct vnode   *tvp;
1145 	struct vattr	va;
1146 	struct componentname cn;
1147 	/*
1148 	 * The size of buf needs to be larger than DIRBLKSIZ.
1149 	 */
1150 	char		buf[256 * 6];
1151 	struct dirent  *dp;
1152 	struct dirent  *edp;
1153 	struct uio	uio;
1154 	struct iovec	iov;
1155 
1156 	ASSERT_VOP_ELOCKED(vp, "unionfs_check_rmdir");
1157 
1158 	eofflag = 0;
1159 	uvp = UNIONFSVPTOUPPERVP(vp);
1160 	lvp = UNIONFSVPTOLOWERVP(vp);
1161 
1162 	/* check opaque */
1163 	if ((error = VOP_GETATTR(uvp, &va, cred)) != 0)
1164 		return (error);
1165 	if (va.va_flags & OPAQUE)
1166 		return (0);
1167 
1168 	/* open vnode */
1169 #ifdef MAC
1170 	if ((error = mac_vnode_check_open(cred, vp, VEXEC|VREAD)) != 0)
1171 		return (error);
1172 #endif
1173 	if ((error = VOP_ACCESS(vp, VEXEC|VREAD, cred, td)) != 0)
1174 		return (error);
1175 	if ((error = VOP_OPEN(vp, FREAD, cred, td, NULL)) != 0)
1176 		return (error);
1177 
1178 	uio.uio_rw = UIO_READ;
1179 	uio.uio_segflg = UIO_SYSSPACE;
1180 	uio.uio_td = td;
1181 	uio.uio_offset = 0;
1182 
1183 #ifdef MAC
1184 	error = mac_vnode_check_readdir(td->td_ucred, lvp);
1185 #endif
1186 	while (!error && !eofflag) {
1187 		iov.iov_base = buf;
1188 		iov.iov_len = sizeof(buf);
1189 		uio.uio_iov = &iov;
1190 		uio.uio_iovcnt = 1;
1191 		uio.uio_resid = iov.iov_len;
1192 
1193 		error = VOP_READDIR(lvp, &uio, cred, &eofflag, NULL, NULL);
1194 		if (error != 0)
1195 			break;
1196 		if (eofflag == 0 && uio.uio_resid == sizeof(buf)) {
1197 #ifdef DIAGNOSTIC
1198 			panic("bad readdir response from lower FS.");
1199 #endif
1200 			break;
1201 		}
1202 
1203 		edp = (struct dirent*)&buf[sizeof(buf) - uio.uio_resid];
1204 		for (dp = (struct dirent*)buf; !error && dp < edp;
1205 		     dp = (struct dirent*)((caddr_t)dp + dp->d_reclen)) {
1206 			if (dp->d_type == DT_WHT ||
1207 			    (dp->d_namlen == 1 && dp->d_name[0] == '.') ||
1208 			    (dp->d_namlen == 2 && !bcmp(dp->d_name, "..", 2)))
1209 				continue;
1210 
1211 			cn.cn_namelen = dp->d_namlen;
1212 			cn.cn_pnbuf = NULL;
1213 			cn.cn_nameptr = dp->d_name;
1214 			cn.cn_nameiop = LOOKUP;
1215 			cn.cn_flags = (LOCKPARENT | LOCKLEAF | SAVENAME | RDONLY | ISLASTCN);
1216 			cn.cn_lkflags = LK_EXCLUSIVE;
1217 			cn.cn_thread = td;
1218 			cn.cn_cred = cred;
1219 			cn.cn_consume = 0;
1220 
1221 			/*
1222 			 * check entry in lower.
1223 			 * Sometimes, readdir function returns
1224 			 * wrong entry.
1225 			 */
1226 			lookuperr = VOP_LOOKUP(lvp, &tvp, &cn);
1227 
1228 			if (!lookuperr)
1229 				vput(tvp);
1230 			else
1231 				continue; /* skip entry */
1232 
1233 			/*
1234 			 * check entry
1235 			 * If it has no exist/whiteout entry in upper,
1236 			 * directory is not empty.
1237 			 */
1238 			cn.cn_flags = (LOCKPARENT | LOCKLEAF | SAVENAME | RDONLY | ISLASTCN);
1239 			lookuperr = VOP_LOOKUP(uvp, &tvp, &cn);
1240 
1241 			if (!lookuperr)
1242 				vput(tvp);
1243 
1244 			/* ignore exist or whiteout entry */
1245 			if (!lookuperr ||
1246 			    (lookuperr == ENOENT && (cn.cn_flags & ISWHITEOUT)))
1247 				continue;
1248 
1249 			error = ENOTEMPTY;
1250 		}
1251 	}
1252 
1253 	/* close vnode */
1254 	VOP_CLOSE(vp, FREAD, cred, td);
1255 
1256 	return (error);
1257 }
1258 
1259 #ifdef DIAGNOSTIC
1260 
1261 struct vnode   *
1262 unionfs_checkuppervp(struct vnode *vp, char *fil, int lno)
1263 {
1264 	struct unionfs_node *unp;
1265 
1266 	unp = VTOUNIONFS(vp);
1267 
1268 #ifdef notyet
1269 	if (vp->v_op != unionfs_vnodeop_p) {
1270 		printf("unionfs_checkuppervp: on non-unionfs-node.\n");
1271 #ifdef KDB
1272 		kdb_enter(KDB_WHY_UNIONFS,
1273 		    "unionfs_checkuppervp: on non-unionfs-node.\n");
1274 #endif
1275 		panic("unionfs_checkuppervp");
1276 	};
1277 #endif
1278 	return (unp->un_uppervp);
1279 }
1280 
1281 struct vnode   *
1282 unionfs_checklowervp(struct vnode *vp, char *fil, int lno)
1283 {
1284 	struct unionfs_node *unp;
1285 
1286 	unp = VTOUNIONFS(vp);
1287 
1288 #ifdef notyet
1289 	if (vp->v_op != unionfs_vnodeop_p) {
1290 		printf("unionfs_checklowervp: on non-unionfs-node.\n");
1291 #ifdef KDB
1292 		kdb_enter(KDB_WHY_UNIONFS,
1293 		    "unionfs_checklowervp: on non-unionfs-node.\n");
1294 #endif
1295 		panic("unionfs_checklowervp");
1296 	};
1297 #endif
1298 	return (unp->un_lowervp);
1299 }
1300 #endif
1301