1 /* 2 * Copyright (c) 1992 The Regents of the University of California 3 * Copyright (c) 1990, 1992 Jan-Simon Pendry 4 * All rights reserved. 5 * 6 * This code is derived from software donated to Berkeley by 7 * Jan-Simon Pendry. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)lofs_vnops.c 1.2 (Berkeley) 06/18/92 12 * 13 * $Id: lofs_vnops.c,v 1.11 1992/05/30 10:05:43 jsp Exp jsp $ 14 */ 15 16 /* 17 * Loopback Filesystem 18 */ 19 20 #include <sys/param.h> 21 #include <sys/systm.h> 22 #include <sys/proc.h> 23 #include <sys/time.h> 24 #include <sys/types.h> 25 #include <sys/vnode.h> 26 #include <sys/mount.h> 27 #include <sys/namei.h> 28 #include <sys/malloc.h> 29 #include <sys/buf.h> 30 #include <lofs/lofs.h> 31 32 /* 33 * Basic strategy: as usual, do as little work as possible. 34 * Nothing is ever locked in the lofs'ed filesystem, all 35 * locks are held in the underlying filesystems. 36 */ 37 38 /* 39 * Save a vnode and replace with 40 * the lofs'ed one 41 */ 42 #define PUSHREF(v, nd) \ 43 { \ 44 struct { struct vnode *vnp; } v; \ 45 v.vnp = (nd); \ 46 (nd) = LOFSVP(v.vnp) 47 48 /* 49 * Undo the PUSHREF 50 */ 51 #define POP(v, nd) \ 52 \ 53 (nd) = v.vnp; \ 54 } 55 56 57 /* 58 * vp is the current namei directory 59 * ndp is the name to locate in that directory... 60 */ 61 lofs_lookup (ap) 62 struct vop_lookup_args *ap; 63 { 64 USES_VOP_LOOKUP; 65 struct vnode *dvp = ap->a_dvp; 66 struct vnode *newvp; 67 struct vnode *targetdvp; 68 int error; 69 int flag = ap->a_cnp->cn_nameiop /*& OPMASK*/; 70 71 #ifdef LOFS_DIAGNOSTIC 72 printf("lofs_lookup(ap->a_dvp = %x->%x, \"%s\", op = %d)\n", 73 dvp, LOFSVP(dvp), ap->a_cnp->cn_nameptr, flag); 74 #endif 75 76 /* 77 * (ap->a_dvp) was locked when passed in, and it will be replaced 78 * with the target vnode, BUT that will already have been 79 * locked when (ap->a_dvp) was locked [see lofs_lock]. all that 80 * must be done here is to keep track of reference counts. 81 */ 82 targetdvp = LOFSVP(dvp); 83 /*VREF(targetdvp);*/ 84 #ifdef LOFS_DIAGNOSTIC 85 vprint("lofs VOP_LOOKUP", targetdvp); 86 #endif 87 88 /* 89 * Call lookup on the looped vnode 90 */ 91 error = VOP_LOOKUP(targetdvp, &newvp, ap->a_cnp); 92 /*vrele(targetdvp);*/ 93 94 if (error) { 95 *ap->a_vpp = NULLVP; 96 #ifdef LOFS_DIAGNOSTIC 97 printf("lofs_lookup(%x->%x) = %d\n", dvp, LOFSVP(dvp), error); 98 #endif 99 return (error); 100 } 101 #ifdef LOFS_DIAGNOSTIC 102 printf("lofs_lookup(%x->%x) = OK\n", dvp, LOFSVP(dvp)); 103 #endif 104 105 *ap->a_vpp = newvp; 106 107 /* 108 * If we just found a directory then make 109 * a loopback node for it and return the loopback 110 * instead of the real vnode. Otherwise simply 111 * return the aliased directory and vnode. 112 */ 113 if (newvp && newvp->v_type == VDIR && flag == LOOKUP) { 114 #ifdef LOFS_DIAGNOSTIC 115 printf("lofs_lookup: found VDIR\n"); 116 #endif 117 /* 118 * At this point, newvp is the vnode to be looped. 119 * Activate a loopback and return the looped vnode. 120 */ 121 return (make_lofs(dvp->v_mount, ap->a_vpp)); 122 } 123 124 #ifdef LOFS_DIAGNOSTIC 125 printf("lofs_lookup: not VDIR\n"); 126 #endif 127 128 return (0); 129 } 130 131 /* 132 * this = ni_dvp 133 * ni_dvp references the locked directory. 134 * ni_vp is NULL. 135 */ 136 lofs_mknod (ap) 137 struct vop_mknod_args *ap; 138 { 139 USES_VOP_MKNOD; 140 int error; 141 142 #ifdef LOFS_DIAGNOSTIC 143 printf("lofs_mknod(vp = %x->%x)\n", ap->a_dvp, LOFSVP(ap->a_dvp)); 144 #endif 145 146 PUSHREF(xdvp, ap->a_dvp); 147 VREF(ap->a_dvp); 148 149 error = VOP_MKNOD(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap); 150 151 POP(xdvp, ap->a_dvp); 152 vrele(ap->a_dvp); 153 154 return (error); 155 } 156 157 /* 158 * this = ni_dvp; 159 * ni_dvp references the locked directory 160 * ni_vp is NULL. 161 */ 162 lofs_create (ap) 163 struct vop_create_args *ap; 164 { 165 USES_VOP_CREATE; 166 int error; 167 168 #ifdef LOFS_DIAGNOSTIC 169 printf("lofs_create(ap->a_dvp = %x->%x)\n", ap->a_dvp, LOFSVP(ap->a_dvp)); 170 #endif 171 172 PUSHREF(xdvp, ap->a_dvp); 173 VREF(ap->a_dvp); 174 175 error = VOP_CREATE(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap); 176 177 POP(xdvp, ap->a_dvp); 178 vrele(ap->a_dvp); 179 180 #ifdef LOFS_DIAGNOSTIC 181 printf("lofs_create(ap->a_dvp = %x->%x)\n", ap->a_dvp, LOFSVP(ap->a_dvp)); 182 #endif 183 184 return (error); 185 } 186 187 lofs_open (ap) 188 struct vop_open_args *ap; 189 { 190 USES_VOP_OPEN; 191 #ifdef LOFS_DIAGNOSTIC 192 printf("lofs_open(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 193 #endif 194 195 return VOP_OPEN(LOFSVP(ap->a_vp), ap->a_mode, ap->a_cred, ap->a_p); 196 } 197 198 lofs_close (ap) 199 struct vop_close_args *ap; 200 { 201 USES_VOP_CLOSE; 202 #ifdef LOFS_DIAGNOSTIC 203 printf("lofs_close(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 204 #endif 205 206 return VOP_CLOSE(LOFSVP(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p); 207 } 208 209 lofs_access (ap) 210 struct vop_access_args *ap; 211 { 212 USES_VOP_ACCESS; 213 #ifdef LOFS_DIAGNOSTIC 214 printf("lofs_access(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 215 #endif 216 217 return VOP_ACCESS(LOFSVP(ap->a_vp), ap->a_mode, ap->a_cred, ap->a_p); 218 } 219 220 lofs_getattr (ap) 221 struct vop_getattr_args *ap; 222 { 223 USES_VOP_GETATTR; 224 int error; 225 226 #ifdef LOFS_DIAGNOSTIC 227 printf("lofs_getattr(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 228 #endif 229 230 /* 231 * Get the stats from the underlying filesystem 232 */ 233 error = VOP_GETATTR(LOFSVP(ap->a_vp), ap->a_vap, ap->a_cred, ap->a_p); 234 if (error) 235 return (error); 236 /* 237 * and replace the fsid field with the loopback number 238 * to preserve the namespace. 239 */ 240 ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; 241 return (0); 242 } 243 244 lofs_setattr (ap) 245 struct vop_setattr_args *ap; 246 { 247 USES_VOP_SETATTR; 248 #ifdef LOFS_DIAGNOSTIC 249 printf("lofs_setattr(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 250 #endif 251 252 return VOP_SETATTR(LOFSVP(ap->a_vp), ap->a_vap, ap->a_cred, ap->a_p); 253 } 254 255 lofs_read (ap) 256 struct vop_read_args *ap; 257 { 258 USES_VOP_READ; 259 #ifdef LOFS_DIAGNOSTIC 260 printf("lofs_read(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 261 #endif 262 263 return VOP_READ(LOFSVP(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred); 264 } 265 266 lofs_write (ap) 267 struct vop_write_args *ap; 268 { 269 USES_VOP_WRITE; 270 #ifdef LOFS_DIAGNOSTIC 271 printf("lofs_write(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 272 #endif 273 274 return VOP_WRITE(LOFSVP(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred); 275 } 276 277 lofs_ioctl (ap) 278 struct vop_ioctl_args *ap; 279 { 280 USES_VOP_IOCTL; 281 #ifdef LOFS_DIAGNOSTIC 282 printf("lofs_ioctl(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 283 #endif 284 285 return VOP_IOCTL(LOFSVP(ap->a_vp), ap->a_command, ap->a_data, ap->a_fflag, ap->a_cred, ap->a_p); 286 } 287 288 lofs_select (ap) 289 struct vop_select_args *ap; 290 { 291 USES_VOP_SELECT; 292 #ifdef LOFS_DIAGNOSTIC 293 printf("lofs_select(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 294 #endif 295 296 return VOP_SELECT(LOFSVP(ap->a_vp), ap->a_which, ap->a_fflags, ap->a_cred, ap->a_p); 297 } 298 299 lofs_mmap (ap) 300 struct vop_mmap_args *ap; 301 { 302 USES_VOP_MMAP; 303 #ifdef LOFS_DIAGNOSTIC 304 printf("lofs_mmap(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 305 #endif 306 307 return VOP_MMAP(LOFSVP(ap->a_vp), ap->a_fflags, ap->a_cred, ap->a_p); 308 } 309 310 lofs_fsync (ap) 311 struct vop_fsync_args *ap; 312 { 313 USES_VOP_FSYNC; 314 #ifdef LOFS_DIAGNOSTIC 315 printf("lofs_fsync(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 316 #endif 317 318 return VOP_FSYNC(LOFSVP(ap->a_vp), ap->a_fflags, ap->a_cred, ap->a_waitfor, ap->a_p); 319 } 320 321 lofs_seek (ap) 322 struct vop_seek_args *ap; 323 { 324 USES_VOP_SEEK; 325 #ifdef LOFS_DIAGNOSTIC 326 printf("lofs_seek(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 327 #endif 328 329 return VOP_SEEK(LOFSVP(ap->a_vp), ap->a_oldoff, ap->a_newoff, ap->a_cred); 330 } 331 332 lofs_remove (ap) 333 struct vop_remove_args *ap; 334 { 335 USES_VOP_REMOVE; 336 int error; 337 338 #ifdef LOFS_DIAGNOSTIC 339 printf("lofs_remove(ap->a_vp = %x->%x)\n", ap->a_dvp, LOFSVP(ap->a_dvp)); 340 #endif 341 342 PUSHREF(xdvp, ap->a_dvp); 343 VREF(ap->a_dvp); 344 PUSHREF(xvp, ap->a_vp); 345 VREF(ap->a_vp); 346 347 error = VOP_REMOVE(ap->a_dvp, ap->a_vp, ap->a_cnp); 348 349 POP(xvp, ap->a_vp); 350 vrele(ap->a_vp); 351 POP(xdvp, ap->a_dvp); 352 vrele(ap->a_dvp); 353 354 return (error); 355 } 356 357 /* 358 * vp is this. 359 * ni_dvp is the locked parent of the target. 360 * ni_vp is NULL. 361 */ 362 lofs_link (ap) 363 struct vop_link_args *ap; 364 { 365 USES_VOP_LINK; 366 int error; 367 368 #ifdef LOFS_DIAGNOSTIC 369 printf("lofs_link(ap->a_tdvp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 370 #endif 371 372 PUSHREF(xdvp, ap->a_vp); 373 VREF(ap->a_vp); 374 375 error = VOP_LINK(ap->a_vp, LOFSVP(ap->a_tdvp), ap->a_cnp); 376 377 POP(xdvp, ap->a_vp); 378 vrele(ap->a_vp); 379 380 return (error); 381 } 382 383 lofs_rename (ap) 384 struct vop_rename_args *ap; 385 { 386 USES_VOP_RENAME; 387 struct vnode *fvp, *tvp; 388 struct vnode *tdvp; 389 #if 0 390 struct vnode *fsvp, *tsvp; 391 #endif 392 int error; 393 394 #ifdef LOFS_DIAGNOSTIC 395 printf("lofs_rename(fdvp = %x->%x)\n", ap->a_fdvp, LOFSVP(ap->a_fdvp)); 396 /*printf("lofs_rename(tdvp = %x->%x)\n", tndp->ni_dvp, LOFSVP(tndp->ni_dvp));*/ 397 #endif 398 399 #ifdef LOFS_DIAGNOSTIC 400 printf("lofs_rename - switch source dvp\n"); 401 #endif 402 /* 403 * Switch source directory to point to lofsed vnode 404 */ 405 PUSHREF(fdvp, ap->a_fdvp); 406 VREF(ap->a_fdvp); 407 408 #ifdef LOFS_DIAGNOSTIC 409 printf("lofs_rename - switch source vp\n"); 410 #endif 411 /* 412 * And source object if it is lofsed... 413 */ 414 fvp = ap->a_fvp; 415 if (fvp && fvp->v_op == lofs_vnodeop_p) { 416 ap->a_fvp = LOFSVP(fvp); 417 VREF(ap->a_fvp); 418 } else { 419 fvp = 0; 420 } 421 422 #if 0 423 #ifdef LOFS_DIAGNOSTIC 424 printf("lofs_rename - switch source start vp\n"); 425 #endif 426 /* 427 * And source startdir object if it is lofsed... 428 */ 429 fsvp = fndp->ni_startdir; 430 if (fsvp && fsvp->v_op == lofs_vnodeop_p) { 431 fndp->ni_startdir = LOFSVP(fsvp); 432 VREF(fndp->ni_startdir); 433 } else { 434 fsvp = 0; 435 } 436 #endif 437 438 #ifdef LOFS_DIAGNOSTIC 439 printf("lofs_rename - switch target dvp\n"); 440 #endif 441 /* 442 * Switch target directory to point to lofsed vnode 443 */ 444 tdvp = ap->a_tdvp; 445 if (tdvp && tdvp->v_op == lofs_vnodeop_p) { 446 ap->a_tdvp = LOFSVP(tdvp); 447 VREF(ap->a_tdvp); 448 } else { 449 tdvp = 0; 450 } 451 452 #ifdef LOFS_DIAGNOSTIC 453 printf("lofs_rename - switch target vp\n"); 454 #endif 455 /* 456 * And target object if it is lofsed... 457 */ 458 tvp = ap->a_tvp; 459 if (tvp && tvp->v_op == lofs_vnodeop_p) { 460 ap->a_tvp = LOFSVP(tvp); 461 VREF(ap->a_tvp); 462 } else { 463 tvp = 0; 464 } 465 466 #if 0 467 #ifdef LOFS_DIAGNOSTIC 468 printf("lofs_rename - switch target start vp\n"); 469 #endif 470 /* 471 * And target startdir object if it is lofsed... 472 */ 473 tsvp = tndp->ni_startdir; 474 if (tsvp && tsvp->v_op == lofs_vnodeop_p) { 475 tndp->ni_startdir = LOFSVP(fsvp); 476 VREF(tndp->ni_startdir); 477 } else { 478 tsvp = 0; 479 } 480 #endif 481 482 #ifdef LOFS_DIAGNOSTIC 483 printf("lofs_rename - VOP_RENAME(%x, %x, %x, %x)\n", 484 ap->a_fdvp, ap->a_fvp, ap->a_tdvp, ap->a_tvp); 485 vprint("ap->a_fdvp", ap->a_fdvp); 486 vprint("ap->a_fvp", ap->a_fvp); 487 vprint("ap->a_tdvp", ap->a_tdvp); 488 if (ap->a_tvp) vprint("ap->a_tvp", ap->a_tvp); 489 DELAY(16000000); 490 #endif 491 492 error = VOP_RENAME(ap->a_fdvp, ap->a_fvp, ap->a_fcnp, ap->a_tdvp, ap->a_tvp, ap->a_tcnp); 493 494 /* 495 * Put everything back... 496 */ 497 498 #if 0 499 #ifdef LOFS_DIAGNOSTIC 500 printf("lofs_rename - restore target startdir\n"); 501 #endif 502 503 if (tsvp) { 504 if (tndp->ni_startdir) 505 vrele(tndp->ni_startdir); 506 tndp->ni_startdir = tsvp; 507 } 508 #endif 509 510 #ifdef LOFS_DIAGNOSTIC 511 printf("lofs_rename - restore target vp\n"); 512 #endif 513 514 if (tvp) { 515 ap->a_tvp = tvp; 516 vrele(ap->a_tvp); 517 } 518 519 #ifdef LOFS_DIAGNOSTIC 520 printf("lofs_rename - restore target dvp\n"); 521 #endif 522 523 if (tdvp) { 524 ap->a_tdvp = tdvp; 525 vrele(ap->a_tdvp); 526 } 527 528 #if 0 529 #ifdef LOFS_DIAGNOSTIC 530 printf("lofs_rename - restore source startdir\n"); 531 #endif 532 533 if (fsvp) { 534 if (fndp->ni_startdir) 535 vrele(fndp->ni_startdir); 536 fndp->ni_startdir = fsvp; 537 } 538 #endif 539 540 #ifdef LOFS_DIAGNOSTIC 541 printf("lofs_rename - restore source vp\n"); 542 #endif 543 544 545 if (fvp) { 546 ap->a_fvp = fvp; 547 vrele(ap->a_fvp); 548 } 549 550 #ifdef LOFS_DIAGNOSTIC 551 printf("lofs_rename - restore source dvp\n"); 552 #endif 553 554 POP(fdvp, ap->a_fdvp); 555 vrele(ap->a_fdvp); 556 557 return (error); 558 } 559 560 /* 561 * ni_dvp is the locked (alias) parent. 562 * ni_vp is NULL. 563 */ 564 lofs_mkdir (ap) 565 struct vop_mkdir_args *ap; 566 { 567 USES_VOP_MKDIR; 568 int error; 569 struct vnode *dvp = ap->a_dvp; 570 struct vnode *xdvp; 571 struct vnode *newvp; 572 573 #ifdef LOFS_DIAGNOSTIC 574 printf("lofs_mkdir(vp = %x->%x)\n", dvp, LOFSVP(dvp)); 575 #endif 576 577 xdvp = dvp; 578 dvp = LOFSVP(xdvp); 579 /*VREF(dvp);*/ 580 581 error = VOP_MKDIR(dvp, &newvp, ap->a_cnp, ap->a_vap); 582 583 if (error) { 584 *ap->a_vpp = NULLVP; 585 /*vrele(xdvp);*/ 586 return (error); 587 } 588 589 /* 590 * Make a new lofs node 591 */ 592 /*VREF(dvp);*/ 593 594 error = make_lofs(dvp->v_mount, &newvp); 595 596 *ap->a_vpp = newvp; 597 598 return (error); 599 } 600 601 /* 602 * ni_dvp is the locked parent. 603 * ni_vp is the entry to be removed. 604 */ 605 lofs_rmdir (ap) 606 struct vop_rmdir_args *ap; 607 { 608 USES_VOP_RMDIR; 609 struct vnode *vp = ap->a_vp; 610 struct vnode *dvp = ap->a_dvp; 611 int error; 612 613 #ifdef LOFS_DIAGNOSTIC 614 printf("lofs_rmdir(dvp = %x->%x)\n", dvp, LOFSVP(dvp)); 615 #endif 616 617 PUSHREF(xdvp, dvp); 618 VREF(dvp); 619 PUSHREF(xvp, vp); 620 VREF(vp); 621 622 error = VOP_RMDIR(dvp, vp, ap->a_cnp); 623 624 POP(xvp, vp); 625 vrele(vp); 626 POP(xdvp, dvp); 627 vrele(dvp); 628 629 return (error); 630 } 631 632 /* 633 * ni_dvp is the locked parent. 634 * ni_vp is NULL. 635 */ 636 lofs_symlink (ap) 637 struct vop_symlink_args *ap; 638 { 639 USES_VOP_SYMLINK; 640 int error; 641 642 #ifdef LOFS_DIAGNOSTIC 643 printf("VOP_SYMLINK(vp = %x->%x)\n", ap->a_dvp, LOFSVP(ap->a_dvp)); 644 #endif 645 646 PUSHREF(xdvp, ap->a_dvp); 647 VREF(ap->a_dvp); 648 649 error = VOP_SYMLINK(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap, ap->a_target); 650 651 POP(xdvp, ap->a_dvp); 652 vrele(ap->a_dvp); 653 654 return (error); 655 } 656 657 lofs_readdir (ap) 658 struct vop_readdir_args *ap; 659 { 660 USES_VOP_READDIR; 661 #ifdef LOFS_DIAGNOSTIC 662 printf("lofs_readdir(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 663 #endif 664 665 return VOP_READDIR(LOFSVP(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflagp); 666 } 667 668 lofs_readlink (ap) 669 struct vop_readlink_args *ap; 670 { 671 USES_VOP_READLINK; 672 #ifdef LOFS_DIAGNOSTIC 673 printf("lofs_readlink(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 674 #endif 675 676 return VOP_READLINK(LOFSVP(ap->a_vp), ap->a_uio, ap->a_cred); 677 } 678 679 /* 680 * Anyone's guess... 681 */ 682 lofs_abortop (ap) 683 struct vop_abortop_args *ap; 684 { 685 USES_VOP_ABORTOP; 686 int error; 687 688 PUSHREF(xdvp, ap->a_dvp); 689 690 error = VOP_ABORTOP(ap->a_dvp, ap->a_cnp); 691 692 POP(xdvp, ap->a_dvp); 693 694 return (error); 695 } 696 697 lofs_inactive (ap) 698 struct vop_inactive_args *ap; 699 { 700 USES_VOP_INACTIVE; 701 struct vnode *targetvp = LOFSVP(ap->a_vp); 702 #ifdef LOFS_DIAGNOSTIC 703 printf("lofs_inactive(ap->a_vp = %x->%x)\n", ap->a_vp, targetvp); 704 #endif 705 706 #ifdef DIAGNOSTIC 707 { extern int prtactive; 708 if (prtactive && ap->a_vp->v_usecount != 0) 709 vprint("lofs_inactive: pushing active", ap->a_vp); 710 } 711 #endif 712 713 if (targetvp) { 714 vrele(targetvp); 715 LOFSP(ap->a_vp)->a_lofsvp = 0; 716 } 717 } 718 719 lofs_reclaim (ap) 720 struct vop_reclaim_args *ap; 721 { 722 USES_VOP_RECLAIM; 723 struct vnode *targetvp; 724 #ifdef LOFS_DIAGNOSTIC 725 printf("lofs_reclaim(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 726 #endif 727 remque(LOFSP(ap->a_vp)); 728 targetvp = LOFSVP(ap->a_vp); 729 if (targetvp) { 730 printf("lofs: delayed vrele of %x\n", targetvp); 731 vrele(targetvp); /* XXX should never happen */ 732 } 733 FREE(ap->a_vp->v_data, M_TEMP); 734 ap->a_vp->v_data = 0; 735 return (0); 736 } 737 738 lofs_lock (ap) 739 struct vop_lock_args *ap; 740 { 741 USES_VOP_LOCK; 742 int error; 743 struct vnode *targetvp = LOFSVP(ap->a_vp); 744 745 #ifdef LOFS_DIAGNOSTIC 746 printf("lofs_lock(ap->a_vp = %x->%x)\n", ap->a_vp, targetvp); 747 /*vprint("lofs_lock ap->a_vp", ap->a_vp); 748 if (targetvp) 749 vprint("lofs_lock ->ap->a_vp", targetvp); 750 else 751 printf("lofs_lock ->ap->a_vp = NIL\n");*/ 752 #endif 753 754 if (targetvp) { 755 error = VOP_LOCK(targetvp); 756 if (error) 757 return (error); 758 } 759 760 return (0); 761 } 762 763 lofs_unlock (ap) 764 struct vop_unlock_args *ap; 765 { 766 USES_VOP_UNLOCK; 767 struct vnode *targetvp = LOFSVP(ap->a_vp); 768 769 #ifdef LOFS_DIAGNOSTIC 770 printf("lofs_unlock(ap->a_vp = %x->%x)\n", ap->a_vp, targetvp); 771 #endif 772 773 if (targetvp) 774 return (VOP_UNLOCK(targetvp)); 775 return (0); 776 } 777 778 lofs_bmap (ap) 779 struct vop_bmap_args *ap; 780 { 781 USES_VOP_BMAP; 782 #ifdef LOFS_DIAGNOSTIC 783 printf("lofs_bmap(ap->a_vp = %x->%x)\n", ap->a_vp, LOFSVP(ap->a_vp)); 784 #endif 785 786 return VOP_BMAP(LOFSVP(ap->a_vp), ap->a_bn, ap->a_vpp, ap->a_bnp); 787 } 788 789 lofs_strategy (ap) 790 struct vop_strategy_args *ap; 791 { 792 USES_VOP_STRATEGY; 793 int error; 794 795 #ifdef LOFS_DIAGNOSTIC 796 printf("lofs_strategy(vp = %x->%x)\n", ap->a_bp->b_vp, LOFSVP(ap->a_bp->b_vp)); 797 #endif 798 799 PUSHREF(vp, ap->a_bp->b_vp); 800 801 error = VOP_STRATEGY(ap->a_bp); 802 803 POP(vp, ap->a_bp->b_vp); 804 805 return (error); 806 } 807 808 lofs_print (ap) 809 struct vop_print_args *ap; 810 { 811 USES_VOP_PRINT; 812 struct vnode *targetvp = LOFSVP(ap->a_vp); 813 printf("tag VT_LOFS ref "); 814 if (targetvp) 815 return (VOP_PRINT(targetvp)); 816 printf("NULLVP\n"); 817 return (0); 818 } 819 820 lofs_islocked (ap) 821 struct vop_islocked_args *ap; 822 { 823 USES_VOP_ISLOCKED; 824 struct vnode *targetvp = LOFSVP(ap->a_vp); 825 if (targetvp) 826 return (VOP_ISLOCKED(targetvp)); 827 return (0); 828 } 829 830 lofs_advlock (ap) 831 struct vop_advlock_args *ap; 832 { 833 USES_VOP_ADVLOCK; 834 return VOP_ADVLOCK(LOFSVP(ap->a_vp), ap->a_id, ap->a_op, ap->a_fl, ap->a_flags); 835 } 836 837 /* 838 * LOFS directory offset lookup. 839 * Currently unsupported. 840 */ 841 lofs_blkatoff (ap) 842 struct vop_blkatoff_args *ap; 843 { 844 845 return (EOPNOTSUPP); 846 } 847 848 /* 849 * LOFS flat namespace lookup. 850 * Currently unsupported. 851 */ 852 lofs_vget (ap) 853 struct vop_vget_args *ap; 854 { 855 856 return (EOPNOTSUPP); 857 } 858 859 /* 860 * LOFS flat namespace allocation. 861 * Currently unsupported. 862 */ 863 lofs_valloc (ap) 864 struct vop_valloc_args *ap; 865 { 866 867 return (EOPNOTSUPP); 868 } 869 870 /* 871 * LOFS flat namespace free. 872 * Currently unsupported. 873 */ 874 /*void*/ 875 lofs_vfree (ap) 876 struct vop_vfree_args *ap; 877 { 878 879 return; 880 } 881 882 /* 883 * LOFS file truncation. 884 */ 885 lofs_truncate (ap) 886 struct vop_truncate_args *ap; 887 { 888 889 /* Use lofs_setattr */ 890 printf("lofs_truncate: need to implement!!"); 891 return (EOPNOTSUPP); 892 } 893 894 /* 895 * LOFS update. 896 */ 897 lofs_update (ap) 898 struct vop_update_args *ap; 899 { 900 901 /* Use lofs_setattr */ 902 printf("lofs_update: need to implement!!"); 903 return (EOPNOTSUPP); 904 } 905 906 /* 907 * LOFS bwrite 908 */ 909 lofs_bwrite (ap) 910 struct vop_bwrite_args *ap; 911 { 912 return (EOPNOTSUPP); 913 } 914 915 /* 916 * Global vfs data structures for ufs 917 */ 918 int (**lofs_vnodeop_p)(); 919 struct vnodeopv_entry_desc lofs_vnodeop_entries[] = { 920 { &vop_default_desc, vn_default_error }, 921 { &vop_lookup_desc, lofs_lookup }, /* lookup */ 922 { &vop_create_desc, lofs_create }, /* create */ 923 { &vop_mknod_desc, lofs_mknod }, /* mknod */ 924 { &vop_open_desc, lofs_open }, /* open */ 925 { &vop_close_desc, lofs_close }, /* close */ 926 { &vop_access_desc, lofs_access }, /* access */ 927 { &vop_getattr_desc, lofs_getattr }, /* getattr */ 928 { &vop_setattr_desc, lofs_setattr }, /* setattr */ 929 { &vop_read_desc, lofs_read }, /* read */ 930 { &vop_write_desc, lofs_write }, /* write */ 931 { &vop_ioctl_desc, lofs_ioctl }, /* ioctl */ 932 { &vop_select_desc, lofs_select }, /* select */ 933 { &vop_mmap_desc, lofs_mmap }, /* mmap */ 934 { &vop_fsync_desc, lofs_fsync }, /* fsync */ 935 { &vop_seek_desc, lofs_seek }, /* seek */ 936 { &vop_remove_desc, lofs_remove }, /* remove */ 937 { &vop_link_desc, lofs_link }, /* link */ 938 { &vop_rename_desc, lofs_rename }, /* rename */ 939 { &vop_mkdir_desc, lofs_mkdir }, /* mkdir */ 940 { &vop_rmdir_desc, lofs_rmdir }, /* rmdir */ 941 { &vop_symlink_desc, lofs_symlink }, /* symlink */ 942 { &vop_readdir_desc, lofs_readdir }, /* readdir */ 943 { &vop_readlink_desc, lofs_readlink }, /* readlink */ 944 { &vop_abortop_desc, lofs_abortop }, /* abortop */ 945 { &vop_inactive_desc, lofs_inactive }, /* inactive */ 946 { &vop_reclaim_desc, lofs_reclaim }, /* reclaim */ 947 { &vop_lock_desc, lofs_lock }, /* lock */ 948 { &vop_unlock_desc, lofs_unlock }, /* unlock */ 949 { &vop_bmap_desc, lofs_bmap }, /* bmap */ 950 { &vop_strategy_desc, lofs_strategy }, /* strategy */ 951 { &vop_print_desc, lofs_print }, /* print */ 952 { &vop_islocked_desc, lofs_islocked }, /* islocked */ 953 { &vop_advlock_desc, lofs_advlock }, /* advlock */ 954 { &vop_blkatoff_desc, lofs_blkatoff }, /* blkatoff */ 955 { &vop_vget_desc, lofs_vget }, /* vget */ 956 { &vop_valloc_desc, lofs_valloc }, /* valloc */ 957 { &vop_vfree_desc, lofs_vfree }, /* vfree */ 958 { &vop_truncate_desc, lofs_truncate }, /* truncate */ 959 { &vop_update_desc, lofs_update }, /* update */ 960 { &vop_bwrite_desc, lofs_bwrite }, /* bwrite */ 961 { (struct vnodeop_desc*)NULL, (int(*)())NULL } 962 }; 963 struct vnodeopv_desc lofs_vnodeop_opv_desc = 964 { &lofs_vnodeop_p, lofs_vnodeop_entries }; 965