diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2010-01-27 15:22:20 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2010-01-27 15:22:20 +0000 |
commit | 3c42ac5cd551fe829f4d35317c16a44d287b0cb8 (patch) | |
tree | d60068d127fdd1a020342ef14d2b90110e566716 /sys/nfsclient/nfs_bio.c | |
parent | c75f72dd7c93d46f29e0e0a7b6fce9f5104ae43c (diff) | |
download | FreeBSD-src-3c42ac5cd551fe829f4d35317c16a44d287b0cb8.zip FreeBSD-src-3c42ac5cd551fe829f4d35317c16a44d287b0cb8.tar.gz |
Fix a race that can occur when nfs nfsiod threads are being created.
Without this patch it was possible for a different thread that calls
nfs_asyncio() to snitch a newly created nfsiod thread that was
intended for another caller of nfs_asyncio(), because the nfs_iod_mtx
mutex was unlocked while the new nfsiod thread was created. This patch
labels the newly created nfsiod, so that it is not taken by another
caller of nfs_asyncio(). This is believed to fix the problem reported
on the freebsd-stable email list under the subject:
FreeBSD NFS client/Linux NFS server issue.
Tested by: to DOT my DOT trociny AT gmail DOT com
Reviewed by: jhb
MFC after: 2 weeks
Diffstat (limited to 'sys/nfsclient/nfs_bio.c')
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 945bc51..cec0220 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -1377,7 +1377,7 @@ again: * Find a free iod to process this request. */ for (iod = 0; iod < nfs_numasync; iod++) - if (nfs_iodwant[iod]) { + if (nfs_iodwant[iod] == NFSIOD_AVAILABLE) { gotiod = TRUE; break; } @@ -1386,7 +1386,7 @@ again: * Try to create one if none are free. */ if (!gotiod) { - iod = nfs_nfsiodnew(); + iod = nfs_nfsiodnew(1); if (iod != -1) gotiod = TRUE; } @@ -1398,7 +1398,7 @@ again: */ NFS_DPF(ASYNCIO, ("nfs_asyncio: waking iod %d for mount %p\n", iod, nmp)); - nfs_iodwant[iod] = NULL; + nfs_iodwant[iod] = NFSIOD_NOT_AVAILABLE; nfs_iodmount[iod] = nmp; nmp->nm_bufqiods++; wakeup(&nfs_iodwant[iod]); |