|
@@ -7813,20 +7813,23 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
|
|
|
dprintk("%s: NFS4ERR_RECALLCONFLICT waiting %lu\n",
|
|
|
__func__, delay);
|
|
|
rpc_delay(task, delay);
|
|
|
- task->tk_status = 0;
|
|
|
- rpc_restart_call_prepare(task);
|
|
|
- goto out; /* Do not call nfs4_async_handle_error() */
|
|
|
+ /* Do not call nfs4_async_handle_error() */
|
|
|
+ goto out_restart;
|
|
|
}
|
|
|
break;
|
|
|
case -NFS4ERR_EXPIRED:
|
|
|
case -NFS4ERR_BAD_STATEID:
|
|
|
spin_lock(&inode->i_lock);
|
|
|
- lo = NFS_I(inode)->layout;
|
|
|
- if (!lo || list_empty(&lo->plh_segs)) {
|
|
|
+ if (nfs4_stateid_match(&lgp->args.stateid,
|
|
|
+ &lgp->args.ctx->state->stateid)) {
|
|
|
spin_unlock(&inode->i_lock);
|
|
|
/* If the open stateid was bad, then recover it. */
|
|
|
state = lgp->args.ctx->state;
|
|
|
- } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ lo = NFS_I(inode)->layout;
|
|
|
+ if (lo && nfs4_stateid_match(&lgp->args.stateid,
|
|
|
+ &lo->plh_stateid)) {
|
|
|
LIST_HEAD(head);
|
|
|
|
|
|
/*
|
|
@@ -7837,16 +7840,19 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
|
|
|
pnfs_mark_matching_lsegs_invalid(lo, &head, NULL);
|
|
|
spin_unlock(&inode->i_lock);
|
|
|
pnfs_free_lseg_list(&head);
|
|
|
-
|
|
|
- task->tk_status = 0;
|
|
|
- rpc_restart_call_prepare(task);
|
|
|
- }
|
|
|
+ } else
|
|
|
+ spin_unlock(&inode->i_lock);
|
|
|
+ goto out_restart;
|
|
|
}
|
|
|
if (nfs4_async_handle_error(task, server, state, NULL) == -EAGAIN)
|
|
|
- rpc_restart_call_prepare(task);
|
|
|
+ goto out_restart;
|
|
|
out:
|
|
|
dprintk("<-- %s\n", __func__);
|
|
|
return;
|
|
|
+out_restart:
|
|
|
+ task->tk_status = 0;
|
|
|
+ rpc_restart_call_prepare(task);
|
|
|
+ return;
|
|
|
out_overflow:
|
|
|
task->tk_status = -EOVERFLOW;
|
|
|
goto out;
|