diff options
author | ps <ps@FreeBSD.org> | 2005-05-04 16:37:31 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2005-05-04 16:37:31 +0000 |
commit | 40a0d434da94827c13d74391779c80cde4aa9b35 (patch) | |
tree | f41535058cd32a9851238415229e8868400bf805 | |
parent | eba8487d851b7ad1891faeed4b880133fdd442ed (diff) | |
download | FreeBSD-src-40a0d434da94827c13d74391779c80cde4aa9b35.zip FreeBSD-src-40a0d434da94827c13d74391779c80cde4aa9b35.tar.gz |
Fix a bug in NFS/TCP where retransmissions would not reliably happen
if the server rebooted or tore down the connection for any reason.
Found by: Jonathan Noack.
Submitted by: Mohan Srinivasan.
-rw-r--r-- | sys/nfsclient/nfs_socket.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index 0ba8351..6ba10e0 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -582,7 +582,8 @@ tryagain: if (rep->r_nmp->nm_flag & NFSMNT_INT) slpflag = PCATCH; mtx_lock(&nfs_reply_mtx); - while ((rep->r_mrep == NULL) && (error == 0)) + while ((rep->r_mrep == NULL) && (error == 0) && + ((sotype == SOCK_DGRAM) || ((rep->r_flags & R_MUSTRESEND) == 0))) error = msleep((caddr_t)rep, &nfs_reply_mtx, slpflag | (PZERO - 1), "nfsreq", 0); mtx_unlock(&nfs_reply_mtx); @@ -1226,11 +1227,18 @@ nfs_timer(void *arg) if (nmp->nm_sotype != SOCK_DGRAM) { if (++rep->r_rexmit > NFS_MAXREXMIT) rep->r_rexmit = NFS_MAXREXMIT; - continue; + /* + * For NFS/TCP, setting R_MUSTRESEND and waking up + * the requester will cause the request to be + * retransmitted (in nfs_reply()), re-connecting + * if necessary. + */ + rep->r_flags |= R_MUSTRESEND; + wakeup_nfsreq(rep); + continue; } if ((so = nmp->nm_so) == NULL) continue; - /* * If there is enough space and the window allows.. * Resend it |