null_vnops.c (140165) | null_vnops.c (140728) |
---|---|
1/*- 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * John Heidemann of the UCLA Ficus project. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 22 unchanged lines hidden (view full) --- 31 * 32 * @(#)null_vnops.c 8.6 (Berkeley) 5/27/95 33 * 34 * Ancestors: 35 * @(#)lofs_vnops.c 1.2 (Berkeley) 6/18/92 36 * ...and... 37 * @(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project 38 * | 1/*- 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * John Heidemann of the UCLA Ficus project. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 22 unchanged lines hidden (view full) --- 31 * 32 * @(#)null_vnops.c 8.6 (Berkeley) 5/27/95 33 * 34 * Ancestors: 35 * @(#)lofs_vnops.c 1.2 (Berkeley) 6/18/92 36 * ...and... 37 * @(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project 38 * |
39 * $FreeBSD: head/sys/fs/nullfs/null_vnops.c 140165 2005-01-13 07:53:01Z phk $ | 39 * $FreeBSD: head/sys/fs/nullfs/null_vnops.c 140728 2005-01-24 11:49:41Z phk $ |
40 */ 41 42/* 43 * Null Layer 44 * 45 * (See mount_nullfs(8) for more information.) 46 * 47 * The null layer duplicates a portion of the filesystem --- 139 unchanged lines hidden (view full) --- 187#include <vm/vm_extern.h> 188#include <vm/vm_object.h> 189#include <vm/vnode_pager.h> 190 191static int null_bug_bypass = 0; /* for debugging: enables bypass printf'ing */ 192SYSCTL_INT(_debug, OID_AUTO, nullfs_bug_bypass, CTLFLAG_RW, 193 &null_bug_bypass, 0, ""); 194 | 40 */ 41 42/* 43 * Null Layer 44 * 45 * (See mount_nullfs(8) for more information.) 46 * 47 * The null layer duplicates a portion of the filesystem --- 139 unchanged lines hidden (view full) --- 187#include <vm/vm_extern.h> 188#include <vm/vm_object.h> 189#include <vm/vnode_pager.h> 190 191static int null_bug_bypass = 0; /* for debugging: enables bypass printf'ing */ 192SYSCTL_INT(_debug, OID_AUTO, nullfs_bug_bypass, CTLFLAG_RW, 193 &null_bug_bypass, 0, ""); 194 |
195static vop_access_t null_access; 196static vop_createvobject_t null_createvobject; 197static vop_destroyvobject_t null_destroyvobject; 198static vop_getattr_t null_getattr; 199static vop_getvobject_t null_getvobject; 200static vop_inactive_t null_inactive; 201static vop_islocked_t null_islocked; 202static vop_lock_t null_lock; 203static vop_lookup_t null_lookup; 204static vop_print_t null_print; 205static vop_reclaim_t null_reclaim; 206static vop_rename_t null_rename; 207static vop_setattr_t null_setattr; 208static vop_unlock_t null_unlock; 209 | |
210/* 211 * This is the 10-Apr-92 bypass routine. 212 * This version has been optimized for speed, throwing away some 213 * safety checks. It should still always work, but it's not as 214 * robust to programmer errors. 215 * 216 * In general, we map all vnodes going down and unmap them on the way back. 217 * As an exception to this, vnodes can be marked "unmapped" by setting --- 9 unchanged lines hidden (view full) --- 227 * - only one returned vpp 228 * - no INOUT vpp's (Sun's vop_open has one of these) 229 * - the vnode operation vector of the first vnode should be used 230 * to determine what implementation of the op should be invoked 231 * - all mapped vnodes are of our vnode-type (NEEDSWORK: 232 * problems on rmdir'ing mount points and renaming?) 233 */ 234int | 195/* 196 * This is the 10-Apr-92 bypass routine. 197 * This version has been optimized for speed, throwing away some 198 * safety checks. It should still always work, but it's not as 199 * robust to programmer errors. 200 * 201 * In general, we map all vnodes going down and unmap them on the way back. 202 * As an exception to this, vnodes can be marked "unmapped" by setting --- 9 unchanged lines hidden (view full) --- 212 * - only one returned vpp 213 * - no INOUT vpp's (Sun's vop_open has one of these) 214 * - the vnode operation vector of the first vnode should be used 215 * to determine what implementation of the op should be invoked 216 * - all mapped vnodes are of our vnode-type (NEEDSWORK: 217 * problems on rmdir'ing mount points and renaming?) 218 */ 219int |
235null_bypass(ap) 236 struct vop_generic_args /* { 237 struct vnodeop_desc *a_desc; 238 <other random data follows, presumably> 239 } */ *ap; | 220null_bypass(struct vop_generic_args *ap) |
240{ 241 register struct vnode **this_vp_p; 242 int error; 243 struct vnode *old_vps[VDESC_MAX_VPS]; 244 struct vnode **vps_p[VDESC_MAX_VPS]; 245 struct vnode ***vppp; 246 struct vnodeop_desc *descp = ap->a_desc; 247 int reles, i; --- 101 unchanged lines hidden (view full) --- 349} 350 351/* 352 * We have to carry on the locking protocol on the null layer vnodes 353 * as we progress through the tree. We also have to enforce read-only 354 * if this layer is mounted read-only. 355 */ 356static int | 221{ 222 register struct vnode **this_vp_p; 223 int error; 224 struct vnode *old_vps[VDESC_MAX_VPS]; 225 struct vnode **vps_p[VDESC_MAX_VPS]; 226 struct vnode ***vppp; 227 struct vnodeop_desc *descp = ap->a_desc; 228 int reles, i; --- 101 unchanged lines hidden (view full) --- 330} 331 332/* 333 * We have to carry on the locking protocol on the null layer vnodes 334 * as we progress through the tree. We also have to enforce read-only 335 * if this layer is mounted read-only. 336 */ 337static int |
357null_lookup(ap) 358 struct vop_lookup_args /* { 359 struct vnode * a_dvp; 360 struct vnode ** a_vpp; 361 struct componentname * a_cnp; 362 } */ *ap; | 338null_lookup(struct vop_lookup_args *ap) |
363{ 364 struct componentname *cnp = ap->a_cnp; 365 struct vnode *dvp = ap->a_dvp; 366 struct thread *td = cnp->cn_thread; 367 int flags = cnp->cn_flags; 368 struct vnode *vp, *ldvp, *lvp; 369 int error; 370 --- 34 unchanged lines hidden (view full) --- 405 } 406 return (error); 407} 408 409/* 410 * Setattr call. Disallow write attempts if the layer is mounted read-only. 411 */ 412static int | 339{ 340 struct componentname *cnp = ap->a_cnp; 341 struct vnode *dvp = ap->a_dvp; 342 struct thread *td = cnp->cn_thread; 343 int flags = cnp->cn_flags; 344 struct vnode *vp, *ldvp, *lvp; 345 int error; 346 --- 34 unchanged lines hidden (view full) --- 381 } 382 return (error); 383} 384 385/* 386 * Setattr call. Disallow write attempts if the layer is mounted read-only. 387 */ 388static int |
413null_setattr(ap) 414 struct vop_setattr_args /* { 415 struct vnodeop_desc *a_desc; 416 struct vnode *a_vp; 417 struct vattr *a_vap; 418 struct ucred *a_cred; 419 struct thread *a_td; 420 } */ *ap; | 389null_setattr(struct vop_setattr_args *ap) |
421{ 422 struct vnode *vp = ap->a_vp; 423 struct vattr *vap = ap->a_vap; 424 425 if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL || 426 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || 427 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) && 428 (vp->v_mount->mnt_flag & MNT_RDONLY)) --- 23 unchanged lines hidden (view full) --- 452 453 return (null_bypass((struct vop_generic_args *)ap)); 454} 455 456/* 457 * We handle getattr only to change the fsid. 458 */ 459static int | 390{ 391 struct vnode *vp = ap->a_vp; 392 struct vattr *vap = ap->a_vap; 393 394 if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL || 395 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || 396 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) && 397 (vp->v_mount->mnt_flag & MNT_RDONLY)) --- 23 unchanged lines hidden (view full) --- 421 422 return (null_bypass((struct vop_generic_args *)ap)); 423} 424 425/* 426 * We handle getattr only to change the fsid. 427 */ 428static int |
460null_getattr(ap) 461 struct vop_getattr_args /* { 462 struct vnode *a_vp; 463 struct vattr *a_vap; 464 struct ucred *a_cred; 465 struct thread *a_td; 466 } */ *ap; | 429null_getattr(struct vop_getattr_args *ap) |
467{ 468 int error; 469 470 if ((error = null_bypass((struct vop_generic_args *)ap)) != 0) 471 return (error); 472 473 ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; 474 return (0); 475} 476 477/* 478 * Handle to disallow write access if mounted read-only. 479 */ 480static int | 430{ 431 int error; 432 433 if ((error = null_bypass((struct vop_generic_args *)ap)) != 0) 434 return (error); 435 436 ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; 437 return (0); 438} 439 440/* 441 * Handle to disallow write access if mounted read-only. 442 */ 443static int |
481null_access(ap) 482 struct vop_access_args /* { 483 struct vnode *a_vp; 484 int a_mode; 485 struct ucred *a_cred; 486 struct thread *a_td; 487 } */ *ap; | 444null_access(struct vop_access_args *ap) |
488{ 489 struct vnode *vp = ap->a_vp; 490 mode_t mode = ap->a_mode; 491 492 /* 493 * Disallow write attempts on read-only layers; 494 * unless the file is a socket, fifo, or a block or 495 * character device resident on the filesystem. --- 14 unchanged lines hidden (view full) --- 510} 511 512/* 513 * We handle this to eliminate null FS to lower FS 514 * file moving. Don't know why we don't allow this, 515 * possibly we should. 516 */ 517static int | 445{ 446 struct vnode *vp = ap->a_vp; 447 mode_t mode = ap->a_mode; 448 449 /* 450 * Disallow write attempts on read-only layers; 451 * unless the file is a socket, fifo, or a block or 452 * character device resident on the filesystem. --- 14 unchanged lines hidden (view full) --- 467} 468 469/* 470 * We handle this to eliminate null FS to lower FS 471 * file moving. Don't know why we don't allow this, 472 * possibly we should. 473 */ 474static int |
518null_rename(ap) 519 struct vop_rename_args /* { 520 struct vnode *a_fdvp; 521 struct vnode *a_fvp; 522 struct componentname *a_fcnp; 523 struct vnode *a_tdvp; 524 struct vnode *a_tvp; 525 struct componentname *a_tcnp; 526 } */ *ap; | 475null_rename(struct vop_rename_args *ap) |
527{ 528 struct vnode *tdvp = ap->a_tdvp; 529 struct vnode *fvp = ap->a_fvp; 530 struct vnode *fdvp = ap->a_fdvp; 531 struct vnode *tvp = ap->a_tvp; 532 533 /* Check for cross-device rename. */ 534 if ((fvp->v_mount != tdvp->v_mount) || --- 13 unchanged lines hidden (view full) --- 548} 549 550/* 551 * We need to process our own vnode lock and then clear the 552 * interlock flag as it applies only to our vnode, not the 553 * vnodes below us on the stack. 554 */ 555static int | 476{ 477 struct vnode *tdvp = ap->a_tdvp; 478 struct vnode *fvp = ap->a_fvp; 479 struct vnode *fdvp = ap->a_fdvp; 480 struct vnode *tvp = ap->a_tvp; 481 482 /* Check for cross-device rename. */ 483 if ((fvp->v_mount != tdvp->v_mount) || --- 13 unchanged lines hidden (view full) --- 497} 498 499/* 500 * We need to process our own vnode lock and then clear the 501 * interlock flag as it applies only to our vnode, not the 502 * vnodes below us on the stack. 503 */ 504static int |
556null_lock(ap) 557 struct vop_lock_args /* { 558 struct vnode *a_vp; 559 int a_flags; 560 struct thread *a_td; 561 } */ *ap; | 505null_lock(struct vop_lock_args *ap) |
562{ 563 struct vnode *vp = ap->a_vp; 564 int flags = ap->a_flags; 565 struct thread *td = ap->a_td; 566 struct vnode *lvp; 567 int error; 568 struct null_node *nn; 569 --- 108 unchanged lines hidden (view full) --- 678} 679 680/* 681 * We need to process our own vnode unlock and then clear the 682 * interlock flag as it applies only to our vnode, not the 683 * vnodes below us on the stack. 684 */ 685static int | 506{ 507 struct vnode *vp = ap->a_vp; 508 int flags = ap->a_flags; 509 struct thread *td = ap->a_td; 510 struct vnode *lvp; 511 int error; 512 struct null_node *nn; 513 --- 108 unchanged lines hidden (view full) --- 622} 623 624/* 625 * We need to process our own vnode unlock and then clear the 626 * interlock flag as it applies only to our vnode, not the 627 * vnodes below us on the stack. 628 */ 629static int |
686null_unlock(ap) 687 struct vop_unlock_args /* { 688 struct vnode *a_vp; 689 int a_flags; 690 struct thread *a_td; 691 } */ *ap; | 630null_unlock(struct vop_unlock_args *ap) |
692{ 693 struct vnode *vp = ap->a_vp; 694 int flags = ap->a_flags; 695 struct thread *td = ap->a_td; 696 struct vnode *lvp; 697 698 if (vp->v_vnlock != NULL) { 699 if (flags & LK_THISLAYER) --- 12 unchanged lines hidden (view full) --- 712 } 713 VOP_UNLOCK(lvp, flags & ~LK_INTERLOCK, td); 714 } else 715 flags &= ~LK_THISLAYER; 716 return (lockmgr(&vp->v_lock, flags | LK_RELEASE, &vp->v_interlock, td)); 717} 718 719static int | 631{ 632 struct vnode *vp = ap->a_vp; 633 int flags = ap->a_flags; 634 struct thread *td = ap->a_td; 635 struct vnode *lvp; 636 637 if (vp->v_vnlock != NULL) { 638 if (flags & LK_THISLAYER) --- 12 unchanged lines hidden (view full) --- 651 } 652 VOP_UNLOCK(lvp, flags & ~LK_INTERLOCK, td); 653 } else 654 flags &= ~LK_THISLAYER; 655 return (lockmgr(&vp->v_lock, flags | LK_RELEASE, &vp->v_interlock, td)); 656} 657 658static int |
720null_islocked(ap) 721 struct vop_islocked_args /* { 722 struct vnode *a_vp; 723 struct thread *a_td; 724 } */ *ap; | 659null_islocked(struct vop_islocked_args *ap) |
725{ 726 struct vnode *vp = ap->a_vp; 727 struct thread *td = ap->a_td; 728 729 if (vp->v_vnlock != NULL) 730 return (lockstatus(vp->v_vnlock, td)); 731 return (lockstatus(&vp->v_lock, td)); 732} --- 4 unchanged lines hidden (view full) --- 737 * as soon as possible. 738 * 739 * Note, we can't release any resources nor remove vnode from hash before 740 * appropriate VXLOCK stuff is is done because other process can find this 741 * vnode in hash during inactivation and may be sitting in vget() and waiting 742 * for null_inactive to unlock vnode. Thus we will do all those in VOP_RECLAIM. 743 */ 744static int | 660{ 661 struct vnode *vp = ap->a_vp; 662 struct thread *td = ap->a_td; 663 664 if (vp->v_vnlock != NULL) 665 return (lockstatus(vp->v_vnlock, td)); 666 return (lockstatus(&vp->v_lock, td)); 667} --- 4 unchanged lines hidden (view full) --- 672 * as soon as possible. 673 * 674 * Note, we can't release any resources nor remove vnode from hash before 675 * appropriate VXLOCK stuff is is done because other process can find this 676 * vnode in hash during inactivation and may be sitting in vget() and waiting 677 * for null_inactive to unlock vnode. Thus we will do all those in VOP_RECLAIM. 678 */ 679static int |
745null_inactive(ap) 746 struct vop_inactive_args /* { 747 struct vnode *a_vp; 748 struct thread *a_td; 749 } */ *ap; | 680null_inactive(struct vop_inactive_args *ap) |
750{ 751 struct vnode *vp = ap->a_vp; 752 struct thread *td = ap->a_td; 753 754 VOP_UNLOCK(vp, 0, td); 755 756 /* 757 * If this is the last reference, then free up the vnode 758 * so as not to tie up the lower vnodes. 759 */ 760 vrecycle(vp, NULL, td); 761 762 return (0); 763} 764 765/* 766 * Now, the VXLOCK is in force and we're free to destroy the null vnode. 767 */ 768static int | 681{ 682 struct vnode *vp = ap->a_vp; 683 struct thread *td = ap->a_td; 684 685 VOP_UNLOCK(vp, 0, td); 686 687 /* 688 * If this is the last reference, then free up the vnode 689 * so as not to tie up the lower vnodes. 690 */ 691 vrecycle(vp, NULL, td); 692 693 return (0); 694} 695 696/* 697 * Now, the VXLOCK is in force and we're free to destroy the null vnode. 698 */ 699static int |
769null_reclaim(ap) 770 struct vop_reclaim_args /* { 771 struct vnode *a_vp; 772 struct thread *a_td; 773 } */ *ap; | 700null_reclaim(struct vop_reclaim_args *ap) |
774{ 775 struct vnode *vp = ap->a_vp; 776 struct null_node *xp = VTONULL(vp); 777 struct vnode *lowervp = xp->null_lowervp; 778 779 if (lowervp) { 780 null_hashrem(xp); 781 --- 4 unchanged lines hidden (view full) --- 786 vp->v_data = NULL; 787 vp->v_vnlock = &vp->v_lock; 788 FREE(xp, M_NULLFSNODE); 789 790 return (0); 791} 792 793static int | 701{ 702 struct vnode *vp = ap->a_vp; 703 struct null_node *xp = VTONULL(vp); 704 struct vnode *lowervp = xp->null_lowervp; 705 706 if (lowervp) { 707 null_hashrem(xp); 708 --- 4 unchanged lines hidden (view full) --- 713 vp->v_data = NULL; 714 vp->v_vnlock = &vp->v_lock; 715 FREE(xp, M_NULLFSNODE); 716 717 return (0); 718} 719 720static int |
794null_print(ap) 795 struct vop_print_args /* { 796 struct vnode *a_vp; 797 } */ *ap; | 721null_print(struct vop_print_args *ap) |
798{ 799 register struct vnode *vp = ap->a_vp; 800 printf("\tvp=%p, lowervp=%p\n", vp, NULLVPTOLOWERVP(vp)); 801 return (0); 802} 803 804/* 805 * Let an underlying filesystem do the work 806 */ 807static int | 722{ 723 register struct vnode *vp = ap->a_vp; 724 printf("\tvp=%p, lowervp=%p\n", vp, NULLVPTOLOWERVP(vp)); 725 return (0); 726} 727 728/* 729 * Let an underlying filesystem do the work 730 */ 731static int |
808null_createvobject(ap) 809 struct vop_createvobject_args /* { 810 struct vnode *vp; 811 struct ucred *cred; 812 struct thread *td; 813 } */ *ap; | 732null_createvobject(struct vop_createvobject_args *ap) |
814{ 815 struct vnode *vp = ap->a_vp; 816 struct vnode *lowervp = VTONULL(vp) ? NULLVPTOLOWERVP(vp) : NULL; 817 int error; 818 819 if (vp->v_type == VNON || lowervp == NULL) 820 return 0; 821 error = VOP_CREATEVOBJECT(lowervp, ap->a_cred, ap->a_td); 822 if (error) 823 return (error); 824 vp->v_vflag |= VV_OBJBUF; 825 return (0); 826} 827 828/* 829 * We have nothing to destroy and this operation shouldn't be bypassed. 830 */ 831static int | 733{ 734 struct vnode *vp = ap->a_vp; 735 struct vnode *lowervp = VTONULL(vp) ? NULLVPTOLOWERVP(vp) : NULL; 736 int error; 737 738 if (vp->v_type == VNON || lowervp == NULL) 739 return 0; 740 error = VOP_CREATEVOBJECT(lowervp, ap->a_cred, ap->a_td); 741 if (error) 742 return (error); 743 vp->v_vflag |= VV_OBJBUF; 744 return (0); 745} 746 747/* 748 * We have nothing to destroy and this operation shouldn't be bypassed. 749 */ 750static int |
832null_destroyvobject(ap) 833 struct vop_destroyvobject_args /* { 834 struct vnode *vp; 835 } */ *ap; | 751null_destroyvobject(struct vop_destroyvobject_args *ap) |
836{ 837 struct vnode *vp = ap->a_vp; 838 839 vp->v_vflag &= ~VV_OBJBUF; 840 return (0); 841} 842 843static int | 752{ 753 struct vnode *vp = ap->a_vp; 754 755 vp->v_vflag &= ~VV_OBJBUF; 756 return (0); 757} 758 759static int |
844null_getvobject(ap) 845 struct vop_getvobject_args /* { 846 struct vnode *vp; 847 struct vm_object **objpp; 848 } */ *ap; | 760null_getvobject(struct vop_getvobject_args *ap) |
849{ 850 struct vnode *lvp = NULLVPTOLOWERVP(ap->a_vp); 851 852 if (lvp == NULL) 853 return EINVAL; 854 return (VOP_GETVOBJECT(lvp, ap->a_objpp)); 855} 856 --- 24 unchanged lines hidden --- | 761{ 762 struct vnode *lvp = NULLVPTOLOWERVP(ap->a_vp); 763 764 if (lvp == NULL) 765 return EINVAL; 766 return (VOP_GETVOBJECT(lvp, ap->a_objpp)); 767} 768 --- 24 unchanged lines hidden --- |