Commit e85d7ee4 authored by Trond Myklebust's avatar Trond Myklebust

pNFS: Separate handling of NFS4ERR_LAYOUTTRYLATER and RECALLCONFLICT

They are not the same error, and need to be handled differently.

Fixes: 183d9e7b ("pnfs: rework LAYOUTGET retry handling")
Cc: stable@vger.kernel.org # 4.7
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: default avatarJeff Layton <jlayton@redhat.com>
parent 56b38a1f
...@@ -437,6 +437,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server, ...@@ -437,6 +437,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
case -NFS4ERR_DELAY: case -NFS4ERR_DELAY:
nfs_inc_server_stats(server, NFSIOS_DELAY); nfs_inc_server_stats(server, NFSIOS_DELAY);
case -NFS4ERR_GRACE: case -NFS4ERR_GRACE:
case -NFS4ERR_LAYOUTTRYLATER:
case -NFS4ERR_RECALLCONFLICT: case -NFS4ERR_RECALLCONFLICT:
exception->delay = 1; exception->delay = 1;
return 0; return 0;
...@@ -7883,11 +7884,12 @@ nfs4_layoutget_handle_exception(struct rpc_task *task, ...@@ -7883,11 +7884,12 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,
struct inode *inode = lgp->args.inode; struct inode *inode = lgp->args.inode;
struct nfs_server *server = NFS_SERVER(inode); struct nfs_server *server = NFS_SERVER(inode);
struct pnfs_layout_hdr *lo; 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); dprintk("--> %s tk_status => %d\n", __func__, -task->tk_status);
switch (status) { switch (nfs4err) {
case 0: case 0:
goto out; goto out;
...@@ -7919,12 +7921,11 @@ nfs4_layoutget_handle_exception(struct rpc_task *task, ...@@ -7919,12 +7921,11 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,
status = -EOVERFLOW; status = -EOVERFLOW;
goto out; goto out;
} }
/* Fallthrough */ status = -EBUSY;
break;
case -NFS4ERR_RECALLCONFLICT: case -NFS4ERR_RECALLCONFLICT:
nfs4_handle_exception(server, -NFS4ERR_RECALLCONFLICT,
exception);
status = -ERECALLCONFLICT; status = -ERECALLCONFLICT;
goto out; break;
case -NFS4ERR_EXPIRED: case -NFS4ERR_EXPIRED:
case -NFS4ERR_BAD_STATEID: case -NFS4ERR_BAD_STATEID:
exception->timeout = 0; exception->timeout = 0;
...@@ -7955,9 +7956,13 @@ nfs4_layoutget_handle_exception(struct rpc_task *task, ...@@ -7955,9 +7956,13 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
} }
status = nfs4_handle_exception(server, status, exception); err = nfs4_handle_exception(server, nfs4err, exception);
if (!status) {
if (exception->retry) if (exception->retry)
status = -EAGAIN; status = -EAGAIN;
else
status = err;
}
out: out:
dprintk("<-- %s\n", __func__); dprintk("<-- %s\n", __func__);
return status; return status;
......
...@@ -1648,6 +1648,7 @@ pnfs_update_layout(struct inode *ino, ...@@ -1648,6 +1648,7 @@ pnfs_update_layout(struct inode *ino,
atomic_dec(&lo->plh_outstanding); atomic_dec(&lo->plh_outstanding);
if (IS_ERR(lseg)) { if (IS_ERR(lseg)) {
switch(PTR_ERR(lseg)) { switch(PTR_ERR(lseg)) {
case -EBUSY:
case -ERECALLCONFLICT: case -ERECALLCONFLICT:
if (time_after(jiffies, giveup)) if (time_after(jiffies, giveup))
lseg = NULL; lseg = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment