From: Trond Myklebust Date: Wed, 30 Jan 2013 18:04:10 +0000 (-0500) Subject: NFSv4.1: Handle NFS4ERR_DELAY when resetting the NFSv4.1 session X-Git-Tag: v3.4.92~127 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ba7959277325911b09944c5aedf3c4bf139be2f2;p=thirdparty%2Fkernel%2Fstable.git NFSv4.1: Handle NFS4ERR_DELAY when resetting the NFSv4.1 session commit c489ee290bdbbace6bb63ebe6ebd4dd605819495 upstream. NFS4ERR_DELAY is a legal reply when we call DESTROY_SESSION. It usually means that the server is busy handling an unfinished RPC request. Just sleep for a second and then retry. We also need to be able to handle the NFS4ERR_BACK_CHAN_BUSY return value. If the NFS server has outstanding callbacks, we just want to similarly sleep & retry. Signed-off-by: Trond Myklebust [bwh: Backported to 3.2: adjust context] Signed-off-by: Ben Hutchings Cc: Rui Xiang Signed-off-by: Greg Kroah-Hartman --- diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index e46579471ccc6..461816beff13f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1651,8 +1651,18 @@ static int nfs4_reset_session(struct nfs_client *clp) nfs4_begin_drain_session(clp); status = nfs4_proc_destroy_session(clp->cl_session); - if (status && status != -NFS4ERR_BADSESSION && - status != -NFS4ERR_DEADSESSION) { + switch (status) { + case 0: + case -NFS4ERR_BADSESSION: + case -NFS4ERR_DEADSESSION: + break; + case -NFS4ERR_BACK_CHAN_BUSY: + case -NFS4ERR_DELAY: + set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); + status = 0; + ssleep(1); + goto out; + default: status = nfs4_recovery_handle_error(clp, status); goto out; }