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