From c099dfbb92727b927efc935d9a5abad3e42a75b0 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 2 Nov 2010 12:55:17 -0700 Subject: [PATCH] kernel - Attempt to fix lost rpc issue with NFS timeout/retry * An edge case in the timeout/retry code failed to pick up on async RPCs which are replied to while the timeout code has the rpc locked for retry. Reported-by: Thomas Nikolajsen --- sys/vfs/nfs/nfs_socket.c | 17 ++++++++++++++++- 1 files changed, 16 insertions(+), 1 deletions(-) diff --git a/sys/vfs/nfs/nfs_socket.c b/sys/vfs/nfs/nfs_socket.c index f1d7dea..c879c8b 100644 --- a/sys/vfs/nfs/nfs_socket.c +++ b/sys/vfs/nfs/nfs_socket.c @@ -1718,13 +1718,28 @@ nfs_timer_callout(void *arg /* never used */) continue; if (req->r_flags & (R_SOFTTERM | R_LOCKED)) continue; + + /* + * Handle timeout/retry. Be sure to process r_mrep + * for async requests that completed while we had + * the request locked or they will hang in the reqq + * forever. + */ req->r_flags |= R_LOCKED; if (nfs_sigintr(nmp, req, req->r_td)) { nfs_softterm(req, 1); + req->r_flags &= ~R_LOCKED; } else { nfs_timer_req(req); + if (req->r_flags & R_ASYNC) { + if (req->r_mrep) + nfs_hardterm(req, 1); + req->r_flags &= ~R_LOCKED; + nfssvc_iod_reader_wakeup(nmp); + } else { + req->r_flags &= ~R_LOCKED; + } } - req->r_flags &= ~R_LOCKED; if (req->r_flags & R_WANTED) { req->r_flags &= ~R_WANTED; wakeup(req); -- 1.7.7.2