Module Name: src Committed By: christos Date: Sat Apr 28 20:01:09 UTC 2012
Modified Files: src/sys/coda: coda_vnops.c coda_vnops.h Log Message: Fixes from get/putpages from rmind. In grab vnode, share the lock of the coda vnode with the underlying vnode, so that the locking protocol works. To generate a diff of this commit: cvs rdiff -u -r1.82 -r1.83 src/sys/coda/coda_vnops.c cvs rdiff -u -r1.13 -r1.14 src/sys/coda/coda_vnops.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/coda/coda_vnops.c diff -u src/sys/coda/coda_vnops.c:1.82 src/sys/coda/coda_vnops.c:1.83 --- src/sys/coda/coda_vnops.c:1.82 Wed Apr 25 23:04:54 2012 +++ src/sys/coda/coda_vnops.c Sat Apr 28 16:01:09 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: coda_vnops.c,v 1.82 2012/04/26 03:04:54 christos Exp $ */ +/* $NetBSD: coda_vnops.c,v 1.83 2012/04/28 20:01:09 christos Exp $ */ /* * @@ -46,7 +46,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.82 2012/04/26 03:04:54 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.83 2012/04/28 20:01:09 christos Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -250,7 +250,7 @@ coda_open(void *v) * Obtain locked and referenced container vnode from container * device/inode. */ - error = coda_grab_vnode(dev, inode, &container_vp); + error = coda_grab_vnode(vp, dev, inode, &container_vp); if (error) return (error); @@ -425,7 +425,7 @@ coda_rdwr(struct vnode *vp, struct uio * if (cp->c_inode != 0 && !(p && (p->p_acflag & ACORE))) { printf("coda_rdwr: grabbing container vnode, losing reference\n"); /* Get locked and refed vnode. */ - error = coda_grab_vnode(cp->c_device, cp->c_inode, &cfvp); + error = coda_grab_vnode(vp, cp->c_device, cp->c_inode, &cfvp); if (error) { MARK_INT_FAIL(CODA_RDWR_STATS); return(error); @@ -1791,7 +1791,7 @@ coda_islocked(void *v) * obtained and passed back to the caller. */ int -coda_grab_vnode(dev_t dev, ino_t ino, struct vnode **vpp) +coda_grab_vnode(struct vnode *uvp, dev_t dev, ino_t ino, struct vnode **vpp) { int error; struct mount *mp; @@ -1814,6 +1814,10 @@ coda_grab_vnode(dev_t dev, ino_t ino, st (unsigned long long)dev, (unsigned long long)ino, *vpp, error)); return(ENOENT); } + /* share the lock with the underlying vnode */ + mutex_obj_hold(uvp->v_interlock); + uvm_obj_setlock(&(*vpp)->v_uobj, uvp->v_interlock); + return(0); } @@ -1934,8 +1938,6 @@ 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 - * held by caller, but this isn't documented in vnodeops(9) or vnode_if.src. */ int coda_getpages(void *v) @@ -1950,7 +1952,7 @@ coda_getpages(void *v) int a_advice; int a_flags; } */ *ap = v; - struct vnode *vp = ap->a_vp; + struct vnode *vp = ap->a_vp, *cvp; struct cnode *cp = VTOC(vp); struct lwp *l = curlwp; kauth_cred_t cred = l->l_cred; @@ -1958,6 +1960,8 @@ coda_getpages(void *v) int waslocked; /* 1 if vnode lock was held on entry */ int didopen = 0; /* 1 if we opened container file */ + KASSERT(mutex_owned(vp->v_interlock)); + /* * Handle a case that uvm_fault doesn't quite use yet. * See layer_vnops.c. for inspiration. @@ -1969,7 +1973,6 @@ 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); } @@ -1984,11 +1987,9 @@ coda_getpages(void *v) /* XXX VOP_ISLOCKED() may not be used for lock decisions. */ waslocked = VOP_ISLOCKED(vp); - /* Drop the vmobject lock. */ - mutex_exit(vp->v_uobj.vmobjlock); - /* Get container file if not already present. */ - if (cp->c_ovp == NULL) { + cvp = cp->c_ovp; + if (cvp == NULL) { /* * VOP_OPEN requires a locked vnode. We must avoid * locking the vnode if it is already locked, and @@ -2025,15 +2026,16 @@ coda_getpages(void *v) #if 0 printf("coda_getpages: opened vnode %p\n", vp); #endif + cvp = cp->c_ovp; didopen = 1; } - KASSERT(cp->c_ovp != NULL); + KASSERT(cvp != NULL); /* Munge the arg structure to refer to the container vnode. */ + KASSERT(cvp->v_interlock == vp->v_interlock); 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); + /* Finally, call getpages on it. */ error = VCALL(ap->a_vp, VOFFSET(vop_getpages), ap); /* If we opened the vnode, we must close it. */ @@ -2057,8 +2059,7 @@ coda_getpages(void *v) } /* - * The protocol requires v_uobj.vmobjlock to be held by the caller, as - * documented in vnodeops(9). XXX vnode_if.src doesn't say this. + * The protocol requires v_interlock to be held by the caller. */ int coda_putpages(void *v) @@ -2069,15 +2070,15 @@ coda_putpages(void *v) voff_t a_offhi; int a_flags; } */ *ap = v; - struct vnode *vp = ap->a_vp; + struct vnode *vp = ap->a_vp, *cvp; struct cnode *cp = VTOC(vp); int error; - /* Drop the vmobject lock. */ - mutex_exit(vp->v_uobj.vmobjlock); + KASSERT(mutex_owned(vp->v_interlock)); /* Check for control object. */ if (IS_CTL_VP(vp)) { + mutex_exit(vp->v_interlock); printf("coda_putpages: control object %p\n", vp); return(EINVAL); } @@ -2088,14 +2089,17 @@ coda_putpages(void *v) * time, apparently during discard of a closed vnode (which * trivially can't have dirty pages). */ - if (cp->c_ovp == NULL) + cvp = cp->c_ovp; + if (cvp == NULL) { + mutex_exit(vp->v_interlock); return 0; + } /* Munge the arg structure to refer to the container vnode. */ - ap->a_vp = cp->c_ovp; + KASSERT(cvp->v_interlock == vp->v_interlock); + ap->a_vp = cvp; - /* Get the lock on the container vnode, and call putpages on it. */ - mutex_enter(ap->a_vp->v_uobj.vmobjlock); + /* Finally, call putpages on it. */ error = VCALL(ap->a_vp, VOFFSET(vop_putpages), ap); return error; Index: src/sys/coda/coda_vnops.h diff -u src/sys/coda/coda_vnops.h:1.13 src/sys/coda/coda_vnops.h:1.14 --- src/sys/coda/coda_vnops.h:1.13 Sun May 14 17:24:49 2006 +++ src/sys/coda/coda_vnops.h Sat Apr 28 16:01:09 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: coda_vnops.h,v 1.13 2006/05/14 21:24:49 elad Exp $ */ +/* $NetBSD: coda_vnops.h,v 1.14 2012/04/28 20:01:09 christos Exp $ */ /* * @@ -80,9 +80,8 @@ int coda_getpages(void *); int coda_putpages(void *); int (**coda_vnodeop_p)(void *); -int coda_rdwr(struct vnode *vp, struct uio *uiop, enum uio_rw rw, - int ioflag, kauth_cred_t cred, struct lwp *l); - -int coda_grab_vnode(dev_t dev, ino_t ino, struct vnode **vpp); -void print_vattr(struct vattr *attr); -void print_cred(kauth_cred_t cred); +int coda_rdwr(vnode_t *, struct uio *, enum uio_rw, int, kauth_cred_t, + struct lwp *); +int coda_grab_vnode(vnode_t *, dev_t, ino_t, vnode_t **); +void print_vattr(struct vattr *); +void print_cred(kauth_cred_t);