NFSv4.1: Handle NFS4ERR_DELAY when resetting the NFSv4.1 session

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 <Trond.Myklebust@netapp.com>
Cc: stable@vger.kernel.org

Changed files
+12 -2
fs
+12 -2
fs/nfs/nfs4state.c
··· 2018 2018 nfs4_begin_drain_session(clp); 2019 2019 cred = nfs4_get_exchange_id_cred(clp); 2020 2020 status = nfs4_proc_destroy_session(clp->cl_session, cred); 2021 - if (status && status != -NFS4ERR_BADSESSION && 2022 - status != -NFS4ERR_DEADSESSION) { 2021 + switch (status) { 2022 + case 0: 2023 + case -NFS4ERR_BADSESSION: 2024 + case -NFS4ERR_DEADSESSION: 2025 + break; 2026 + case -NFS4ERR_BACK_CHAN_BUSY: 2027 + case -NFS4ERR_DELAY: 2028 + set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); 2029 + status = 0; 2030 + ssleep(1); 2031 + goto out; 2032 + default: 2023 2033 status = nfs4_recovery_handle_error(clp, status); 2024 2034 goto out; 2025 2035 }