Commit 287a9c55 authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

NFSv4: Clean up pNFS return-on-close error handling



Both close and delegreturn have identical code to handle pNFS
return-on-close. This patch refactors that code and places it
in pnfs.c

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 9c47b18c
Loading
Loading
Loading
Loading
+10 −56
Original line number Diff line number Diff line
@@ -3363,32 +3363,11 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
	trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status);

	/* Handle Layoutreturn errors */
	if (calldata->arg.lr_args && task->tk_status != 0) {
		switch (calldata->res.lr_ret) {
		default:
			calldata->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
			break;
		case 0:
			calldata->arg.lr_args = NULL;
			calldata->res.lr_res = NULL;
			break;
		case -NFS4ERR_OLD_STATEID:
			if (nfs4_layoutreturn_refresh_stateid(&calldata->arg.lr_args->stateid,
						&calldata->arg.lr_args->range,
						calldata->inode))
				goto lr_restart;
			/* Fallthrough */
		case -NFS4ERR_ADMIN_REVOKED:
		case -NFS4ERR_DELEG_REVOKED:
		case -NFS4ERR_EXPIRED:
		case -NFS4ERR_BAD_STATEID:
		case -NFS4ERR_UNKNOWN_LAYOUTTYPE:
		case -NFS4ERR_WRONG_CRED:
			calldata->arg.lr_args = NULL;
			calldata->res.lr_res = NULL;
			goto lr_restart;
		}
	}
	if (pnfs_roc_done(task, calldata->inode,
				&calldata->arg.lr_args,
				&calldata->res.lr_res,
				&calldata->res.lr_ret) == -EAGAIN)
		goto out_restart;

	/* hmm. we are done with the inode, and in the process of freeing
	 * the state_owner. we keep this around to process errors
@@ -3435,8 +3414,6 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
	nfs_refresh_inode(calldata->inode, &calldata->fattr);
	dprintk("%s: done, ret = %d!\n", __func__, task->tk_status);
	return;
lr_restart:
	calldata->res.lr_ret = 0;
out_restart:
	task->tk_status = 0;
	rpc_restart_call_prepare(task);
@@ -6128,32 +6105,11 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
	trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status);

	/* Handle Layoutreturn errors */
	if (data->args.lr_args && task->tk_status != 0) {
		switch(data->res.lr_ret) {
		default:
			data->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
			break;
		case 0:
			data->args.lr_args = NULL;
			data->res.lr_res = NULL;
			break;
		case -NFS4ERR_OLD_STATEID:
			if (nfs4_layoutreturn_refresh_stateid(&data->args.lr_args->stateid,
						&data->args.lr_args->range,
						data->inode))
				goto lr_restart;
			/* Fallthrough */
		case -NFS4ERR_ADMIN_REVOKED:
		case -NFS4ERR_DELEG_REVOKED:
		case -NFS4ERR_EXPIRED:
		case -NFS4ERR_BAD_STATEID:
		case -NFS4ERR_UNKNOWN_LAYOUTTYPE:
		case -NFS4ERR_WRONG_CRED:
			data->args.lr_args = NULL;
			data->res.lr_res = NULL;
			goto lr_restart;
		}
	}
	if (pnfs_roc_done(task, data->inode,
				&data->args.lr_args,
				&data->res.lr_res,
				&data->res.lr_ret) == -EAGAIN)
		goto out_restart;

	switch (task->tk_status) {
	case 0:
@@ -6191,8 +6147,6 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
	}
	data->rpc_status = task->tk_status;
	return;
lr_restart:
	data->res.lr_ret = 0;
out_restart:
	task->tk_status = 0;
	rpc_restart_call_prepare(task);
+27 −0
Original line number Diff line number Diff line
@@ -1440,6 +1440,33 @@ bool pnfs_roc(struct inode *ino,
	return false;
}

int pnfs_roc_done(struct rpc_task *task, struct inode *inode,
		struct nfs4_layoutreturn_args **argpp,
		struct nfs4_layoutreturn_res **respp,
		int *ret)
{
	struct nfs4_layoutreturn_args *arg = *argpp;
	int retval = -EAGAIN;

	if (!arg)
		return 0;
	/* Handle Layoutreturn errors */
	switch (*ret) {
	case 0:
		retval = 0;
		break;
	case -NFS4ERR_OLD_STATEID:
		if (!nfs4_layoutreturn_refresh_stateid(&arg->stateid,
					&arg->range, inode))
			break;
		*ret = -NFS4ERR_NOMATCHING_LAYOUT;
		return -EAGAIN;
	}
	*argpp = NULL;
	*respp = NULL;
	return retval;
}

void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
		struct nfs4_layoutreturn_res *res,
		int ret)
+13 −0
Original line number Diff line number Diff line
@@ -282,6 +282,10 @@ bool pnfs_roc(struct inode *ino,
		struct nfs4_layoutreturn_args *args,
		struct nfs4_layoutreturn_res *res,
		const struct cred *cred);
int pnfs_roc_done(struct rpc_task *task, struct inode *inode,
		struct nfs4_layoutreturn_args **argpp,
		struct nfs4_layoutreturn_res **respp,
		int *ret);
void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
		struct nfs4_layoutreturn_res *res,
		int ret);
@@ -701,6 +705,15 @@ pnfs_roc(struct inode *ino,
	return false;
}

static inline int
pnfs_roc_done(struct rpc_task *task, struct inode *inode,
		struct nfs4_layoutreturn_args **argpp,
		struct nfs4_layoutreturn_res **respp,
		int *ret)
{
	return 0;
}

static inline void
pnfs_roc_release(struct nfs4_layoutreturn_args *args,
		struct nfs4_layoutreturn_res *res,