summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2010-12-17 22:18:09 +0000
committerrmacklem <rmacklem@FreeBSD.org>2010-12-17 22:18:09 +0000
commit76685b94905e80dbe3579c45ca040d9de78bdf75 (patch)
treeca7871903dbb3ea7b92836c57326b36a66d39546
parenta5ae0d2d14fc55d90dad2bba41f7fb3f94dc91f8 (diff)
downloadFreeBSD-src-76685b94905e80dbe3579c45ca040d9de78bdf75.zip
FreeBSD-src-76685b94905e80dbe3579c45ca040d9de78bdf75.tar.gz
Fix two vnode locking problems in nfsd_recalldelegation() in the
experimental NFSv4 server. The first was a bogus use of VOP_ISLOCKED() in a KASSERT() and the second was the need to lock the vnode for the nfsrv_checkremove() call. Also, delete a "__unused" that was bogus, since the argument is used. Reviewed by: zack.kirsch at isilon.com MFC after: 2 weeks
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 9f657d6..9775644 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -4275,7 +4275,7 @@ nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, __unused vnode_t vp,
*/
static int
nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
- __unused vnode_t vp)
+ vnode_t vp)
{
struct nfsclient *clp = stp->ls_clp;
int gotlock, error, retrycnt, zapped_clp;
@@ -4568,8 +4568,6 @@ nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p)
int32_t starttime;
int error;
- KASSERT(!VOP_ISLOCKED(vp), ("vp %p is locked", vp));
-
/*
* First, check to see if the server is currently running and it has
* been called for a regular file when issuing delegations.
@@ -4578,6 +4576,7 @@ nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p)
nfsrv_issuedelegs == 0)
return;
+ KASSERT((VOP_ISLOCKED(vp) != LK_EXCLUSIVE), ("vp %p is locked", vp));
/*
* First, get a reference on the nfsv4rootfs_lock so that an
* exclusive lock cannot be acquired by another thread.
@@ -4593,7 +4592,12 @@ nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p)
NFSGETNANOTIME(&mytime);
starttime = (u_int32_t)mytime.tv_sec;
do {
- error = nfsrv_checkremove(vp, 0, p);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ if ((vp->v_iflag & VI_DOOMED) == 0)
+ error = nfsrv_checkremove(vp, 0, p);
+ else
+ error = EPERM;
+ VOP_UNLOCK(vp, 0);
if (error == NFSERR_DELAY) {
NFSGETNANOTIME(&mytime);
if (((u_int32_t)mytime.tv_sec - starttime) >
OpenPOWER on IntegriCloud