Deleted Added
sdiff udiff text old ( 140165 ) new ( 140728 )
full compact
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 $
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
235null_bypass(ap)
236 struct vop_generic_args /* {
237 struct vnodeop_desc *a_desc;
238 <other random data follows, presumably>
239 } */ *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
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;
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
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;
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
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;
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
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;
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
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;
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
556null_lock(ap)
557 struct vop_lock_args /* {
558 struct vnode *a_vp;
559 int a_flags;
560 struct thread *a_td;
561 } */ *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
686null_unlock(ap)
687 struct vop_unlock_args /* {
688 struct vnode *a_vp;
689 int a_flags;
690 struct thread *a_td;
691 } */ *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
720null_islocked(ap)
721 struct vop_islocked_args /* {
722 struct vnode *a_vp;
723 struct thread *a_td;
724 } */ *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
745null_inactive(ap)
746 struct vop_inactive_args /* {
747 struct vnode *a_vp;
748 struct thread *a_td;
749 } */ *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
769null_reclaim(ap)
770 struct vop_reclaim_args /* {
771 struct vnode *a_vp;
772 struct thread *a_td;
773 } */ *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
794null_print(ap)
795 struct vop_print_args /* {
796 struct vnode *a_vp;
797 } */ *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
808null_createvobject(ap)
809 struct vop_createvobject_args /* {
810 struct vnode *vp;
811 struct ucred *cred;
812 struct thread *td;
813 } */ *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
832null_destroyvobject(ap)
833 struct vop_destroyvobject_args /* {
834 struct vnode *vp;
835 } */ *ap;
836{
837 struct vnode *vp = ap->a_vp;
838
839 vp->v_vflag &= ~VV_OBJBUF;
840 return (0);
841}
842
843static int
844null_getvobject(ap)
845 struct vop_getvobject_args /* {
846 struct vnode *vp;
847 struct vm_object **objpp;
848 } */ *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 ---