? o Index: coda_vnops.c =================================================================== RCS file: /cvsroot/src/sys/coda/coda_vnops.c,v retrieving revision 1.82 diff -u -p -u -r1.82 coda_vnops.c --- coda_vnops.c 26 Apr 2012 03:04:54 -0000 1.82 +++ coda_vnops.c 28 Apr 2012 18:33:23 -0000 @@ -389,7 +389,10 @@ coda_rdwr(struct vnode *vp, struct uio * struct cnode *cp = VTOC(vp); struct vnode *cfvp = cp->c_ovp; struct proc *p = l->l_proc; - int opened_internally = 0; + int how; +#define NORMAL 0 +#define OPENED 1 +#define GRABBED 2 int error = 0; MARK_ENTRY(CODA_RDWR_STATS); @@ -423,7 +426,7 @@ coda_rdwr(struct vnode *vp, struct uio * * it's completely written. */ if (cp->c_inode != 0 && !(p && (p->p_acflag & ACORE))) { - printf("coda_rdwr: grabbing container vnode, losing reference\n"); + printf("%s: grabbing container vnode\n", __func__); /* Get locked and refed vnode. */ error = coda_grab_vnode(cp->c_device, cp->c_inode, &cfvp); if (error) { @@ -434,11 +437,11 @@ coda_rdwr(struct vnode *vp, struct uio * * Drop lock. * XXX Where is reference released. */ - VOP_UNLOCK(cfvp); +// VOP_UNLOCK(cfvp); + how = GRABBED; } else { - printf("coda_rdwr: internal VOP_OPEN\n"); - opened_internally = 1; + printf("%s: internal VOP_OPEN\n", __func__); MARK_INT_GEN(CODA_OPEN_STATS); error = VOP_OPEN(vp, (rw == UIO_READ ? FREAD : FWRITE), cred); #ifdef CODA_VERBOSE @@ -449,7 +452,11 @@ printf("coda_rdwr: Internally Opening %p return(error); } cfvp = cp->c_ovp; + how = OPENED; } + } else { + printf("%s: normal case\n", __func__); + how = NORMAL; } /* Have UFS handle the call. */ @@ -468,9 +475,16 @@ printf("coda_rdwr: Internally Opening %p MARK_INT_SAT(CODA_RDWR_STATS); /* Do an internal close if necessary. */ - if (opened_internally) { + switch (how) + case OPENED: { MARK_INT_GEN(CODA_CLOSE_STATS); (void)VOP_CLOSE(vp, (rw == UIO_READ ? FREAD : FWRITE), cred); + break; + case GRABBED: + vput(cfvp); + break; + case NORMAL: + break; } /* Invalidate cached attributes if writing. */ @@ -1934,7 +1948,7 @@ make_coda_node(CodaFid *fid, struct moun * e.g. to fault in pages to execute a program. In that case, we must * open the file to get the container. The vnode may or may not be * locked, and we must leave it in the same state. - * XXX The protocol requires v_uobj.vmobjlock to be + * XXX The protocol requires v_interlock to be * held by caller, but this isn't documented in vnodeops(9) or vnode_if.src. */ int @@ -1962,6 +1976,7 @@ coda_getpages(void *v) * Handle a case that uvm_fault doesn't quite use yet. * See layer_vnops.c. for inspiration. */ +printf("%s: vp-%p ovp-%p flags %x\n", __func__, vp, cp->c_ovp, ap->a_flags); if (ap->a_flags & PGO_LOCKED) { return EBUSY; } @@ -1969,9 +1984,15 @@ coda_getpages(void *v) /* Check for control object. */ if (IS_CTL_VP(vp)) { printf("coda_getpages: control object %p\n", vp); - mutex_exit(vp->v_uobj.vmobjlock); - return(EINVAL); + mutex_exit(vp->v_interlock); + return EINVAL; } +#if 0 + if ((ap->a_flags & PGO_SYNCIO) == 0) { + mutex_exit(vp->v_interlock); + return 0; + } +#endif /* * XXX It's really not ok to be releasing the lock we get, @@ -1985,10 +2006,11 @@ coda_getpages(void *v) waslocked = VOP_ISLOCKED(vp); /* Drop the vmobject lock. */ - mutex_exit(vp->v_uobj.vmobjlock); + mutex_exit(vp->v_interlock); /* Get container file if not already present. */ if (cp->c_ovp == NULL) { +printf("%s: ovp = NULL waslocked = %d\n", __func__, waslocked); /* * VOP_OPEN requires a locked vnode. We must avoid * locking the vnode if it is already locked, and @@ -2014,6 +2036,7 @@ coda_getpages(void *v) /* XXX Is it ok to do this while holding the simplelock? */ cerror = VOP_OPEN(vp, FREAD, cred); +printf("%s: open = %d\n", __func__, cerror); if (cerror) { printf("coda_getpages: cannot open vnode %p => %d\n", vp, cerror); @@ -2033,8 +2056,11 @@ coda_getpages(void *v) ap->a_vp = cp->c_ovp; /* Get the lock on the container vnode, and call getpages on it. */ - mutex_enter(ap->a_vp->v_uobj.vmobjlock); + mutex_enter(ap->a_vp->v_interlock); +printf("%s: before vcall\n", __func__); error = VCALL(ap->a_vp, VOFFSET(vop_getpages), ap); +printf("%s: after vcall %d\n", __func__, error); + ap->a_vp = vp; /* If we opened the vnode, we must close it. */ if (didopen) { @@ -2043,21 +2069,25 @@ coda_getpages(void *v) * holding the lock (or riding a caller's lock). */ cerror = VOP_CLOSE(vp, FREAD, cred); +printf("%s: close %d\n", __func__, cerror); if (cerror != 0) /* XXX How should we handle this? */ printf("coda_getpages: closed vnode %p -> %d\n", vp, cerror); /* If we obtained a lock, drop it. */ - if (waslocked == 0) + if (waslocked == 0) { +printf("%s: unlock\n", __func__); VOP_UNLOCK(vp); + } } +printf("%s: done %d\n", __func__, error); return error; } /* - * The protocol requires v_uobj.vmobjlock to be held by the caller, as + * The protocol requires v_uobj.vmock to be held by the caller, as * documented in vnodeops(9). XXX vnode_if.src doesn't say this. */ int @@ -2074,7 +2104,7 @@ coda_putpages(void *v) int error; /* Drop the vmobject lock. */ - mutex_exit(vp->v_uobj.vmobjlock); + mutex_exit(vp->v_interlock); /* Check for control object. */ if (IS_CTL_VP(vp)) { @@ -2095,8 +2125,11 @@ coda_putpages(void *v) ap->a_vp = cp->c_ovp; /* Get the lock on the container vnode, and call putpages on it. */ - mutex_enter(ap->a_vp->v_uobj.vmobjlock); + mutex_enter(ap->a_vp->v_interlock); +printf("%s: before\n", __func__); error = VCALL(ap->a_vp, VOFFSET(vop_putpages), ap); +printf("%s: after %d\n", __func__, error); + ap->a_vp = vp; return error; }