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