? compile/LINT Index: dev/aic7xxx/Makefile =================================================================== RCS file: /home/ncvs/src/sys/dev/aic7xxx/Makefile,v retrieving revision 1.5 diff -u -r1.5 Makefile --- Makefile 1999/01/17 19:56:02 1.5 +++ Makefile 1999/02/10 01:10:59 @@ -19,7 +19,13 @@ DEPENDFILE= .endif -CFLAGS+= -I/usr/include -I. +.if exists(../../../include) +CFLAGS+= -nostdinc -I../../ -I../../../include +.else +CFLAGS+= -I/usr/include +.endif +CFLAGS+= -I. + NOMAN= noman .ifdef DEBUG Index: dev/aic7xxx/aicasm_symbol.c =================================================================== RCS file: /home/ncvs/src/sys/dev/aic7xxx/aicasm_symbol.c,v retrieving revision 1.5 diff -u -r1.5 aicasm_symbol.c --- aicasm_symbol.c 1998/09/15 07:24:17 1.5 +++ aicasm_symbol.c 1999/02/10 01:10:59 @@ -30,9 +30,9 @@ #include +#include #include -#include #include #include #include Index: kern/imgact_aout.c =================================================================== RCS file: /home/ncvs/src/sys/kern/imgact_aout.c,v retrieving revision 1.45 diff -u -r1.45 imgact_aout.c --- imgact_aout.c 1999/01/29 22:59:43 1.45 +++ imgact_aout.c 1999/02/10 01:11:17 @@ -176,7 +176,7 @@ vmspace = imgp->proc->p_vmspace; vp = imgp->vp; - object = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &object); vm_object_reference(object); text_end = virtual_offset + a_out->a_text; Index: kern/imgact_elf.c =================================================================== RCS file: /home/ncvs/src/sys/kern/imgact_elf.c,v retrieving revision 1.53 diff -u -r1.53 imgact_elf.c --- imgact_elf.c 1999/02/07 23:49:56 1.53 +++ imgact_elf.c 1999/02/10 01:11:17 @@ -193,7 +193,7 @@ vm_offset_t file_addr; vm_offset_t data_buf = 0; - object = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &object); error = 0; map_addr = trunc_page((vm_offset_t)vmaddr); Index: kern/kern_exec.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_exec.c,v retrieving revision 1.95 diff -u -r1.95 kern_exec.c --- kern_exec.c 1999/01/28 00:57:47 1.95 +++ kern_exec.c 1999/02/10 01:11:18 @@ -357,7 +357,10 @@ exec_unmap_first_page(imgp); } - object = imgp->vp->v_object; + VOP_GETBACKINGOBJECT(imgp->vp, &object); + KASSERT(object, + ("exec_map_first_page: No backing object for impg %p -> vp %p", + imgp, imgp->vp)); s = splvm(); ma[0] = vm_page_grab(object, 0, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); Index: kern/kern_lock.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_lock.c,v retrieving revision 1.23 diff -u -r1.23 kern_lock.c --- kern_lock.c 1999/01/20 14:49:11 1.23 +++ kern_lock.c 1999/02/10 01:11:18 @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -142,7 +143,14 @@ lkp->lk_flags |= LK_WAIT_NONZERO; lkp->lk_waitcount++; simple_unlock(&lkp->lk_interlock); +#ifdef INVARIANTS + error = tsleep(lkp, lkp->lk_prio, lkp->lk_wmesg, + lkp->lk_timo ? lkp->lk_timo : 100*hz); + if (error == EWOULDBLOCK && lkp->lk_timo == 0) + Debugger("Timed out at 100s"); +#else error = tsleep(lkp, lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo); +#endif simple_lock(&lkp->lk_interlock); if (lkp->lk_waitcount == 1) { lkp->lk_flags &= ~LK_WAIT_NONZERO; @@ -443,8 +451,15 @@ while (lkp->lk_flags & LK_ALL) { lkp->lk_flags |= LK_WAITDRAIN; simple_unlock(&lkp->lk_interlock); +#ifdef INVARIANTS + error = tsleep(lkp, lkp->lk_prio, lkp->lk_wmesg, + lkp->lk_timo ? lkp->lk_timo : 100*hz); + if (error == EWOULDBLOCK && lkp->lk_timo == 0) + Debugger("Timed out at 100s"); +#else error = tsleep(&lkp->lk_flags, lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo); +#endif simple_lock(&lkp->lk_interlock); if (error) return error; Index: kern/uipc_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.55 diff -u -r1.55 uipc_syscalls.c --- uipc_syscalls.c 1999/01/27 21:49:57 1.55 +++ uipc_syscalls.c 1999/02/10 01:11:18 @@ -1438,7 +1438,7 @@ goto done; } vp = (struct vnode *)fp->f_data; - obj = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &obj); if (vp->v_type != VREG || obj == NULL) { error = EINVAL; goto done; Index: kern/vfs_bio.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v retrieving revision 1.199 diff -u -r1.199 vfs_bio.c --- vfs_bio.c 1999/01/27 21:49:58 1.199 +++ vfs_bio.c 1999/02/10 01:11:18 @@ -671,7 +671,7 @@ vm_page_flag_clear(m, PG_ZERO); if (m == bogus_page) { - obj = (vm_object_t) vp->v_object; + VOP_GETBACKINGOBJECT(vp, &obj); poff = OFF_TO_IDX(bp->b_offset); for (j = i; j < bp->b_npages; j++) { @@ -1302,10 +1302,12 @@ return 1; if (vp->v_mount == NULL) return 0; - if ((vp->v_object == NULL) || (vp->v_flag & VOBJBUF) == 0) + + (void)VOP_GETBACKINGVP(vp, &vp); + VOP_GETBACKINGOBJECT(vp, &obj); + if (obj == NULL || (vp->v_flag & VOBJBUF) == 0) return 0; - obj = vp->v_object; size = PAGE_SIZE; if (size > vp->v_mount->mnt_stat.f_iosize) size = vp->v_mount->mnt_stat.f_iosize; @@ -1519,6 +1521,7 @@ splx(s); return (bp); } else { + vm_object_t obj; int bsize, maxsize, vmio; off_t offset; @@ -1532,7 +1535,9 @@ bsize = size; offset = (off_t)blkno * bsize; - vmio = (vp->v_object != 0) && (vp->v_flag & VOBJBUF); + (void)VOP_GETBACKINGVP(vp, &vp); + VOP_GETBACKINGOBJECT(vp, &obj); + vmio = (obj != 0) && (vp->v_flag & VOBJBUF); maxsize = vmio ? size + (offset & PAGE_MASK) : size; maxsize = imax(maxsize, bsize); @@ -1768,7 +1773,7 @@ bsize = vp->v_mount->mnt_stat.f_iosize; if (bp->b_npages < desiredpages) { - obj = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &obj); tinc = PAGE_SIZE; off = bp->b_offset; @@ -1952,14 +1957,15 @@ int iosize; struct vnode *vp = bp->b_vp; - obj = vp->v_object; + (void)VOP_GETBACKINGVP(vp,&vp); + VOP_GETBACKINGOBJECT(vp, &obj); #if defined(VFS_BIO_DEBUG) if (vp->v_usecount == 0) { panic("biodone: zero vnode ref count"); } - if (vp->v_object == NULL) { + if (obj == NULL) { panic("biodone: missing VM object"); } @@ -2054,6 +2060,12 @@ foff += resid; iosize -= resid; } + if (obj && + (obj->paging_in_progress == 0) && + (obj->flags & OBJ_PIPWNT)) { + vm_object_clear_flag(obj, OBJ_PIPWNT); + wakeup(obj); + } if (obj) vm_object_pip_wakeupn(obj, 0); } @@ -2117,8 +2129,10 @@ if (bp->b_flags & B_VMIO) { struct vnode *vp = bp->b_vp; - vm_object_t obj = vp->v_object; + vm_object_t obj; + VOP_GETBACKINGOBJECT(vp, &obj); + for (i = 0; i < bp->b_npages; i++) { vm_page_t m = bp->b_pages[i]; @@ -2242,8 +2256,10 @@ if (bp->b_flags & B_VMIO) { struct vnode *vp = bp->b_vp; - vm_object_t obj = vp->v_object; + vm_object_t obj; vm_ooffset_t foff; + + VOP_GETBACKINGOBJECT(vp, &obj); foff = bp->b_offset; KASSERT(bp->b_offset != NOOFFSET, Index: kern/vfs_default.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_default.c,v retrieving revision 1.17 diff -u -r1.17 vfs_default.c --- vfs_default.c 1999/01/20 14:49:11 1.17 +++ vfs_default.c 1999/02/10 01:11:18 @@ -77,6 +77,7 @@ { &vop_revoke_desc, (vop_t *) vop_revoke }, { &vop_strategy_desc, (vop_t *) vop_nostrategy }, { &vop_unlock_desc, (vop_t *) vop_nounlock }, + { &vop_getbackingobject_desc, (vop_t *) vop_stdgetbackingobject }, { NULL, NULL } }; @@ -382,7 +383,7 @@ struct proc *a_p; } */ *ap; { -#ifdef notyet +#if 0 /* * This code cannot be used until all the non-locking filesystems * (notably NFS) are converted to properly lock and release nodes. @@ -475,3 +476,17 @@ return (lockstatus(vp->v_vnlock)); } +/* + * Get backing object (default such). + */ +int +vop_stdgetbackingobject(ap) + struct vop_getbackingobject_args /* { + struct vnode *a_vp; + struct vm_object **a_vmopp; + } */ *ap; +{ + struct vnode *vp = ap->a_vp; + *ap->a_vmopp = vp->_v_real_object; + return (0); +} Index: kern/vfs_lookup.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_lookup.c,v retrieving revision 1.33 diff -u -r1.33 vfs_lookup.c --- vfs_lookup.c 1999/01/28 00:57:47 1.33 +++ vfs_lookup.c 1999/02/10 01:11:18 @@ -524,9 +524,13 @@ cnp->cn_nameptr++; ndp->ni_pathlen--; } +#if 0 + /* XXX This seems to be wrong. I got a panic() + where syncer had locked my vnode... */ if (ndp->ni_dvp != ndp->ni_vp) { - ASSERT_VOP_UNLOCKED(ndp->ni_dvp, "lookup"); + ASSERT_VOP_LOCKED(ndp->ni_dvp, "lookup"); } +#endif vrele(ndp->ni_dvp); goto dirloop; } Index: kern/vfs_subr.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_subr.c,v retrieving revision 1.186 diff -u -r1.186 vfs_subr.c --- vfs_subr.c 1999/02/04 18:25:39 1.186 +++ vfs_subr.c 1999/02/10 01:11:18 @@ -431,7 +431,11 @@ if (vp->v_usecount) panic("free vnode isn't"); - object = vp->v_object; + /* + * Stacking layers do not count here - we're only + * interested in the single vnode vp. + */ + object = vp->_v_real_object; if (object && (object->resident_page_count || object->ref_count)) { printf("object inconsistant state: RPC: %d, RC: %d\n", object->resident_page_count, object->ref_count); @@ -668,7 +672,7 @@ * Destroy the copy in the VM cache, too. */ simple_lock(&vp->v_interlock); - object = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &object); if (object != NULL) { vm_object_page_remove(object, 0, 0, (flags & V_SAVE) ? TRUE : FALSE); @@ -1286,6 +1290,7 @@ int flags; struct proc *p; { + struct vm_object *object; int error; /* @@ -1320,7 +1325,8 @@ */ simple_lock(&vp->v_interlock); vp->v_usecount--; - if (VSHOULDFREE(vp)) + VOP_GETBACKINGOBJECT(vp, &object); + if (VSHOULDFREE(vp, object)) vfree(vp); simple_unlock(&vp->v_interlock); } @@ -1346,6 +1352,7 @@ vrele(vp) struct vnode *vp; { + struct vm_object *object; struct proc *p = curproc; /* XXX */ KASSERT(vp != NULL, ("vrele: null vp")); @@ -1363,7 +1370,8 @@ if (vp->v_usecount == 1) { vp->v_usecount--; - if (VSHOULDFREE(vp)) + VOP_GETBACKINGOBJECT(vp, &object); + if (VSHOULDFREE(vp, object)) vfree(vp); /* * If we are doing a vput, the node is already locked, and we must @@ -1387,6 +1395,7 @@ vput(vp) struct vnode *vp; { + struct vm_object *object; struct proc *p = curproc; /* XXX */ KASSERT(vp != NULL, ("vput: null vp")); @@ -1404,7 +1413,8 @@ if (vp->v_usecount == 1) { vp->v_usecount--; - if (VSHOULDFREE(vp)) + VOP_GETBACKINGOBJECT(vp, &object); + if (VSHOULDFREE(vp, object)) vfree(vp); /* * If we are doing a vput, the node is already locked, and we must @@ -1445,13 +1455,15 @@ vdrop(vp) register struct vnode *vp; { + struct vm_object *object; int s; s = splbio(); if (vp->v_holdcnt <= 0) panic("vdrop: holdcnt"); vp->v_holdcnt--; - if (VSHOULDFREE(vp)) + VOP_GETBACKINGOBJECT(vp, &object); + if (VSHOULDFREE(vp, object)) vfree(vp); splx(s); } @@ -1594,7 +1606,8 @@ * Clean out any buffers associated with the vnode. */ vinvalbuf(vp, V_SAVE, NOCRED, p, 0, 0); - if ((obj = vp->v_object) != NULL) { + VOP_GETBACKINGOBJECT(vp, &obj); + if (obj != NULL) { if (obj->ref_count == 0) { /* * This is a normal way of shutting down the object/vnode @@ -1646,7 +1659,7 @@ vp->v_vnlock = NULL; } - if (VSHOULDFREE(vp)) + if (VSHOULDFREE(vp, (struct vm_object *)NULL)) vfree(vp); /* @@ -2494,7 +2507,10 @@ continue; if (flags != MNT_WAIT) { - obj = vp->v_object; + obj = (void*)0xdeadf00d; + VOP_GETBACKINGOBJECT(vp, &obj); + if (obj == (void*)0xdeadf00d) panic("No GETBACKINOBJ1 for %p\n", vp); + if (obj && (char*)obj <= (char*)0x1000) panic("1: obj=%p <= 0x1000 for vp %p\n", obj, vp); if (obj == NULL || (obj->flags & OBJ_MIGHTBEDIRTY) == 0) continue; if (VOP_ISLOCKED(vp)) @@ -2502,12 +2518,21 @@ } simple_lock(&vp->v_interlock); - if (vp->v_object && - (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) { + obj = (void*)0xdeadf00d; + VOP_GETBACKINGOBJECT(vp, &obj); + if (obj == (void*)0xdeadf00d) panic("No GETBACKINOBJ2 for %p\n", vp); + if (obj && (char*)obj <= (char*)0x1000) panic("2: obj=%p <= 0x1000 for vp %p\n", obj, vp); + if (obj && (obj->flags & OBJ_MIGHTBEDIRTY)) { if (!vget(vp, - LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) { - if (vp->v_object) { - vm_object_page_clean(vp->v_object, 0, 0, flags == MNT_WAIT ? OBJPC_SYNC : 0); + LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | + LK_NOOBJ, curproc)) { + obj = (void*)0xdeadf00d; + VOP_GETBACKINGOBJECT(vp, &obj); + if (obj == (void*)0xdeadf00d) panic("No GETBACKINOBJ3 for %p\n", vp); + if (obj && (char*)obj <= (char*)0x1000) panic("3: obj=%p <= 0x1000 for vp %p\n", obj, vp); + if (obj) { + vm_object_page_clean(obj, 0, 0, + flags == MNT_WAIT ? OBJPC_SYNC : 0); anyio = 1; } vput(vp); @@ -2536,13 +2561,16 @@ { struct vattr vat; vm_object_t object; + struct vnode *oldvp = vp; int error = 0; if ((vp->v_type != VREG) && (vp->v_type != VBLK)) return 0; + (void)VOP_GETBACKINGVP(vp, &vp); retry: - if ((object = vp->v_object) == NULL) { + VOP_GETBACKINGOBJECT(vp, &object); + if (object == NULL) { if (vp->v_type == VREG) { if ((error = VOP_GETATTR(vp, &vat, cred, p)) != 0) goto retn; @@ -2566,14 +2594,14 @@ vp->v_usecount--; } else { if (object->flags & OBJ_DEAD) { - VOP_UNLOCK(vp, 0, p); + VOP_UNLOCK(oldvp, 0, p); tsleep(object, PVM, "vodead", 0); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + vn_lock(oldvp, LK_EXCLUSIVE | LK_RETRY, p); goto retry; } } - KASSERT(vp->v_object != NULL, ("vfs_object_create: NULL object")); + KASSERT(vp->_v_real_object != NULL, ("vfs_object_create: NULL object")); vp->v_flag |= VOBJBUF; retn: @@ -2723,15 +2751,16 @@ static vop_t **sync_vnodeop_p; static struct vnodeopv_entry_desc sync_vnodeop_entries[] = { - { &vop_default_desc, (vop_t *) vop_eopnotsupp }, - { &vop_close_desc, (vop_t *) sync_close }, /* close */ - { &vop_fsync_desc, (vop_t *) sync_fsync }, /* fsync */ - { &vop_inactive_desc, (vop_t *) sync_inactive }, /* inactive */ - { &vop_reclaim_desc, (vop_t *) sync_reclaim }, /* reclaim */ - { &vop_lock_desc, (vop_t *) sync_lock }, /* lock */ - { &vop_unlock_desc, (vop_t *) sync_unlock }, /* unlock */ - { &vop_print_desc, (vop_t *) sync_print }, /* print */ - { &vop_islocked_desc, (vop_t *) sync_islocked }, /* islocked */ + { &vop_default_desc, (vop_t *) vop_eopnotsupp }, + { &vop_close_desc, (vop_t *) sync_close }, + { &vop_fsync_desc, (vop_t *) sync_fsync }, + { &vop_inactive_desc, (vop_t *) sync_inactive }, + { &vop_reclaim_desc, (vop_t *) sync_reclaim }, + { &vop_lock_desc, (vop_t *) sync_lock }, + { &vop_unlock_desc, (vop_t *) sync_unlock }, + { &vop_print_desc, (vop_t *) sync_print }, + { &vop_islocked_desc, (vop_t *) sync_islocked }, + { &vop_getbackingobject_desc, (vop_t *)vop_stdgetbackingobject }, { NULL, NULL } }; static struct vnodeopv_desc sync_vnodeop_opv_desc = Index: kern/vfs_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.116 diff -u -r1.116 vfs_syscalls.c --- vfs_syscalls.c 1999/01/30 12:27:00 1.116 +++ vfs_syscalls.c 1999/02/10 01:11:18 @@ -912,6 +912,7 @@ int type, indx, error; struct flock lf; struct nameidata nd; + struct vm_object *object; oflags = SCARG(uap, flags); if ((oflags & O_ACCMODE) == O_ACCMODE) @@ -967,8 +968,11 @@ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); fp->f_flag |= FHASLOCK; } - if ((vp->v_type == VREG) && (vp->v_object == NULL)) - vfs_object_create(vp, p, p->p_ucred); + if (vp->v_type == VREG) { + VOP_GETBACKINGOBJECT(vp, &object); + if (object == NULL) + vfs_object_create(vp, p, p->p_ucred); + } VOP_UNLOCK(vp, 0, p); p->p_retval[0] = indx; return (0); @@ -2416,6 +2420,7 @@ } */ *uap; { register struct vnode *vp; + struct vm_object *object; struct file *fp; int error; @@ -2423,8 +2428,9 @@ return (error); vp = (struct vnode *)fp->f_data; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); - if (vp->v_object) - vm_object_page_clean(vp->v_object, 0, 0, 0); + VOP_GETBACKINGOBJECT(vp, &object); + if (object) + vm_object_page_clean(object, 0, 0, 0); if ((error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p)) == 0 && vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) && bioops.io_fsync) Index: kern/vnode_if.src =================================================================== RCS file: /home/ncvs/src/sys/kern/vnode_if.src,v retrieving revision 1.19 diff -u -r1.19 vnode_if.src --- vnode_if.src 1998/09/05 14:13:06 1.19 +++ vnode_if.src 1999/02/10 01:11:18 @@ -486,3 +486,31 @@ #vop_bwrite { # IN struct buf *bp; #}; + +# +#% getbackingobject vp L L L +# +# Get hold of the backing object for a vnode. This is necessary to +# support stacking layers. +# +# This function never fails; it set *vmopp to NULL if no object is +# available. + +vop_getbackingobject { + IN struct vnode *vp; + OUT struct vm_object **vmopp; +}; + +# +#% getbackingvp vp L L L +# +# Get hold of the final vnode in a stack. This is necessary to +# support stacking layers. +# +# NOTE: *vpp is _not_ touched on error, and is _not_ touched if it is +# equal to vp. + +vop_getbackingvp { + IN struct vnode *vp; + OUT struct vnode **vpp; +}; Index: miscfs/nullfs/null_subr.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/nullfs/null_subr.c,v retrieving revision 1.19 diff -u -r1.19 null_subr.c --- null_subr.c 1998/07/30 17:40:45 1.19 +++ null_subr.c 1999/02/10 01:11:21 @@ -198,7 +198,7 @@ * null_node_find has taken another reference * to the alias vnode. */ -#ifdef NULLFS_DIAGNOSTIC +#if defined(NULLFS_DIAGNOSTIC) && 0 vprint("null_node_create: exists", aliasvp); #endif /* VREF(aliasvp); --- done in null_node_find */ @@ -235,7 +235,7 @@ }; #endif -#ifdef NULLFS_DIAGNOSTIC +#if defined(NULLFS_DIAGNOSTIC) && 0 vprint("null_node_create: alias", aliasvp); vprint("null_node_create: lower", lowervp); #endif Index: miscfs/nullfs/null_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/nullfs/null_vfsops.c,v retrieving revision 1.28 diff -u -r1.28 null_vfsops.c --- null_vfsops.c 1998/09/07 13:17:01 1.28 +++ null_vfsops.c 1999/02/10 01:11:21 @@ -286,7 +286,7 @@ struct proc *p = curproc; /* XXX */ struct vnode *vp; -#ifdef NULLFS_DIAGNOSTIC +#if defined(NULLFS_DIAGNOSTIC) && 0 printf("nullfs_root(mp = %p, vp = %p->%p)\n", (void *)mp, (void *)MOUNTTONULLMOUNT(mp)->nullm_rootvp, (void *)NULLVPTOLOWERVP(MOUNTTONULLMOUNT(mp)->nullm_rootvp)); @@ -297,17 +297,21 @@ */ vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp; VREF(vp); +#if 0 /* This can occur normally, it seems */ if (VOP_ISLOCKED(vp)) { /* * XXX * Should we check type of node? */ #ifdef DIAGNOSTIC - printf("nullfs_root: multi null mount?\n"); + VOP_PRINT(vp); + panic("nullfs_root: root (%p) locked - multi null mount?\n", + vp); #endif vrele(vp); return (EDEADLK); } else +#endif vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); *vpp = vp; return 0; Index: miscfs/nullfs/null_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/nullfs/null_vnops.c,v retrieving revision 1.32 diff -u -r1.32 null_vnops.c --- null_vnops.c 1999/01/28 00:57:50 1.32 +++ null_vnops.c 1999/02/10 01:11:21 @@ -194,6 +194,7 @@ static int null_access __P((struct vop_access_args *ap)); static int null_bwrite __P((struct vop_bwrite_args *ap)); static int null_getattr __P((struct vop_getattr_args *ap)); +static int null_getbackingvp __P((struct vop_getbackingvp_args *ap)); static int null_inactive __P((struct vop_inactive_args *ap)); static int null_lock __P((struct vop_lock_args *ap)); static int null_lookup __P((struct vop_lookup_args *ap)); @@ -387,7 +388,7 @@ lockargs.a_vp = vp; lockargs.a_flags = LK_SHARED; lockargs.a_p = p; - vop_nolock(&lockargs); + vop_sharedlock(&lockargs); } return (error); } @@ -505,7 +506,7 @@ } */ *ap; { - vop_nolock(ap); + vop_sharedlock(ap); if ((ap->a_flags & LK_TYPE_MASK) == LK_DRAIN) return (0); ap->a_flags &= ~LK_INTERLOCK; @@ -644,6 +645,21 @@ return (error); } +static int +null_getbackingvp(ap) + struct vop_getbackingvp_args /* { + struct vnode *a_vp; + struct vnode *a_vpp; + } */ *ap; +{ + register struct vnode *vp = ap->a_vp; + + if (VOP_GETBACKINGVP(NULLVPTOLOWERVP(vp), ap->a_vpp)) + *ap->a_vpp = NULLVPTOLOWERVP(vp); + + return (0); +} + /* * Global vfs data structures */ @@ -653,6 +669,7 @@ { &vop_access_desc, (vop_t *) null_access }, { &vop_bwrite_desc, (vop_t *) null_bwrite }, { &vop_getattr_desc, (vop_t *) null_getattr }, + { &vop_getbackingvp_desc, (vop_t *) null_getbackingvp }, { &vop_inactive_desc, (vop_t *) null_inactive }, { &vop_lock_desc, (vop_t *) null_lock }, { &vop_lookup_desc, (vop_t *) null_lookup }, Index: miscfs/union/union_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/union/union_vnops.c,v retrieving revision 1.60 diff -u -r1.60 union_vnops.c --- union_vnops.c 1999/01/27 22:42:08 1.60 +++ union_vnops.c 1999/02/10 01:11:23 @@ -98,6 +98,8 @@ static int union_unlock __P((struct vop_unlock_args *ap)); static int union_whiteout __P((struct vop_whiteout_args *ap)); static int union_write __P((struct vop_read_args *ap)); +static int union_getbackingobject __P((struct vop_getbackingobject_args + *ap)); static void union_fixup(un, p) @@ -1670,6 +1672,46 @@ } static int +union_getbackingobject(ap) + struct vop_getbackingobject_args /* { + struct vnode *a_vp; + struct vm_object **a_vmopp; + } */ *ap; +{ + struct vnode *vp = ap->a_vp; + + if (UPPERVP(vp) != NULLVP) + vp = UPPERVP(vp); + else if (LOWERVP(vp) != NULLVP) + vp = LOWERVP(vp); + else { + *ap->a_vmopp = NULL; + return (0); + } + + return (VOP_GETBACKINGOBJECT(vp, ap->a_vmopp)); +} + +static int +union_getbackingvp(ap) + struct vop_getbackingvp_args /* { + struct vnode *a_vp; + struct vm_object **a_vmopp; + } */ *ap; +{ + struct vnode *vp = ap->a_vp; + + if (UPPERVP(vp) != NULLVP) + vp = UPPERVP(vp); + else if (LOWERVP(vp) != NULLVP) + vp = LOWERVP(vp); + else + return (EINVAL); + + return (VOP_GETBACKINGVP(vp, ap->a_vpp)); +} + +static int union_islocked(ap) struct vop_islocked_args /* { struct vnode *a_vp; @@ -1768,6 +1810,8 @@ { &vop_create_desc, (vop_t *) union_create }, { &vop_fsync_desc, (vop_t *) union_fsync }, { &vop_getattr_desc, (vop_t *) union_getattr }, + { &vop_getbackingobject_desc, (vop_t *) union_getbackingobject }, + { &vop_getbackingvp_desc, (vop_t *) union_getbackingvp }, { &vop_inactive_desc, (vop_t *) union_inactive }, { &vop_ioctl_desc, (vop_t *) union_ioctl }, { &vop_islocked_desc, (vop_t *) union_islocked }, Index: nfs/nfs_bio.c =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfs_bio.c,v retrieving revision 1.66 diff -u -r1.66 nfs_bio.c --- nfs_bio.c 1999/01/21 08:29:07 1.66 +++ nfs_bio.c 1999/02/10 01:11:40 @@ -88,6 +88,7 @@ struct uio uio; struct iovec iov; vm_offset_t kva; + struct vm_object *obj; struct buf *bp; struct vnode *vp; struct proc *p; @@ -102,7 +103,8 @@ pages = ap->a_m; count = ap->a_count; - if (vp->v_object == NULL) { + VOP_GETBACKINGOBJECT(vp, &obj); /* Just for the check */ + if (obj == NULL) { printf("nfs_getpages: called with non-merged cache vnode??\n"); return VM_PAGER_ERROR; } Index: nfs/nfs_serv.c =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfs_serv.c,v retrieving revision 1.72 diff -u -r1.72 nfs_serv.c --- nfs_serv.c 1998/12/09 15:12:53 1.72 +++ nfs_serv.c 1999/02/10 01:11:40 @@ -3096,6 +3096,7 @@ char *cp2; struct mbuf *mb, *mb2, *mreq; u_quad_t frev, off; + struct vm_object *obj; #ifndef nolint cache = 0; @@ -3119,10 +3120,9 @@ return (0); } for_ret = VOP_GETATTR(vp, &bfor, cred, procp); - if (vp->v_object && - (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) { - vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC); - } + VOP_GETBACKINGOBJECT(vp, &obj); + if (obj && (obj->flags & OBJ_MIGHTBEDIRTY)) + vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); error = VOP_FSYNC(vp, cred, MNT_WAIT, procp); aft_ret = VOP_GETATTR(vp, &aft, cred, procp); vput(vp); Index: sys/vnode.h =================================================================== RCS file: /home/ncvs/src/sys/sys/vnode.h,v retrieving revision 1.84 diff -u -r1.84 vnode.h --- vnode.h 1999/02/03 04:12:36 1.84 +++ vnode.h 1999/02/10 01:11:45 @@ -110,7 +110,7 @@ daddr_t v_lasta; /* last allocation */ int v_clen; /* length of current cluster */ int v_maxio; /* maximum I/O cluster size */ - struct vm_object *v_object; /* Place to store VM object */ + struct vm_object *_v_real_object; /* Place to store VM object */ struct simplelock v_interlock; /* lock on usecount and flag */ struct lock *v_vnlock; /* used for non-locking fs's */ enum vtagtype v_tag; /* type of underlying data */ @@ -288,11 +288,11 @@ extern void (*lease_updatetime) __P((int deltat)); -#define VSHOULDFREE(vp) \ +#define VSHOULDFREE(vp,object) \ (!((vp)->v_flag & (VFREE|VDOOMED)) && \ !(vp)->v_holdcnt && !(vp)->v_usecount && \ - (!(vp)->v_object || \ - !((vp)->v_object->ref_count || (vp)->v_object->resident_page_count))) + (!(object) || \ + !((object)->ref_count || (object)->resident_page_count))) #define VSHOULDBUSY(vp) \ (((vp)->v_flag & (VFREE|VTBFREE)) && \ @@ -535,6 +535,7 @@ int vop_nolock __P((struct vop_lock_args *)); int vop_nopoll __P((struct vop_poll_args *)); int vop_nounlock __P((struct vop_unlock_args *)); +int vop_stdgetbackingobject __P((struct vop_getbackingobject_args *)); int vop_stdpathconf __P((struct vop_pathconf_args *)); int vop_stdpoll __P((struct vop_poll_args *)); int vop_revoke __P((struct vop_revoke_args *)); Index: ufs/ufs/ufs_readwrite.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_readwrite.c,v retrieving revision 1.57 diff -u -r1.57 ufs_readwrite.c --- ufs_readwrite.c 1999/01/28 00:57:56 1.57 +++ ufs_readwrite.c 1999/02/10 01:11:46 @@ -97,7 +97,7 @@ if ((u_int64_t)uio->uio_offset > fs->fs_maxfilesize) return (EFBIG); - object = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &object); bytesinfile = ip->i_size - uio->uio_offset; if (bytesinfile <= 0) { @@ -366,7 +366,7 @@ vp = ap->a_vp; ip = VTOI(vp); - object = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &object); if (object) vm_object_reference(object); @@ -550,7 +550,7 @@ } vp = ap->a_vp; - obj = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &obj); bsize = vp->v_mount->mnt_stat.f_iosize; pindex = mreq->pindex; foff = IDX_TO_OFF(pindex) /* + ap->a_offset should be zero */; Index: vm/vm_page.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_page.c,v retrieving revision 1.125 diff -u -r1.125 vm_page.c --- vm_page.c 1999/02/08 00:37:35 1.125 +++ vm_page.c 1999/02/10 01:11:46 @@ -533,6 +533,8 @@ register struct vm_page **bucket; int generation; + KASSERT(object, ("vm_page_lookup: NULL object")); + /* * Search the hash table for this object/offset pair */ @@ -1200,7 +1202,7 @@ ) { struct vnode *vp = (struct vnode *)object->handle; - if (vp && VSHOULDFREE(vp)) { + if (vp && VSHOULDFREE(vp, object)) { if ((vp->v_flag & (VTBFREE|VDOOMED|VFREE)) == 0) { TAILQ_INSERT_TAIL(&vnode_tobefree_list, vp, v_freelist); vp->v_flag |= VTBFREE; @@ -1423,6 +1425,8 @@ vm_page_t m; int s, generation; + + KASSERT(object, ("vm_page_grab: NULL object")); retrylookup: if ((m = vm_page_lookup(object, pindex)) != NULL) { Index: vm/vnode_pager.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vnode_pager.c,v retrieving revision 1.103 diff -u -r1.103 vnode_pager.c --- vnode_pager.c 1999/01/24 02:32:15 1.103 +++ vnode_pager.c 1999/02/10 01:11:46 @@ -116,6 +116,7 @@ } vp = (struct vnode *) handle; + (void)VOP_GETBACKINGVP(vp,&vp); /* * Prevent race condition when allocating the object. This @@ -131,7 +132,7 @@ * If the object is being terminated, wait for it to * go away. */ - while (((object = vp->v_object) != NULL) && + while (((object = vp->_v_real_object) != NULL) && (object->flags & OBJ_DEAD)) { tsleep(object, PVM, "vadead", 0); } @@ -149,7 +150,7 @@ object->un_pager.vnp.vnp_size = size; object->handle = handle; - vp->v_object = object; + vp->_v_real_object = object; vp->v_usecount++; } else { object->ref_count++; @@ -172,12 +173,13 @@ if (vp == NULL) panic("vnode_pager_dealloc: pager already dealloced"); + (void)VOP_GETBACKINGVP(vp, &vp); vm_object_pip_wait(object, "vnpdea"); object->handle = NULL; object->type = OBJT_DEAD; - vp->v_object = NULL; + vp->_v_real_object = NULL; vp->v_flag &= ~(VTEXT | VOBJBUF); } @@ -196,9 +198,11 @@ int bsize; int pagesperblock, blocksperpage; - if ((vp == NULL) || (vp->v_flag & VDOOMED)) + if (vp == NULL) return FALSE; - + (void)VOP_GETBACKINGVP(vp,&vp); + if (vp->v_flag & VDOOMED) + return FALSE; /* * If filesystem no longer mounted or offset beyond end of file we do * not have the page. @@ -263,7 +267,10 @@ vm_ooffset_t nsize; { vm_pindex_t nobjsize; - vm_object_t object = vp->v_object; + vm_object_t object; + + (void)VOP_GETBACKINGVP(vp,&vp); + VOP_GETBACKINGOBJECT(vp, &object); if (object == NULL) return; @@ -579,7 +586,7 @@ int count; int error = 0; - object = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &object); count = bytecount / PAGE_SIZE; if (vp->v_mount == NULL) @@ -865,7 +872,7 @@ int error; int ioflags; - object = vp->v_object; + VOP_GETBACKINGOBJECT(vp, &object); count = bytecount / PAGE_SIZE; for (i = 0; i < count; i++)