summaryrefslogtreecommitdiffstats
path: root/sys/nfsclient/nfs_nfsiod.c
diff options
context:
space:
mode:
authormohans <mohans@FreeBSD.org>2006-05-24 23:06:50 +0000
committermohans <mohans@FreeBSD.org>2006-05-24 23:06:50 +0000
commit365e894b0f63e67763498fc8f9ebd33fa3cfa8bf (patch)
tree5a8ae5cf6c25251ebeb224a4c1e21ee7583aeec9 /sys/nfsclient/nfs_nfsiod.c
parentebcbe046b9de0cd9b1ee9874be24aef9ed6699c6 (diff)
downloadFreeBSD-src-365e894b0f63e67763498fc8f9ebd33fa3cfa8bf.zip
FreeBSD-src-365e894b0f63e67763498fc8f9ebd33fa3cfa8bf.tar.gz
Since NFSv4 is not SMP safe, nfsiod needs to acquire Giant for NFSv4 mounts
before doing the read/write. Reported by: Chuck Lever.
Diffstat (limited to 'sys/nfsclient/nfs_nfsiod.c')
-rw-r--r--sys/nfsclient/nfs_nfsiod.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c
index 4851824..e219c71 100644
--- a/sys/nfsclient/nfs_nfsiod.c
+++ b/sys/nfsclient/nfs_nfsiod.c
@@ -248,6 +248,8 @@ nfssvc_iod(void *instance)
if (error)
break;
while ((bp = TAILQ_FIRST(&nmp->nm_bufq)) != NULL) {
+ int giant_locked = 0;
+
/* Take one off the front of the list */
TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist);
nmp->nm_bufqlen--;
@@ -256,6 +258,10 @@ nfssvc_iod(void *instance)
wakeup(&nmp->nm_bufq);
}
mtx_unlock(&nfs_iod_mtx);
+ if (NFS_ISV4(bp->b_vp)) {
+ giant_locked = 1;
+ mtx_lock(&Giant);
+ }
if (bp->b_flags & B_DIRECT) {
KASSERT((bp->b_iocmd == BIO_WRITE), ("nfscvs_iod: BIO_WRITE not set"));
(void)nfs_doio_directwrite(bp);
@@ -265,6 +271,8 @@ nfssvc_iod(void *instance)
else
(void) nfs_doio(bp->b_vp, bp, bp->b_wcred, NULL);
}
+ if (giant_locked)
+ mtx_unlock(&Giant);
mtx_lock(&nfs_iod_mtx);
/*
* If there are more than one iod on this mount, then defect
OpenPOWER on IntegriCloud