Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2259f960 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4.x/pnfs: Don't try to recover stateids twice in layoutget



If the current open or layout stateid doesn't match the stateid used
in the layoutget RPC call, then don't try to recover it.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 24311f88
Loading
Loading
Loading
Loading
+17 −11
Original line number Diff line number Diff line
@@ -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;