mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-04 12:52:15 +00:00
Fix for a very rare race, caused by the nfsiod wakeup and nfsiod idle
timeout occurring at exactly the same time. If this happens, the nfsiod exits although there may be a queued async IO request for it. Found by : Kris Kennaway Approved by: re
This commit is contained in:
parent
129f717f65
commit
17c53e4a28
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=172324
@ -1453,6 +1453,13 @@ nfs_asyncio(struct nfsmount *nmp, struct buf *bp, struct ucred *cred, struct thr
|
||||
}
|
||||
}
|
||||
|
||||
/* We might have lost our nfsiod */
|
||||
if (nmp->nm_bufqiods == 0) {
|
||||
NFS_DPF(ASYNCIO,
|
||||
("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp));
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (bp->b_iocmd == BIO_READ) {
|
||||
if (bp->b_rcred == NOCRED && cred != NOCRED)
|
||||
bp->b_rcred = crhold(cred);
|
||||
|
@ -229,9 +229,8 @@ nfssvc_iod(void *instance)
|
||||
* Main loop
|
||||
*/
|
||||
for (;;) {
|
||||
while (((nmp = nfs_iodmount[myiod]) == NULL
|
||||
|| !TAILQ_FIRST(&nmp->nm_bufq))
|
||||
&& error == 0) {
|
||||
while (((nmp = nfs_iodmount[myiod]) == NULL)
|
||||
|| !TAILQ_FIRST(&nmp->nm_bufq)) {
|
||||
if (myiod >= nfs_iodmax)
|
||||
goto finish;
|
||||
if (nmp)
|
||||
@ -244,6 +243,17 @@ nfssvc_iod(void *instance)
|
||||
timo = (myiod < nfs_iodmin) ? 0 : nfs_iodmaxidle * hz;
|
||||
error = msleep(&nfs_iodwant[myiod], &nfs_iod_mtx, PWAIT | PCATCH,
|
||||
"-", timo);
|
||||
if (error) {
|
||||
nmp = nfs_iodmount[myiod];
|
||||
/*
|
||||
* Rechecking the nm_bufq closes a rare race where the
|
||||
* nfsiod is woken up at the exact time the idle timeout
|
||||
* fires
|
||||
*/
|
||||
if (nmp && TAILQ_FIRST(&nmp->nm_bufq))
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error)
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user