diff options
author | alc <alc@FreeBSD.org> | 2002-12-23 06:20:41 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2002-12-23 06:20:41 +0000 |
commit | 1b398f04d9e2d70e7f2247c282197c834d5b2de0 (patch) | |
tree | 9b47fb7aa3ac087fa47c5361170de22c3484dbd0 /sys/nfsclient | |
parent | c5121aa08287dd00902d035938cf8871f0831bad (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 10 |
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; |