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 * We need to make sure we're not trying to remove a mount point for a 779 * filesystem mounted on top of lofs, which only we know about. 780 */ 781 if (vn_matchops(ndvp, lo_vnodeops)) /* Not our problem. */ 782 goto rename; 783 if (VOP_LOOKUP(ndvp, nnm, &tnvp, NULL, 0, NULL, cr) != 0) 784 goto rename; 785 if (tnvp->v_type != VDIR) { 786 VN_RELE(tnvp); 787 goto rename; 788 } 789 if (vn_mountedvfs(tnvp)) { 790 VN_RELE(tnvp); 791 return (EBUSY); 792 } 793 VN_RELE(tnvp); 794 rename: 795 /* 796 * Since the case we're dealing with above can happen at any layer in 797 * the stack of lofs filesystems, we need to recurse down the stack, 798 * checking to see if there are any instances of a filesystem mounted on 799 * top of lofs. In order to keep on using the lofs version of 800 * VOP_RENAME(), we make sure that while the target directory is of type 801 * lofs, the source directory (the one used for getting the fs-specific 802 * version of VOP_RENAME()) is also of type lofs. 803 */ 804 if (vn_matchops(ndvp, lo_vnodeops)) { 805 if (IS_ZONEDEVFS(ndvp)) 806 return (EACCES); 807 ndvp = realvp(ndvp); /* Check the next layer */ 808 } else { 809 /* 810 * We can go fast here 811 */ 812 while (vn_matchops(odvp, lo_vnodeops)) { 813 if (IS_ZONEDEVFS(odvp)) 814 return (EACCES); 815 odvp = realvp(odvp); 816 } 817 if (odvp->v_vfsp != ndvp->v_vfsp) 818 return (EXDEV); 819 } 820 return (VOP_RENAME(odvp, onm, ndvp, nnm, cr)); 821 } 822 823 static int 824 lo_mkdir( 825 vnode_t *dvp, 826 char *nm, 827 struct vattr *va, 828 vnode_t **vpp, 829 struct cred *cr) 830 { 831 int error; 832 833 #ifdef LODEBUG 834 lo_dprint(4, "lo_mkdir vp %p realvp %p\n", dvp, realvp(dvp)); 835 #endif 836 if (IS_ZONEDEVFS(dvp)) 837 return (EACCES); 838 error = VOP_MKDIR(realvp(dvp), nm, va, vpp, cr); 839 if (!error) 840 *vpp = makelonode(*vpp, vtoli(dvp->v_vfsp), 0); 841 return (error); 842 } 843 844 static int 845 lo_realvp(vnode_t *vp, vnode_t **vpp) 846 { 847 #ifdef LODEBUG 848 lo_dprint(4, "lo_realvp %p\n", vp); 849 #endif 850 while (vn_matchops(vp, lo_vnodeops)) 851 vp = realvp(vp); 852 853 if (VOP_REALVP(vp, vpp) != 0) 854 *vpp = vp; 855 return (0); 856 } 857 858 static int 859 lo_rmdir( 860 vnode_t *dvp, 861 char *nm, 862 vnode_t *cdir, 863 struct cred *cr) 864 { 865 vnode_t *rvp = cdir; 866 867 #ifdef LODEBUG 868 lo_dprint(4, "lo_rmdir vp %p realvp %p\n", dvp, realvp(dvp)); 869 #endif 870 if (IS_ZONEDEVFS(dvp)) 871 return (EACCES); 872 /* if cdir is lofs vnode ptr get its real vnode ptr */ 873 if (vn_matchops(dvp, vn_getops(rvp))) 874 (void) lo_realvp(cdir, &rvp); 875 dvp = realvp(dvp); 876 return (VOP_RMDIR(dvp, nm, rvp, cr)); 877 } 878 879 static int 880 lo_symlink( 881 vnode_t *dvp, 882 char *lnm, 883 struct vattr *tva, 884 char *tnm, 885 struct cred *cr) 886 { 887 #ifdef LODEBUG 888 lo_dprint(4, "lo_symlink vp %p realvp %p\n", dvp, realvp(dvp)); 889 #endif 890 if (IS_ZONEDEVFS(dvp)) 891 return (EACCES); 892 dvp = realvp(dvp); 893 return (VOP_SYMLINK(dvp, lnm, tva, tnm, cr)); 894 } 895 896 static int 897 lo_readlink(vnode_t *vp, struct uio *uiop, struct cred *cr) 898 { 899 vp = realvp(vp); 900 return (VOP_READLINK(vp, uiop, cr)); 901 } 902 903 static int 904 lo_readdir(vnode_t *vp, struct uio *uiop, struct cred *cr, int *eofp) 905 { 906 #ifdef LODEBUG 907 lo_dprint(4, "lo_readdir vp %p realvp %p\n", vp, realvp(vp)); 908 #endif 909 vp = realvp(vp); 910 return (VOP_READDIR(vp, uiop, cr, eofp)); 911 } 912 913 static int 914 lo_rwlock(vnode_t *vp, int write_lock, caller_context_t *ct) 915 { 916 vp = realvp(vp); 917 return (VOP_RWLOCK(vp, write_lock, ct)); 918 } 919 920 static void 921 lo_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ct) 922 { 923 vp = realvp(vp); 924 VOP_RWUNLOCK(vp, write_lock, ct); 925 } 926 927 static int 928 lo_seek(vnode_t *vp, offset_t ooff, offset_t *noffp) 929 { 930 vp = realvp(vp); 931 return (VOP_SEEK(vp, ooff, noffp)); 932 } 933 934 static int 935 lo_cmp(vnode_t *vp1, vnode_t *vp2) 936 { 937 while (vn_matchops(vp1, lo_vnodeops)) 938 vp1 = realvp(vp1); 939 while (vn_matchops(vp2, lo_vnodeops)) 940 vp2 = realvp(vp2); 941 return (VOP_CMP(vp1, vp2)); 942 } 943 944 static int 945 lo_frlock( 946 vnode_t *vp, 947 int cmd, 948 struct flock64 *bfp, 949 int flag, 950 offset_t offset, 951 struct flk_callback *flk_cbp, 952 cred_t *cr) 953 { 954 vp = realvp(vp); 955 return (VOP_FRLOCK(vp, cmd, bfp, flag, offset, flk_cbp, cr)); 956 } 957 958 static int 959 lo_space( 960 vnode_t *vp, 961 int cmd, 962 struct flock64 *bfp, 963 int flag, 964 offset_t offset, 965 struct cred *cr, 966 caller_context_t *ct) 967 { 968 vp = realvp(vp); 969 return (VOP_SPACE(vp, cmd, bfp, flag, offset, cr, ct)); 970 } 971 972 static int 973 lo_getpage( 974 vnode_t *vp, 975 offset_t off, 976 size_t len, 977 uint_t *prot, 978 struct page *parr[], 979 size_t psz, 980 struct seg *seg, 981 caddr_t addr, 982 enum seg_rw rw, 983 struct cred *cr) 984 { 985 vp = realvp(vp); 986 return (VOP_GETPAGE(vp, off, len, prot, parr, psz, seg, addr, rw, cr)); 987 } 988 989 static int 990 lo_putpage(vnode_t *vp, offset_t off, size_t len, int flags, struct cred *cr) 991 { 992 vp = realvp(vp); 993 return (VOP_PUTPAGE(vp, off, len, flags, cr)); 994 } 995 996 static int 997 lo_map( 998 vnode_t *vp, 999 offset_t off, 1000 struct as *as, 1001 caddr_t *addrp, 1002 size_t len, 1003 uchar_t prot, 1004 uchar_t maxprot, 1005 uint_t flags, 1006 struct cred *cr) 1007 { 1008 vp = realvp(vp); 1009 return (VOP_MAP(vp, off, as, addrp, len, prot, maxprot, flags, cr)); 1010 } 1011 1012 static int 1013 lo_addmap( 1014 vnode_t *vp, 1015 offset_t off, 1016 struct as *as, 1017 caddr_t addr, 1018 size_t len, 1019 uchar_t prot, 1020 uchar_t maxprot, 1021 uint_t flags, 1022 struct cred *cr) 1023 { 1024 vp = realvp(vp); 1025 return (VOP_ADDMAP(vp, off, as, addr, len, prot, maxprot, flags, cr)); 1026 } 1027 1028 static int 1029 lo_delmap( 1030 vnode_t *vp, 1031 offset_t off, 1032 struct as *as, 1033 caddr_t addr, 1034 size_t len, 1035 uint_t prot, 1036 uint_t maxprot, 1037 uint_t flags, 1038 struct cred *cr) 1039 { 1040 vp = realvp(vp); 1041 return (VOP_DELMAP(vp, off, as, addr, len, prot, maxprot, flags, cr)); 1042 } 1043 1044 static int 1045 lo_poll( 1046 vnode_t *vp, 1047 short events, 1048 int anyyet, 1049 short *reventsp, 1050 struct pollhead **phpp) 1051 { 1052 vp = realvp(vp); 1053 return (VOP_POLL(vp, events, anyyet, reventsp, phpp)); 1054 } 1055 1056 static int 1057 lo_dump(vnode_t *vp, caddr_t addr, int bn, int count) 1058 { 1059 vp = realvp(vp); 1060 return (VOP_DUMP(vp, addr, bn, count)); 1061 } 1062 1063 static int 1064 lo_pathconf(vnode_t *vp, int cmd, ulong_t *valp, struct cred *cr) 1065 { 1066 vp = realvp(vp); 1067 return (VOP_PATHCONF(vp, cmd, valp, cr)); 1068 } 1069 1070 static int 1071 lo_pageio( 1072 vnode_t *vp, 1073 struct page *pp, 1074 u_offset_t io_off, 1075 size_t io_len, 1076 int flags, 1077 cred_t *cr) 1078 { 1079 vp = realvp(vp); 1080 return (VOP_PAGEIO(vp, pp, io_off, io_len, flags, cr)); 1081 } 1082 1083 static void 1084 lo_dispose(vnode_t *vp, page_t *pp, int fl, int dn, cred_t *cr) 1085 { 1086 vp = realvp(vp); 1087 if (vp != NULL && vp != &kvp) 1088 VOP_DISPOSE(vp, pp, fl, dn, cr); 1089 } 1090 1091 static int 1092 lo_setsecattr(vnode_t *vp, vsecattr_t *secattr, int flags, struct cred *cr) 1093 { 1094 if (vn_is_readonly(vp)) 1095 return (EROFS); 1096 vp = realvp(vp); 1097 return (VOP_SETSECATTR(vp, secattr, flags, cr)); 1098 } 1099 1100 static int 1101 lo_getsecattr(vnode_t *vp, vsecattr_t *secattr, int flags, struct cred *cr) 1102 { 1103 vp = realvp(vp); 1104 return (VOP_GETSECATTR(vp, secattr, flags, cr)); 1105 } 1106 1107 static int 1108 lo_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, cred_t *cr) 1109 { 1110 vp = realvp(vp); 1111 return (VOP_SHRLOCK(vp, cmd, shr, flag, cr)); 1112 } 1113 1114 /* 1115 * Loopback vnode operations vector. 1116 */ 1117 1118 struct vnodeops *lo_vnodeops; 1119 1120 const fs_operation_def_t lo_vnodeops_template[] = { 1121 VOPNAME_OPEN, lo_open, 1122 VOPNAME_CLOSE, lo_close, 1123 VOPNAME_READ, lo_read, 1124 VOPNAME_WRITE, lo_write, 1125 VOPNAME_IOCTL, lo_ioctl, 1126 VOPNAME_SETFL, lo_setfl, 1127 VOPNAME_GETATTR, lo_getattr, 1128 VOPNAME_SETATTR, lo_setattr, 1129 VOPNAME_ACCESS, lo_access, 1130 VOPNAME_LOOKUP, lo_lookup, 1131 VOPNAME_CREATE, lo_create, 1132 VOPNAME_REMOVE, lo_remove, 1133 VOPNAME_LINK, lo_link, 1134 VOPNAME_RENAME, lo_rename, 1135 VOPNAME_MKDIR, lo_mkdir, 1136 VOPNAME_RMDIR, lo_rmdir, 1137 VOPNAME_READDIR, lo_readdir, 1138 VOPNAME_SYMLINK, lo_symlink, 1139 VOPNAME_READLINK, lo_readlink, 1140 VOPNAME_FSYNC, lo_fsync, 1141 VOPNAME_INACTIVE, (fs_generic_func_p) lo_inactive, 1142 VOPNAME_FID, lo_fid, 1143 VOPNAME_RWLOCK, lo_rwlock, 1144 VOPNAME_RWUNLOCK, (fs_generic_func_p) lo_rwunlock, 1145 VOPNAME_SEEK, lo_seek, 1146 VOPNAME_CMP, lo_cmp, 1147 VOPNAME_FRLOCK, lo_frlock, 1148 VOPNAME_SPACE, lo_space, 1149 VOPNAME_REALVP, lo_realvp, 1150 VOPNAME_GETPAGE, lo_getpage, 1151 VOPNAME_PUTPAGE, lo_putpage, 1152 VOPNAME_MAP, (fs_generic_func_p) lo_map, 1153 VOPNAME_ADDMAP, (fs_generic_func_p) lo_addmap, 1154 VOPNAME_DELMAP, lo_delmap, 1155 VOPNAME_POLL, (fs_generic_func_p) lo_poll, 1156 VOPNAME_DUMP, lo_dump, 1157 VOPNAME_DUMPCTL, fs_error, /* XXX - why? */ 1158 VOPNAME_PATHCONF, lo_pathconf, 1159 VOPNAME_PAGEIO, lo_pageio, 1160 VOPNAME_DISPOSE, (fs_generic_func_p) lo_dispose, 1161 VOPNAME_SETSECATTR, lo_setsecattr, 1162 VOPNAME_GETSECATTR, lo_getsecattr, 1163 VOPNAME_SHRLOCK, lo_shrlock, 1164 NULL, NULL 1165 }; 1166