summaryrefslogtreecommitdiffstats
path: root/sys/nfsserver/nfs_serv.c
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2006-03-12 04:59:04 +0000
committerjeff <jeff@FreeBSD.org>2006-03-12 04:59:04 +0000
commit52c1783c83a8377b9f20934b4d35b62af8aec3a6 (patch)
tree141b2f74619b6f0da29ed03de2e4094b1e0dbcd9 /sys/nfsserver/nfs_serv.c
parentc98db28d0e7855b17c8ec3073f43d862b9800b07 (diff)
downloadFreeBSD-src-52c1783c83a8377b9f20934b4d35b62af8aec3a6.zip
FreeBSD-src-52c1783c83a8377b9f20934b4d35b62af8aec3a6.tar.gz
- Reorder vrele calls after vput calls to prevent lock order reversals
between leaf and directory locks. Found by: kris Sponsored by: Isilon Systems, Inc.
Diffstat (limited to 'sys/nfsserver/nfs_serv.c')
-rw-r--r--sys/nfsserver/nfs_serv.c43
1 files changed, 17 insertions, 26 deletions
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index 8117cbb..f7597e4 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -599,15 +599,9 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
}
}
- if (dirp) {
- vrele(dirp);
- dirp = NULL;
- }
-
/*
* Resources at this point:
* ndp->ni_vp may not be NULL
- *
*/
if (error) {
@@ -621,15 +615,6 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
}
/*
- * Clear out some resources prior to potentially blocking. This
- * is not as critical as ni_dvp resources in other routines, but
- * it helps.
- */
- vrele(ndp->ni_startdir);
- ndp->ni_startdir = NULL;
- NDFREE(&nd, NDF_ONLY_PNBUF);
-
- /*
* Get underlying attribute, then release remaining resources ( for
* the same potential blocking reason ) and reply.
*/
@@ -641,8 +626,12 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
error = VOP_GETATTR(vp, vap, cred, td);
vput(vp);
- mtx_unlock(&Giant); /* VFS */
+ vrele(ndp->ni_startdir);
+ vrele(dirp);
ndp->ni_vp = NULL;
+ ndp->ni_startdir = NULL;
+ dirp = NULL;
+ mtx_unlock(&Giant); /* VFS */
NFSD_LOCK();
nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3));
if (error) {
@@ -662,17 +651,19 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
nfsmout:
NFSD_LOCK_ASSERT();
- NFSD_UNLOCK();
- mtx_lock(&Giant); /* VFS */
- if (ndp->ni_vp)
- vput(ndp->ni_vp);
- if (dirp)
- vrele(dirp);
+ if (ndp->ni_vp || dirp || ndp->ni_startdir) {
+ NFSD_UNLOCK();
+ mtx_lock(&Giant); /* VFS */
+ if (ndp->ni_vp)
+ vput(ndp->ni_vp);
+ if (dirp)
+ vrele(dirp);
+ if (ndp->ni_startdir)
+ vrele(ndp->ni_startdir);
+ mtx_unlock(&Giant); /* VFS */
+ NFSD_LOCK();
+ }
NDFREE(&nd, NDF_ONLY_PNBUF);
- if (ndp->ni_startdir)
- vrele(ndp->ni_startdir);
- mtx_unlock(&Giant); /* VFS */
- NFSD_LOCK();
return (error);
}
OpenPOWER on IntegriCloud