From: Matthew Dillon Date: Tue, 2 Nov 2010 19:55:17 +0000 (-0700) Subject: kernel - Attempt to fix lost rpc issue with NFS timeout/retry X-Git-Url: http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/c099dfbb92727b927efc935d9a5abad3e42a75b0 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 --- 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);