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