Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/coda Fixes from get/putpages from rmind.
details: https://anonhg.NetBSD.org/src/rev/5d46a69ae13f
branches: trunk
changeset: 779046:5d46a69ae13f
user: christos <christos%NetBSD.org@localhost>
date: Sat Apr 28 20:01:09 2012 +0000
description:
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.
diffstat:
sys/coda/coda_vnops.c | 54 +++++++++++++++++++++++++++-----------------------
sys/coda/coda_vnops.h | 13 +++++------
2 files changed, 35 insertions(+), 32 deletions(-)
diffs (200 lines):
diff -r eca4fe94fdd8 -r 5d46a69ae13f sys/coda/coda_vnops.c
--- a/sys/coda/coda_vnops.c Sat Apr 28 18:04:02 2012 +0000
+++ b/sys/coda/coda_vnops.c Sat Apr 28 20:01:09 2012 +0000
@@ -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 @@
* 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 @@
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 @@
* 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 @@
(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 @@
* 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 @@
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 @@
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 @@
/* 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 @@
/* 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 @@
#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 @@
}
/*
- * 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 @@
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 @@
* 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;
diff -r eca4fe94fdd8 -r 5d46a69ae13f sys/coda/coda_vnops.h
--- a/sys/coda/coda_vnops.h Sat Apr 28 18:04:02 2012 +0000
+++ b/sys/coda/coda_vnops.h Sat Apr 28 20:01:09 2012 +0000
@@ -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_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);
Home |
Main Index |
Thread Index |
Old Index