summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2005-05-04 16:37:31 +0000
committerps <ps@FreeBSD.org>2005-05-04 16:37:31 +0000
commit40a0d434da94827c13d74391779c80cde4aa9b35 (patch)
treef41535058cd32a9851238415229e8868400bf805 /sys
parenteba8487d851b7ad1891faeed4b880133fdd442ed (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys')
-rw-r--r--sys/nfsclient/nfs_socket.c14
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
OpenPOWER on IntegriCloud