xref: /titanic_41/usr/src/uts/common/fs/lofs/lofs_vnops.c (revision fef1e07ef354c2dcda4dc397c33f5a5532432c7a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/errno.h>
31 #include <sys/vnode.h>
32 #include <sys/vfs.h>
33 #include <sys/uio.h>
34 #include <sys/cred.h>
35 #include <sys/pathname.h>
36 #include <sys/debug.h>
37 #include <sys/fs/lofs_node.h>
38 #include <sys/fs/lofs_info.h>
39 #include <fs/fs_subr.h>
40 #include <vm/as.h>
41 #include <vm/seg.h>
42 
43 #define	IS_ZONEDEVFS(vp) \
44 	(vtoli((vp)->v_vfsp)->li_flag & LO_ZONEDEVFS)
45 
46 /*
47  * These are the vnode ops routines which implement the vnode interface to
48  * the looped-back file system.  These routines just take their parameters,
49  * and then calling the appropriate real vnode routine(s) to do the work.
50  */
51 
52 static int
53 lo_open(vnode_t **vpp, int flag, struct cred *cr)
54 {
55 	vnode_t *vp = *vpp;
56 	vnode_t *rvp;
57 	vnode_t *oldvp;
58 	int error;
59 
60 #ifdef LODEBUG
61 	lo_dprint(4, "lo_open vp %p cnt=%d realvp %p cnt=%d\n",
62 		vp, vp->v_count, realvp(vp), realvp(vp)->v_count);
63 #endif
64 
65 	oldvp = vp;
66 	vp = rvp = realvp(vp);
67 	/*
68 	 * Need to hold new reference to vp since VOP_OPEN() may
69 	 * decide to release it.
70 	 */
71 	VN_HOLD(vp);
72 	error = VOP_OPEN(&rvp, flag, cr);
73 
74 	if (!error && rvp != vp) {
75 		/*
76 		 * the FS which we called should have released the
77 		 * new reference on vp
78 		 */
79 		*vpp = makelonode(rvp, vtoli(oldvp->v_vfsp), 0);
80 		if ((*vpp)->v_type == VDIR) {
81 			/*
82 			 * Copy over any looping flags to the new lnode.
83 			 */
84 			(vtol(*vpp))->lo_looping |= (vtol(oldvp))->lo_looping;
85 		}
86 		if (IS_DEVVP(*vpp)) {
87 			vnode_t *svp;
88 
89 			svp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, cr);
90 			VN_RELE(*vpp);
91 			if (svp == NULL)
92 				error = ENOSYS;
93 			else
94 				*vpp = svp;
95 		}
96 		VN_RELE(oldvp);
97 	} else {
98 		ASSERT(rvp->v_count > 1);
99 		VN_RELE(rvp);
100 	}
101 
102 	return (error);
103 }
104 
105 static int
106 lo_close(
107 	vnode_t *vp,
108 	int flag,
109 	int count,
110 	offset_t offset,
111 	struct cred *cr)
112 {
113 #ifdef LODEBUG
114 	lo_dprint(4, "lo_close vp %p realvp %p\n", vp, realvp(vp));
115 #endif
116 	vp = realvp(vp);
117 	return (VOP_CLOSE(vp, flag, count, offset, cr));
118 }
119 
120 static int
121 lo_read(vnode_t *vp, struct uio *uiop, int ioflag, struct cred *cr,
122 	caller_context_t *ct)
123 {
124 #ifdef LODEBUG
125 	lo_dprint(4, "lo_read vp %p realvp %p\n", vp, realvp(vp));
126 #endif
127 	vp = realvp(vp);
128 	return (VOP_READ(vp, uiop, ioflag, cr, ct));
129 }
130 
131 static int
132 lo_write(vnode_t *vp, struct uio *uiop, int ioflag, struct cred *cr,
133 	caller_context_t *ct)
134 {
135 #ifdef LODEBUG
136 	lo_dprint(4, "lo_write vp %p realvp %p\n", vp, realvp(vp));
137 #endif
138 	vp = realvp(vp);
139 	return (VOP_WRITE(vp, uiop, ioflag, cr, ct));
140 }
141 
142 static int
143 lo_ioctl(
144 	vnode_t *vp,
145 	int cmd,
146 	intptr_t arg,
147 	int flag,
148 	struct cred *cr,
149 	int *rvalp)
150 {
151 #ifdef LODEBUG
152 	lo_dprint(4, "lo_ioctl vp %p realvp %p\n", vp, realvp(vp));
153 #endif
154 	vp = realvp(vp);
155 	return (VOP_IOCTL(vp, cmd, arg, flag, cr, rvalp));
156 }
157 
158 static int
159 lo_setfl(vnode_t *vp, int oflags, int nflags, cred_t *cr)
160 {
161 	vp = realvp(vp);
162 	return (VOP_SETFL(vp, oflags, nflags, cr));
163 }
164 
165 static int
166 lo_getattr(
167 	vnode_t *vp,
168 	struct vattr *vap,
169 	int flags,
170 	struct cred *cr)
171 {
172 	int error;
173 
174 #ifdef LODEBUG
175 	lo_dprint(4, "lo_getattr vp %p realvp %p\n", vp, realvp(vp));
176 #endif
177 	if (error = VOP_GETATTR(realvp(vp), vap, flags, cr))
178 		return (error);
179 
180 	/*
181 	 * In zonedevfs mode, we pull a nasty trick; we make sure that
182 	 * the dev_t does *not* reflect the underlying device, so that
183 	 * no renames can occur to or from the /dev hierarchy.
184 	 */
185 	if (IS_ZONEDEVFS(vp)) {
186 		vap->va_fsid = expldev(vp->v_vfsp->vfs_fsid.val[0]);
187 	}
188 
189 	return (0);
190 }
191 
192 static int
193 lo_setattr(
194 	vnode_t *vp,
195 	struct vattr *vap,
196 	int flags,
197 	struct cred *cr,
198 	caller_context_t *ct)
199 {
200 #ifdef LODEBUG
201 	lo_dprint(4, "lo_setattr vp %p realvp %p\n", vp, realvp(vp));
202 #endif
203 	if (IS_ZONEDEVFS(vp) && !IS_DEVVP(vp)) {
204 		return (EACCES);
205 	}
206 	vp = realvp(vp);
207 	return (VOP_SETATTR(vp, vap, flags, cr, ct));
208 }
209 
210 static int
211 lo_access(vnode_t *vp, int mode, int flags, struct cred *cr)
212 {
213 #ifdef LODEBUG
214 	lo_dprint(4, "lo_access vp %p realvp %p\n", vp, realvp(vp));
215 #endif
216 	if (mode & VWRITE) {
217 		if (vp->v_type == VREG && vn_is_readonly(vp))
218 			return (EROFS);
219 		if (IS_ZONEDEVFS(vp) && !IS_DEVVP(vp))
220 			return (EACCES);
221 	}
222 	vp = realvp(vp);
223 	return (VOP_ACCESS(vp, mode, flags, cr));
224 }
225 
226 static int
227 lo_fsync(vnode_t *vp, int syncflag, struct cred *cr)
228 {
229 #ifdef LODEBUG
230 	lo_dprint(4, "lo_fsync vp %p realvp %p\n", vp, realvp(vp));
231 #endif
232 	vp = realvp(vp);
233 	return (VOP_FSYNC(vp, syncflag, cr));
234 }
235 
236 /*ARGSUSED*/
237 static void
238 lo_inactive(vnode_t *vp, struct cred *cr)
239 {
240 #ifdef LODEBUG
241 	lo_dprint(4, "lo_inactive %p, realvp %p\n", vp, realvp(vp));
242 #endif
243 	freelonode(vtol(vp));
244 }
245 
246 /* ARGSUSED */
247 static int
248 lo_fid(vnode_t *vp, struct fid *fidp)
249 {
250 #ifdef LODEBUG
251 	lo_dprint(4, "lo_fid %p, realvp %p\n", vp, realvp(vp));
252 #endif
253 	vp = realvp(vp);
254 	return (VOP_FID(vp, fidp));
255 }
256 
257 /*
258  * Given a vnode of lofs type, lookup nm name and
259  * return a shadow vnode (of lofs type) of the
260  * real vnode found.
261  *
262  * Due to the nature of lofs, there is a potential
263  * looping in path traversal.
264  *
265  * starting from the mount point of an lofs;
266  * a loop is defined to be a traversal path
267  * where the mount point or the real vnode of
268  * the root of this lofs is encountered twice.
269  * Once at the start of traversal and second
270  * when the looping is found.
271  *
272  * When a loop is encountered, a shadow of the
273  * covered vnode is returned to stop the looping.
274  *
275  * This normally works, but with the advent of
276  * the new automounter, returning the shadow of the
277  * covered vnode (autonode, in this case) does not
278  * stop the loop.  Because further lookup on this
279  * lonode will cause the autonode to call lo_lookup()
280  * on the lonode covering it.
281  *
282  * example "/net/jurassic/net/jurassic" is a loop.
283  * returning the shadow of the autonode corresponding to
284  * "/net/jurassic/net/jurassic" will not terminate the
285  * loop.   To solve this problem we allow the loop to go
286  * through one more level component lookup.  Whichever
287  * directory is then looked up in "/net/jurassic/net/jurassic"
288  * the vnode returned is the vnode covered by the autonode
289  * "net" and this will terminate the loop.
290  *
291  * Lookup for dot dot has to be dealt with separately.
292  * It will be nice to have a "one size fits all" kind
293  * of solution, so that we don't have so many ifs statement
294  * in the lo_lookup() to handle dotdot.  But, since
295  * there are so many special cases to handle different
296  * kinds looping above, we need special codes to handle
297  * dotdot lookup as well.
298  */
299 static int
300 lo_lookup(
301 	vnode_t *dvp,
302 	char *nm,
303 	vnode_t **vpp,
304 	struct pathname *pnp,
305 	int flags,
306 	vnode_t *rdir,
307 	struct cred *cr)
308 {
309 	vnode_t *vp = NULL, *tvp = NULL, *nonlovp;
310 	int error, is_indirectloop;
311 	vnode_t *realdvp = realvp(dvp);
312 	struct loinfo *li = vtoli(dvp->v_vfsp);
313 	int looping = 0;
314 	int autoloop = 0;
315 	int doingdotdot = 0;
316 	int nosub = 0;
317 	int mkflag = 0;
318 
319 	/*
320 	 * If name is empty and no XATTR flags are set, then return
321 	 * dvp (empty name == lookup ".").  If an XATTR flag is set
322 	 * then we need to call VOP_LOOKUP to get the xattr dir.
323 	 */
324 	if (nm[0] == '\0' && ! (flags & (CREATE_XATTR_DIR|LOOKUP_XATTR))) {
325 		VN_HOLD(dvp);
326 		*vpp = dvp;
327 		return (0);
328 	}
329 
330 	if (nm[0] == '.' && nm[1] == '.' && nm[2] == '\0') {
331 		doingdotdot++;
332 		/*
333 		 * Handle ".." out of mounted filesystem
334 		 */
335 		while ((realdvp->v_flag & VROOT) && realdvp != rootdir) {
336 			realdvp = realdvp->v_vfsp->vfs_vnodecovered;
337 			ASSERT(realdvp != NULL);
338 		}
339 	}
340 
341 	*vpp = NULL;	/* default(error) case */
342 
343 	/*
344 	 * Do the normal lookup
345 	 */
346 	if (error = VOP_LOOKUP(realdvp, nm, &vp, pnp, flags, rdir, cr)) {
347 		vp = NULL;
348 		goto out;
349 	}
350 
351 	/*
352 	 * We do this check here to avoid returning a stale file handle to the
353 	 * caller.
354 	 */
355 	if (nm[0] == '.' && nm[1] == '\0') {
356 		ASSERT(vp == realdvp);
357 		VN_HOLD(dvp);
358 		VN_RELE(vp);
359 		*vpp = dvp;
360 		return (0);
361 	}
362 
363 	if (doingdotdot) {
364 		if ((vtol(dvp))->lo_looping & LO_LOOPING) {
365 			vfs_t *vfsp;
366 
367 			error = vn_vfsrlock_wait(realdvp);
368 			if (error)
369 				goto out;
370 			vfsp = vn_mountedvfs(realdvp);
371 			/*
372 			 * In the standard case if the looping flag is set and
373 			 * performing dotdot we would be returning from a
374 			 * covered vnode, implying vfsp could not be null. The
375 			 * exceptions being if we have looping and overlay
376 			 * mounts or looping and covered file systems.
377 			 */
378 			if (vfsp == NULL) {
379 				/*
380 				 * Overlay mount or covered file system,
381 				 * so just make the shadow node.
382 				 */
383 				vn_vfsunlock(realdvp);
384 				*vpp = makelonode(vp, li, 0);
385 				(vtol(*vpp))->lo_looping |= LO_LOOPING;
386 				return (0);
387 			}
388 			/*
389 			 * When looping get the actual found vnode
390 			 * instead of the vnode covered.
391 			 * Here we have to hold the lock for realdvp
392 			 * since an unmount during the traversal to the
393 			 * root vnode would turn *vfsp into garbage
394 			 * which would be fatal.
395 			 */
396 			error = VFS_ROOT(vfsp, &tvp);
397 			vn_vfsunlock(realdvp);
398 
399 			if (error)
400 				goto out;
401 
402 			if ((tvp == li->li_rootvp) && (vp == realvp(tvp))) {
403 				/*
404 				 * we're back at the real vnode
405 				 * of the rootvp
406 				 *
407 				 * return the rootvp
408 				 * Ex: /mnt/mnt/..
409 				 * where / has been lofs-mounted
410 				 * onto /mnt.  Return the lofs
411 				 * node mounted at /mnt.
412 				 */
413 				*vpp = tvp;
414 				VN_RELE(vp);
415 				return (0);
416 			} else {
417 				/*
418 				 * We are returning from a covered
419 				 * node whose vfs_mountedhere is
420 				 * not pointing to vfs of the current
421 				 * root vnode.
422 				 * This is a condn where in we
423 				 * returned a covered node say Zc
424 				 * but Zc is not the cover of current
425 				 * root.
426 				 * i.e.., if X is the root vnode
427 				 * lookup(Zc,"..") is taking us to
428 				 * X.
429 				 * Ex: /net/X/net/X/Y
430 				 *
431 				 * If LO_AUTOLOOP (autofs/lofs looping detected)
432 				 * has been set then we are encountering the
433 				 * cover of Y (Y being any directory vnode
434 				 * under /net/X/net/X/).
435 				 * When performing a dotdot set the
436 				 * returned vp to the vnode covered
437 				 * by the mounted lofs, ie /net/X/net/X
438 				 */
439 				VN_RELE(tvp);
440 				if ((vtol(dvp))->lo_looping & LO_AUTOLOOP) {
441 					VN_RELE(vp);
442 					vp = li->li_rootvp;
443 					vp = vp->v_vfsp->vfs_vnodecovered;
444 					VN_HOLD(vp);
445 					*vpp = makelonode(vp, li, 0);
446 					(vtol(*vpp))->lo_looping |= LO_LOOPING;
447 					return (0);
448 				}
449 			}
450 		} else {
451 			/*
452 			 * No frills just make the shadow node.
453 			 */
454 			*vpp = makelonode(vp, li, 0);
455 			return (0);
456 		}
457 	}
458 
459 	nosub = (vtoli(dvp->v_vfsp)->li_flag & LO_NOSUB);
460 
461 	/*
462 	 * If this vnode is mounted on, then we
463 	 * traverse to the vnode which is the root of
464 	 * the mounted file system.
465 	 */
466 	if (!nosub && (error = traverse(&vp)))
467 		goto out;
468 
469 	/*
470 	 * Make a lnode for the real vnode.
471 	 */
472 	if (vp->v_type != VDIR || nosub) {
473 		*vpp = makelonode(vp, li, 0);
474 		if (IS_DEVVP(*vpp)) {
475 			vnode_t *svp;
476 
477 			svp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, cr);
478 			VN_RELE(*vpp);
479 			if (svp == NULL)
480 				error = ENOSYS;
481 			else
482 				*vpp = svp;
483 		}
484 		return (error);
485 	}
486 
487 	/*
488 	 * if the found vnode (vp) is not of type lofs
489 	 * then we're just going to make a shadow of that
490 	 * vp and get out.
491 	 *
492 	 * If the found vnode (vp) is of lofs type, and
493 	 * we're not doing dotdot, check if we are
494 	 * looping.
495 	 */
496 	if (!doingdotdot && vfs_matchops(vp->v_vfsp, lo_vfsops)) {
497 		/*
498 		 * Check if we're looping, i.e.
499 		 * vp equals the root vp of the lofs, directly
500 		 * or indirectly, return the covered node.
501 		 */
502 
503 		if (!((vtol(dvp))->lo_looping & LO_LOOPING)) {
504 			if (vp == li->li_rootvp) {
505 				/*
506 				 * Direct looping condn.
507 				 * Ex:- X is / mounted directory so lookup of
508 				 * /X/X is a direct looping condn.
509 				 */
510 				tvp = vp;
511 				vp = vp->v_vfsp->vfs_vnodecovered;
512 				VN_HOLD(vp);
513 				VN_RELE(tvp);
514 				looping++;
515 			} else {
516 				/*
517 				 * Indirect looping can be defined as
518 				 * real lookup returning rootvp of the current
519 				 * tree in any level of recursion.
520 				 *
521 				 * This check is useful if there are multiple
522 				 * levels of lofs indirections. Suppose vnode X
523 				 * in the current lookup has as its real vnode
524 				 * another lofs node. Y = realvp(X) Y should be
525 				 * a lofs node for the check to continue or Y
526 				 * is not the rootvp of X.
527 				 * Ex:- say X and Y are two vnodes
528 				 * say real(Y) is X and real(X) is Z
529 				 * parent vnode for X and Y is Z
530 				 * lookup(Y,"path") say we are looking for Y
531 				 * again under Y and we have to return Yc.
532 				 * but the lookup of Y under Y doesnot return
533 				 * Y the root vnode again here is why.
534 				 * 1. lookup(Y,"path of Y") will go to
535 				 * 2. lookup(real(Y),"path of Y") and then to
536 				 * 3. lookup(real(X),"path of Y").
537 				 * and now what lookup level 1 sees is the
538 				 * outcome of 2 but the vnode Y is due to
539 				 * lookup(Z,"path of Y") so we have to skip
540 				 * intermediate levels to find if in any level
541 				 * there is a looping.
542 				 */
543 				is_indirectloop = 0;
544 				nonlovp = vp;
545 				while (
546 				    vfs_matchops(nonlovp->v_vfsp, lo_vfsops) &&
547 				    !(is_indirectloop)) {
548 					if (li->li_rootvp  == nonlovp) {
549 						is_indirectloop++;
550 						break;
551 					}
552 					nonlovp = realvp(nonlovp);
553 				}
554 
555 				if (is_indirectloop) {
556 					VN_RELE(vp);
557 					vp = nonlovp;
558 					vp = vp->v_vfsp->vfs_vnodecovered;
559 					VN_HOLD(vp);
560 					looping++;
561 				}
562 			}
563 		} else {
564 			/*
565 			 * come here only because of the interaction between
566 			 * the autofs and lofs.
567 			 *
568 			 * Lookup of "/net/X/net/X" will return a shadow of
569 			 * an autonode X_a which we call X_l.
570 			 *
571 			 * Lookup of anything under X_l, will trigger a call to
572 			 * auto_lookup(X_a,nm) which will eventually call
573 			 * lo_lookup(X_lr,nm) where X_lr is the root vnode of
574 			 * the current lofs.
575 			 *
576 			 * We come here only when we are called with X_l as dvp
577 			 * and look for something underneath.
578 			 *
579 			 * Now that an autofs/lofs looping condition has been
580 			 * identified any directory vnode contained within
581 			 * dvp will be set to the vnode covered by the
582 			 * mounted autofs. Thus all directories within dvp
583 			 * will appear empty hence teminating the looping.
584 			 * The LO_AUTOLOOP flag is set on the returned lonode
585 			 * to indicate the termination of the autofs/lofs
586 			 * looping. This is required for the correct behaviour
587 			 * when performing a dotdot.
588 			 */
589 			realdvp = realvp(dvp);
590 			while (vfs_matchops(realdvp->v_vfsp, lo_vfsops)) {
591 				realdvp = realvp(realdvp);
592 			}
593 
594 			error = VFS_ROOT(realdvp->v_vfsp, &tvp);
595 			if (error)
596 				goto out;
597 			/*
598 			 * tvp now contains the rootvp of the vfs of the
599 			 * real vnode of dvp. The directory vnode vp is set
600 			 * to the covered vnode to terminate looping. No
601 			 * distinction is made between any vp as all directory
602 			 * vnodes contained in dvp are returned as the covered
603 			 * vnode.
604 			 */
605 			VN_RELE(vp);
606 			vp = tvp;	/* possibly is an autonode */
607 
608 			/*
609 			 * Need to find the covered vnode
610 			 */
611 			if (vp->v_vfsp->vfs_vnodecovered == NULL) {
612 				/*
613 				 * We don't have a covered vnode so this isn't
614 				 * an autonode. To find the autonode simply
615 				 * find the vnode covered by the lofs rootvp.
616 				 */
617 				vp = li->li_rootvp;
618 				vp = vp->v_vfsp->vfs_vnodecovered;
619 				VN_RELE(tvp);
620 				error = VFS_ROOT(vp->v_vfsp, &tvp);
621 				if (error)
622 					goto out;
623 				vp = tvp;	/* now this is an autonode */
624 				if (vp->v_vfsp->vfs_vnodecovered == NULL) {
625 					/*
626 					 * Still can't find a covered vnode.
627 					 * Fail the lookup, or we'd loop.
628 					 */
629 					error = ENOENT;
630 					goto out;
631 				}
632 			}
633 			vp = vp->v_vfsp->vfs_vnodecovered;
634 			VN_HOLD(vp);
635 			VN_RELE(tvp);
636 			/*
637 			 * Force the creation of a new lnode even if the hash
638 			 * table contains a lnode that references this vnode.
639 			 */
640 			mkflag = LOF_FORCE;
641 			autoloop++;
642 		}
643 	}
644 	*vpp = makelonode(vp, li, mkflag);
645 
646 	if ((looping) ||
647 	    (((vtol(dvp))->lo_looping & LO_LOOPING) && !doingdotdot)) {
648 		(vtol(*vpp))->lo_looping |= LO_LOOPING;
649 	}
650 
651 	if (autoloop) {
652 		(vtol(*vpp))->lo_looping |= LO_AUTOLOOP;
653 	}
654 
655 out:
656 	if (error != 0 && vp != NULL)
657 		VN_RELE(vp);
658 #ifdef LODEBUG
659 	lo_dprint(4,
660 	"lo_lookup dvp %x realdvp %x nm '%s' newvp %x real vp %x error %d\n",
661 		dvp, realvp(dvp), nm, *vpp, vp, error);
662 #endif
663 	return (error);
664 }
665 
666 /*ARGSUSED*/
667 static int
668 lo_create(
669 	vnode_t *dvp,
670 	char *nm,
671 	struct vattr *va,
672 	enum vcexcl exclusive,
673 	int mode,
674 	vnode_t **vpp,
675 	struct cred *cr,
676 	int flag)
677 {
678 	int error;
679 	vnode_t *vp = NULL;
680 	vnode_t *tvp = NULL;
681 
682 #ifdef LODEBUG
683 	lo_dprint(4, "lo_create vp %p realvp %p\n", dvp, realvp(dvp));
684 #endif
685 	if (*nm == '\0') {
686 		ASSERT(vpp && dvp == *vpp);
687 		vp = realvp(*vpp);
688 	}
689 
690 	if (IS_ZONEDEVFS(dvp)) {
691 
692 		/*
693 		 * In the case of an exclusive create, *vpp will not
694 		 * be populated.  We must check to see if the file exists.
695 		 */
696 		if ((exclusive == EXCL) && (*nm != '\0')) {
697 			(void) VOP_LOOKUP(dvp, nm, &tvp, NULL, 0, NULL, cr);
698 		}
699 
700 		/* Is this truly a create?  If so, fail */
701 		if ((*vpp == NULL) && (tvp == NULL))
702 			return (EACCES);
703 
704 		if (tvp != NULL)
705 			VN_RELE(tvp);
706 
707 		/* Is this an open of a non-special for writing?  If so, fail */
708 		if (*vpp != NULL && (mode & VWRITE) && !IS_DEVVP(*vpp))
709 			return (EACCES);
710 	}
711 
712 	error = VOP_CREATE(realvp(dvp), nm, va, exclusive, mode, &vp, cr, flag);
713 	if (!error) {
714 		*vpp = makelonode(vp, vtoli(dvp->v_vfsp), 0);
715 		if (IS_DEVVP(*vpp)) {
716 			vnode_t *svp;
717 
718 			svp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, cr);
719 			VN_RELE(*vpp);
720 			if (svp == NULL)
721 				error = ENOSYS;
722 			else
723 				*vpp = svp;
724 		}
725 	}
726 	return (error);
727 }
728 
729 static int
730 lo_remove(vnode_t *dvp, char *nm, struct cred *cr)
731 {
732 #ifdef LODEBUG
733 	lo_dprint(4, "lo_remove vp %p realvp %p\n", dvp, realvp(dvp));
734 #endif
735 	if (IS_ZONEDEVFS(dvp))
736 		return (EACCES);
737 	dvp = realvp(dvp);
738 	return (VOP_REMOVE(dvp, nm, cr));
739 }
740 
741 static int
742 lo_link(vnode_t *tdvp, vnode_t *vp, char *tnm, struct cred *cr)
743 {
744 #ifdef LODEBUG
745 	lo_dprint(4, "lo_link vp %p realvp %p\n", vp, realvp(vp));
746 #endif
747 	while (vn_matchops(vp, lo_vnodeops)) {
748 		if (IS_ZONEDEVFS(vp))
749 			return (EACCES);
750 		vp = realvp(vp);
751 	}
752 	while (vn_matchops(tdvp, lo_vnodeops)) {
753 		if (IS_ZONEDEVFS(tdvp))
754 			return (EACCES);
755 		tdvp = realvp(tdvp);
756 	}
757 	if (vp->v_vfsp != tdvp->v_vfsp)
758 		return (EXDEV);
759 	return (VOP_LINK(tdvp, vp, tnm, cr));
760 }
761 
762 static int
763 lo_rename(
764 	vnode_t *odvp,
765 	char *onm,
766 	vnode_t *ndvp,
767 	char *nnm,
768 	struct cred *cr)
769 {
770 	vnode_t *tnvp;
771 
772 #ifdef LODEBUG
773 	lo_dprint(4, "lo_rename vp %p realvp %p\n", odvp, realvp(odvp));
774 #endif
775 	if (IS_ZONEDEVFS(odvp))
776 		return (EACCES);
777 	/*
778 	 * If we are coming from a loop back mounted fs, that has been
779 	 * mounted in the same filesystem as where we want to move to,
780 	 * and that filesystem is read/write, but the lofs filesystem is
781 	 * read only, we don't want to allow a rename of the file. The
782 	 * vn_rename code checks to be sure the target is read/write already
783 	 * so that is not necessary here. However, consider the following
784 	 * example:
785 	 *		/ - regular root fs
786 	 *		/foo - directory in root
787 	 *		/foo/bar - file in foo directory(in root fs)
788 	 *		/baz - directory in root
789 	 *		mount -F lofs -o ro /foo /baz - all still in root
790 	 *			directory
791 	 * The fact that we mounted /foo on /baz read only should stop us
792 	 * from renaming the file /foo/bar /bar, but it doesn't since
793 	 * / is read/write. We are still renaming here since we are still
794 	 * in the same filesystem, it is just that we do not check to see
795 	 * if the filesystem we are coming from in this case is read only.
796 	 */
797 	if (odvp->v_vfsp->vfs_flag & VFS_RDONLY)
798 		return (EROFS);
799 	/*
800 	 * We need to make sure we're not trying to remove a mount point for a
801 	 * filesystem mounted on top of lofs, which only we know about.
802 	 */
803 	if (vn_matchops(ndvp, lo_vnodeops))	/* Not our problem. */
804 		goto rename;
805 	if (VOP_LOOKUP(ndvp, nnm, &tnvp, NULL, 0, NULL, cr) != 0)
806 		goto rename;
807 	if (tnvp->v_type != VDIR) {
808 		VN_RELE(tnvp);
809 		goto rename;
810 	}
811 	if (vn_mountedvfs(tnvp)) {
812 		VN_RELE(tnvp);
813 		return (EBUSY);
814 	}
815 	VN_RELE(tnvp);
816 rename:
817 	/*
818 	 * Since the case we're dealing with above can happen at any layer in
819 	 * the stack of lofs filesystems, we need to recurse down the stack,
820 	 * checking to see if there are any instances of a filesystem mounted on
821 	 * top of lofs. In order to keep on using the lofs version of
822 	 * VOP_RENAME(), we make sure that while the target directory is of type
823 	 * lofs, the source directory (the one used for getting the fs-specific
824 	 * version of VOP_RENAME()) is also of type lofs.
825 	 */
826 	if (vn_matchops(ndvp, lo_vnodeops)) {
827 		if (IS_ZONEDEVFS(ndvp))
828 			return (EACCES);
829 		ndvp = realvp(ndvp);	/* Check the next layer */
830 	} else {
831 		/*
832 		 * We can go fast here
833 		 */
834 		while (vn_matchops(odvp, lo_vnodeops)) {
835 			if (IS_ZONEDEVFS(odvp))
836 				return (EACCES);
837 			odvp = realvp(odvp);
838 		}
839 		if (odvp->v_vfsp != ndvp->v_vfsp)
840 			return (EXDEV);
841 	}
842 	return (VOP_RENAME(odvp, onm, ndvp, nnm, cr));
843 }
844 
845 static int
846 lo_mkdir(
847 	vnode_t *dvp,
848 	char *nm,
849 	struct vattr *va,
850 	vnode_t **vpp,
851 	struct cred *cr)
852 {
853 	int error;
854 
855 #ifdef LODEBUG
856 	lo_dprint(4, "lo_mkdir vp %p realvp %p\n", dvp, realvp(dvp));
857 #endif
858 	if (IS_ZONEDEVFS(dvp))
859 		return (EACCES);
860 	error = VOP_MKDIR(realvp(dvp), nm, va, vpp, cr);
861 	if (!error)
862 		*vpp = makelonode(*vpp, vtoli(dvp->v_vfsp), 0);
863 	return (error);
864 }
865 
866 static int
867 lo_realvp(vnode_t *vp, vnode_t **vpp)
868 {
869 #ifdef LODEBUG
870 	lo_dprint(4, "lo_realvp %p\n", vp);
871 #endif
872 	while (vn_matchops(vp, lo_vnodeops))
873 		vp = realvp(vp);
874 
875 	if (VOP_REALVP(vp, vpp) != 0)
876 		*vpp = vp;
877 	return (0);
878 }
879 
880 static int
881 lo_rmdir(
882 	vnode_t *dvp,
883 	char *nm,
884 	vnode_t *cdir,
885 	struct cred *cr)
886 {
887 	vnode_t *rvp = cdir;
888 
889 #ifdef LODEBUG
890 	lo_dprint(4, "lo_rmdir vp %p realvp %p\n", dvp, realvp(dvp));
891 #endif
892 	if (IS_ZONEDEVFS(dvp))
893 		return (EACCES);
894 	/* if cdir is lofs vnode ptr get its real vnode ptr */
895 	if (vn_matchops(dvp, vn_getops(rvp)))
896 		(void) lo_realvp(cdir, &rvp);
897 	dvp = realvp(dvp);
898 	return (VOP_RMDIR(dvp, nm, rvp, cr));
899 }
900 
901 static int
902 lo_symlink(
903 	vnode_t *dvp,
904 	char *lnm,
905 	struct vattr *tva,
906 	char *tnm,
907 	struct cred *cr)
908 {
909 #ifdef LODEBUG
910 	lo_dprint(4, "lo_symlink vp %p realvp %p\n", dvp, realvp(dvp));
911 #endif
912 	if (IS_ZONEDEVFS(dvp))
913 		return (EACCES);
914 	dvp = realvp(dvp);
915 	return (VOP_SYMLINK(dvp, lnm, tva, tnm, cr));
916 }
917 
918 static int
919 lo_readlink(vnode_t *vp, struct uio *uiop, struct cred *cr)
920 {
921 	vp = realvp(vp);
922 	return (VOP_READLINK(vp, uiop, cr));
923 }
924 
925 static int
926 lo_readdir(vnode_t *vp, struct uio *uiop, struct cred *cr, int *eofp)
927 {
928 #ifdef LODEBUG
929 	lo_dprint(4, "lo_readdir vp %p realvp %p\n", vp, realvp(vp));
930 #endif
931 	vp = realvp(vp);
932 	return (VOP_READDIR(vp, uiop, cr, eofp));
933 }
934 
935 static int
936 lo_rwlock(vnode_t *vp, int write_lock, caller_context_t *ct)
937 {
938 	vp = realvp(vp);
939 	return (VOP_RWLOCK(vp, write_lock, ct));
940 }
941 
942 static void
943 lo_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ct)
944 {
945 	vp = realvp(vp);
946 	VOP_RWUNLOCK(vp, write_lock, ct);
947 }
948 
949 static int
950 lo_seek(vnode_t *vp, offset_t ooff, offset_t *noffp)
951 {
952 	vp = realvp(vp);
953 	return (VOP_SEEK(vp, ooff, noffp));
954 }
955 
956 static int
957 lo_cmp(vnode_t *vp1, vnode_t *vp2)
958 {
959 	while (vn_matchops(vp1, lo_vnodeops))
960 		vp1 = realvp(vp1);
961 	while (vn_matchops(vp2, lo_vnodeops))
962 		vp2 = realvp(vp2);
963 	return (VOP_CMP(vp1, vp2));
964 }
965 
966 static int
967 lo_frlock(
968 	vnode_t *vp,
969 	int cmd,
970 	struct flock64 *bfp,
971 	int flag,
972 	offset_t offset,
973 	struct flk_callback *flk_cbp,
974 	cred_t *cr)
975 {
976 	vp = realvp(vp);
977 	return (VOP_FRLOCK(vp, cmd, bfp, flag, offset, flk_cbp, cr));
978 }
979 
980 static int
981 lo_space(
982 	vnode_t *vp,
983 	int cmd,
984 	struct flock64 *bfp,
985 	int flag,
986 	offset_t offset,
987 	struct cred *cr,
988 	caller_context_t *ct)
989 {
990 	vp = realvp(vp);
991 	return (VOP_SPACE(vp, cmd, bfp, flag, offset, cr, ct));
992 }
993 
994 static int
995 lo_getpage(
996 	vnode_t *vp,
997 	offset_t off,
998 	size_t len,
999 	uint_t *prot,
1000 	struct page *parr[],
1001 	size_t psz,
1002 	struct seg *seg,
1003 	caddr_t addr,
1004 	enum seg_rw rw,
1005 	struct cred *cr)
1006 {
1007 	vp = realvp(vp);
1008 	return (VOP_GETPAGE(vp, off, len, prot, parr, psz, seg, addr, rw, cr));
1009 }
1010 
1011 static int
1012 lo_putpage(vnode_t *vp, offset_t off, size_t len, int flags, struct cred *cr)
1013 {
1014 	vp = realvp(vp);
1015 	return (VOP_PUTPAGE(vp, off, len, flags, cr));
1016 }
1017 
1018 static int
1019 lo_map(
1020 	vnode_t *vp,
1021 	offset_t off,
1022 	struct as *as,
1023 	caddr_t *addrp,
1024 	size_t len,
1025 	uchar_t prot,
1026 	uchar_t maxprot,
1027 	uint_t flags,
1028 	struct cred *cr)
1029 {
1030 	vp = realvp(vp);
1031 	return (VOP_MAP(vp, off, as, addrp, len, prot, maxprot, flags, cr));
1032 }
1033 
1034 static int
1035 lo_addmap(
1036 	vnode_t *vp,
1037 	offset_t off,
1038 	struct as *as,
1039 	caddr_t addr,
1040 	size_t len,
1041 	uchar_t prot,
1042 	uchar_t maxprot,
1043 	uint_t flags,
1044 	struct cred *cr)
1045 {
1046 	vp = realvp(vp);
1047 	return (VOP_ADDMAP(vp, off, as, addr, len, prot, maxprot, flags, cr));
1048 }
1049 
1050 static int
1051 lo_delmap(
1052 	vnode_t *vp,
1053 	offset_t off,
1054 	struct as *as,
1055 	caddr_t addr,
1056 	size_t len,
1057 	uint_t prot,
1058 	uint_t maxprot,
1059 	uint_t flags,
1060 	struct cred *cr)
1061 {
1062 	vp = realvp(vp);
1063 	return (VOP_DELMAP(vp, off, as, addr, len, prot, maxprot, flags, cr));
1064 }
1065 
1066 static int
1067 lo_poll(
1068 	vnode_t *vp,
1069 	short events,
1070 	int anyyet,
1071 	short *reventsp,
1072 	struct pollhead **phpp)
1073 {
1074 	vp = realvp(vp);
1075 	return (VOP_POLL(vp, events, anyyet, reventsp, phpp));
1076 }
1077 
1078 static int
1079 lo_dump(vnode_t *vp, caddr_t addr, int bn, int count)
1080 {
1081 	vp = realvp(vp);
1082 	return (VOP_DUMP(vp, addr, bn, count));
1083 }
1084 
1085 static int
1086 lo_pathconf(vnode_t *vp, int cmd, ulong_t *valp, struct cred *cr)
1087 {
1088 	vp = realvp(vp);
1089 	return (VOP_PATHCONF(vp, cmd, valp, cr));
1090 }
1091 
1092 static int
1093 lo_pageio(
1094 	vnode_t *vp,
1095 	struct page *pp,
1096 	u_offset_t io_off,
1097 	size_t io_len,
1098 	int flags,
1099 	cred_t *cr)
1100 {
1101 	vp = realvp(vp);
1102 	return (VOP_PAGEIO(vp, pp, io_off, io_len, flags, cr));
1103 }
1104 
1105 static void
1106 lo_dispose(vnode_t *vp, page_t *pp, int fl, int dn, cred_t *cr)
1107 {
1108 	vp = realvp(vp);
1109 	if (vp != NULL && vp != &kvp)
1110 		VOP_DISPOSE(vp, pp, fl, dn, cr);
1111 }
1112 
1113 static int
1114 lo_setsecattr(vnode_t *vp, vsecattr_t *secattr, int flags, struct cred *cr)
1115 {
1116 	if (vn_is_readonly(vp))
1117 		return (EROFS);
1118 	vp = realvp(vp);
1119 	return (VOP_SETSECATTR(vp, secattr, flags, cr));
1120 }
1121 
1122 static int
1123 lo_getsecattr(vnode_t *vp, vsecattr_t *secattr, int flags, struct cred *cr)
1124 {
1125 	vp = realvp(vp);
1126 	return (VOP_GETSECATTR(vp, secattr, flags, cr));
1127 }
1128 
1129 static int
1130 lo_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr)
1131 {
1132 	vp = realvp(vp);
1133 	return (VOP_SHRLOCK(vp, cmd, shr, flag, cr));
1134 }
1135 
1136 /*
1137  * Loopback vnode operations vector.
1138  */
1139 
1140 struct vnodeops *lo_vnodeops;
1141 
1142 const fs_operation_def_t lo_vnodeops_template[] = {
1143 	VOPNAME_OPEN, lo_open,
1144 	VOPNAME_CLOSE, lo_close,
1145 	VOPNAME_READ, lo_read,
1146 	VOPNAME_WRITE, lo_write,
1147 	VOPNAME_IOCTL, lo_ioctl,
1148 	VOPNAME_SETFL, lo_setfl,
1149 	VOPNAME_GETATTR, lo_getattr,
1150 	VOPNAME_SETATTR, lo_setattr,
1151 	VOPNAME_ACCESS, lo_access,
1152 	VOPNAME_LOOKUP, lo_lookup,
1153 	VOPNAME_CREATE, lo_create,
1154 	VOPNAME_REMOVE, lo_remove,
1155 	VOPNAME_LINK, lo_link,
1156 	VOPNAME_RENAME, lo_rename,
1157 	VOPNAME_MKDIR, lo_mkdir,
1158 	VOPNAME_RMDIR, lo_rmdir,
1159 	VOPNAME_READDIR, lo_readdir,
1160 	VOPNAME_SYMLINK, lo_symlink,
1161 	VOPNAME_READLINK, lo_readlink,
1162 	VOPNAME_FSYNC, lo_fsync,
1163 	VOPNAME_INACTIVE, (fs_generic_func_p) lo_inactive,
1164 	VOPNAME_FID, lo_fid,
1165 	VOPNAME_RWLOCK, lo_rwlock,
1166 	VOPNAME_RWUNLOCK, (fs_generic_func_p) lo_rwunlock,
1167 	VOPNAME_SEEK, lo_seek,
1168 	VOPNAME_CMP, lo_cmp,
1169 	VOPNAME_FRLOCK, lo_frlock,
1170 	VOPNAME_SPACE, lo_space,
1171 	VOPNAME_REALVP, lo_realvp,
1172 	VOPNAME_GETPAGE, lo_getpage,
1173 	VOPNAME_PUTPAGE, lo_putpage,
1174 	VOPNAME_MAP, (fs_generic_func_p) lo_map,
1175 	VOPNAME_ADDMAP, (fs_generic_func_p) lo_addmap,
1176 	VOPNAME_DELMAP, lo_delmap,
1177 	VOPNAME_POLL, (fs_generic_func_p) lo_poll,
1178 	VOPNAME_DUMP, lo_dump,
1179 	VOPNAME_DUMPCTL, fs_error,		/* XXX - why? */
1180 	VOPNAME_PATHCONF, lo_pathconf,
1181 	VOPNAME_PAGEIO, lo_pageio,
1182 	VOPNAME_DISPOSE, (fs_generic_func_p) lo_dispose,
1183 	VOPNAME_SETSECATTR, lo_setsecattr,
1184 	VOPNAME_GETSECATTR, lo_getsecattr,
1185 	VOPNAME_SHRLOCK, lo_shrlock,
1186 	NULL, NULL
1187 };
1188