summaryrefslogtreecommitdiffstats
path: root/sys/nfsclient/nfs_vnops.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2002-12-23 06:20:41 +0000
committeralc <alc@FreeBSD.org>2002-12-23 06:20:41 +0000
commit1b398f04d9e2d70e7f2247c282197c834d5b2de0 (patch)
tree9b47fb7aa3ac087fa47c5361170de22c3484dbd0 /sys/nfsclient/nfs_vnops.c
parentc5121aa08287dd00902d035938cf8871f0831bad (diff)
downloadFreeBSD-src-1b398f04d9e2d70e7f2247c282197c834d5b2de0.zip
FreeBSD-src-1b398f04d9e2d70e7f2247c282197c834d5b2de0.tar.gz
Avoid holding the vnode interlock around malloc() or free() to prevent a
lock order reversal. Reviewed by: jeff
Diffstat (limited to 'sys/nfsclient/nfs_vnops.c')
-rw-r--r--sys/nfsclient/nfs_vnops.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 7d739d3..ad5c357 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -2622,6 +2622,8 @@ again:
bvecpos = 0;
if (NFS_ISV3(vp) && commit) {
s = splbio();
+ if (bvec != NULL && bvec != bvec_on_stack)
+ free(bvec, M_TEMP);
/*
* Count up how many buffers waiting for a commit.
*/
@@ -2640,12 +2642,16 @@ again:
* If we can't get memory (for whatever reason), we will end up
* committing the buffers one-by-one in the loop below.
*/
- if (bvec != NULL && bvec != bvec_on_stack)
- free(bvec, M_TEMP);
if (bveccount > NFS_COMMITBVECSIZ) {
+ /*
+ * Release the vnode interlock to avoid a lock
+ * order reversal.
+ */
+ VI_UNLOCK(vp);
bvec = (struct buf **)
malloc(bveccount * sizeof(struct buf *),
M_TEMP, M_NOWAIT);
+ VI_LOCK(vp);
if (bvec == NULL) {
bvec = bvec_on_stack;
bvecsize = NFS_COMMITBVECSIZ;
OpenPOWER on IntegriCloud