]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
pNFS: Separate handling of NFS4ERR_LAYOUTTRYLATER and RECALLCONFLICT
authorTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 14 Jul 2016 22:46:24 +0000 (18:46 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 19 Jul 2016 20:23:22 +0000 (16:23 -0400)
They are not the same error, and need to be handled differently.

Fixes: 183d9e7b112aa ("pnfs: rework LAYOUTGET retry handling")
Cc: stable@vger.kernel.org # 4.7
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
fs/nfs/nfs4proc.c
fs/nfs/pnfs.c

index 519368b987622ea23bea210929bebfd0c327e14e..ee8efe0a52029ec5f0d9cbc46cc6d895191b6a6a 100644 (file)
@@ -437,6 +437,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
                case -NFS4ERR_DELAY:
                        nfs_inc_server_stats(server, NFSIOS_DELAY);
                case -NFS4ERR_GRACE:
+               case -NFS4ERR_LAYOUTTRYLATER:
                case -NFS4ERR_RECALLCONFLICT:
                        exception->delay = 1;
                        return 0;
@@ -7883,11 +7884,12 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,
        struct inode *inode = lgp->args.inode;
        struct nfs_server *server = NFS_SERVER(inode);
        struct pnfs_layout_hdr *lo;
-       int status = task->tk_status;
+       int nfs4err = task->tk_status;
+       int err, status = 0;
 
        dprintk("--> %s tk_status => %d\n", __func__, -task->tk_status);
 
-       switch (status) {
+       switch (nfs4err) {
        case 0:
                goto out;
 
@@ -7919,12 +7921,11 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,
                        status = -EOVERFLOW;
                        goto out;
                }
-               /* Fallthrough */
+               status = -EBUSY;
+               break;
        case -NFS4ERR_RECALLCONFLICT:
-               nfs4_handle_exception(server, -NFS4ERR_RECALLCONFLICT,
-                                       exception);
                status = -ERECALLCONFLICT;
-               goto out;
+               break;
        case -NFS4ERR_EXPIRED:
        case -NFS4ERR_BAD_STATEID:
                exception->timeout = 0;
@@ -7955,9 +7956,13 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,
                        spin_unlock(&inode->i_lock);
        }
 
-       status = nfs4_handle_exception(server, status, exception);
-       if (exception->retry)
-               status = -EAGAIN;
+       err = nfs4_handle_exception(server, nfs4err, exception);
+       if (!status) {
+               if (exception->retry)
+                       status = -EAGAIN;
+               else
+                       status = err;
+       }
 out:
        dprintk("<-- %s\n", __func__);
        return status;
index 563f131c9abe953be046ed4350cc3fd56864e332..c50d4ebab5c5b96bfca01161d7e1926cc0ce5b87 100644 (file)
@@ -1648,6 +1648,7 @@ lookup_again:
        atomic_dec(&lo->plh_outstanding);
        if (IS_ERR(lseg)) {
                switch(PTR_ERR(lseg)) {
+               case -EBUSY:
                case -ERECALLCONFLICT:
                        if (time_after(jiffies, giveup))
                                lseg = NULL;