summaryrefslogtreecommitdiffstats
path: root/sys/fs/coda
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-02-08 23:01:40 +0000
committerrwatson <rwatson@FreeBSD.org>2008-02-08 23:01:40 +0000
commit83dcd82dd9053e133a3a2ad73bae909c5794fe2a (patch)
treec1060a9417393e4cdd8250da2fa820ce2a2df46f /sys/fs/coda
parent09506e9ff83f7c5c59c4386d975e5bebaec96e1f (diff)
downloadFreeBSD-src-83dcd82dd9053e133a3a2ad73bae909c5794fe2a.zip
FreeBSD-src-83dcd82dd9053e133a3a2ad73bae909c5794fe2a.tar.gz
Before invoking vnode operations on cache vnodes, acquire the vnode
locks of those vnodes. Probably, Coda should do the same lock sharing/ pass-through that is done for nullfs, but in the mean time this ensures that locks are adequately held to prevent corruption of data structures in the cache file system. Assuming most operations came from the top layer of Coda and weren't performed directly on the cache vnodes, in practice this corruption was relatively unlikely as the Coda vnode locks were ensuring exclusive access for most consumers. This causes WITNESS to squeal like a pig immediately when Coda is used, rather than waiting until file close; I noticed these problems because of the lack of said squealing. MFC after: 1 month
Diffstat (limited to 'sys/fs/coda')
-rw-r--r--sys/fs/coda/coda_vnops.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/fs/coda/coda_vnops.c b/sys/fs/coda/coda_vnops.c
index 6074938..8e1e49d 100644
--- a/sys/fs/coda/coda_vnops.c
+++ b/sys/fs/coda/coda_vnops.c
@@ -234,13 +234,16 @@ coda_open(struct vop_open_args *ap)
}
/* Open the cache file. */
+ vn_lock(vp, LK_EXCLUSIVE);
error = VOP_OPEN(vp, flag, cred, td, NULL);
if (error) {
+ VOP_UNLOCK(vp, 0);
printf("coda_open: VOP_OPEN on container failed %d\n", error);
return (error);
} else {
(*vpp)->v_object = vp->v_object;
}
+ VOP_UNLOCK(vp, 0);
/* grab (above) does this when it calls newvnode unless it's in the cache*/
return(error);
@@ -270,8 +273,9 @@ coda_close(struct vop_close_args *ap)
}
if (cp->c_ovp) {
+ vn_lock(cp->c_ovp, LK_EXCLUSIVE);
VOP_CLOSE(cp->c_ovp, flag, cred, td); /* Do errors matter here? */
- vrele(cp->c_ovp);
+ vput(cp->c_ovp);
}
#ifdef CODA_VERBOSE
else printf("coda_close: NO container vp %p/cp %p\n", vp, cp);
@@ -354,6 +358,7 @@ coda_rdwr(struct vnode *vp, struct uio *uiop, enum uio_rw rw, int ioflag,
/* Have UFS handle the call. */
CODADEBUG(CODA_RDWR, myprintf(("indirect rdwr: fid = %s, refcnt = %d\n",
coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount)); )
+ vn_lock(cfvp, LK_EXCLUSIVE);
if (rw == UIO_READ) {
error = VOP_READ(cfvp, uiop, ioflag, cred);
} else {
@@ -367,6 +372,7 @@ coda_rdwr(struct vnode *vp, struct uio *uiop, enum uio_rw rw, int ioflag,
}
}
}
+ VOP_UNLOCK(cfvp, 0);
if (error)
MARK_INT_FAIL(CODA_RDWR_STATS);
@@ -1457,8 +1463,10 @@ coda_readdir(struct vop_readdir_args *ap)
/* Have UFS handle the call. */
CODADEBUG(CODA_READDIR, myprintf(("indirect readdir: fid = %s, refcnt = %d\n", coda_f2s(&cp->c_fid), vp->v_usecount)); )
+ vn_lock(cp->c_ovp, LK_EXCLUSIVE);
error = VOP_READDIR(cp->c_ovp, uiop, cred, eofflag, ncookies,
cookies);
+ VOP_UNLOCK(cp->c_ovp, 0);
if (error)
MARK_INT_FAIL(CODA_READDIR_STATS);
OpenPOWER on IntegriCloud