Commit 7a84394f authored by Joshua Watt's avatar Joshua Watt Committed by Anna Schumaker
Browse files

NFS4: Apply delay_retrans to async operations



The setting of delay_retrans is applied to synchronous RPC operations
because the retransmit count is stored in same struct nfs4_exception
that is passed each time an error is checked. However, for asynchronous
operations (READ, WRITE, LOCKU, CLOSE, DELEGRETURN), a new struct
nfs4_exception is made on the stack each time the task callback is
invoked. This means that the retransmit count is always zero and thus
delay_retrans never takes effect.

Apply delay_retrans to these operations by tracking and updating their
retransmit count.

Change-Id: Ieb33e046c2b277cb979caa3faca7f52faf0568c9
Signed-off-by: default avatarJoshua Watt <jpewhacker@gmail.com>
Reviewed-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Signed-off-by: default avatarAnna Schumaker <anna.schumaker@oracle.com>
parent 8db4a1d1
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -3636,6 +3636,7 @@ struct nfs4_closedata {
	} lr;
	struct nfs_fattr fattr;
	unsigned long timestamp;
	unsigned short retrans;
};

static void nfs4_free_closedata(void *data)
@@ -3664,6 +3665,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
		.state = state,
		.inode = calldata->inode,
		.stateid = &calldata->arg.stateid,
		.retrans = calldata->retrans,
	};

	if (!nfs4_sequence_done(task, &calldata->res.seq_res))
@@ -3711,6 +3713,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
		default:
			task->tk_status = nfs4_async_handle_exception(task,
					server, task->tk_status, &exception);
			calldata->retrans = exception.retrans;
			if (exception.retry)
				goto out_restart;
	}
@@ -5593,9 +5596,11 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_pgio_header *hdr)
			.inode = hdr->inode,
			.state = hdr->args.context->state,
			.stateid = &hdr->args.stateid,
			.retrans = hdr->retrans,
		};
		task->tk_status = nfs4_async_handle_exception(task,
				server, task->tk_status, &exception);
		hdr->retrans = exception.retrans;
		if (exception.retry) {
			rpc_restart_call_prepare(task);
			return -EAGAIN;
@@ -5709,10 +5714,12 @@ static int nfs4_write_done_cb(struct rpc_task *task,
			.inode = hdr->inode,
			.state = hdr->args.context->state,
			.stateid = &hdr->args.stateid,
			.retrans = hdr->retrans,
		};
		task->tk_status = nfs4_async_handle_exception(task,
				NFS_SERVER(inode), task->tk_status,
				&exception);
		hdr->retrans = exception.retrans;
		if (exception.retry) {
			rpc_restart_call_prepare(task);
			return -EAGAIN;
@@ -6726,6 +6733,7 @@ struct nfs4_delegreturndata {
	struct nfs_fh fh;
	nfs4_stateid stateid;
	unsigned long timestamp;
	unsigned short retrans;
	struct {
		struct nfs4_layoutreturn_args arg;
		struct nfs4_layoutreturn_res res;
@@ -6746,6 +6754,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
		.inode = data->inode,
		.stateid = &data->stateid,
		.task_is_privileged = data->args.seq_args.sa_privileged,
		.retrans = data->retrans,
	};

	if (!nfs4_sequence_done(task, &data->res.seq_res))
@@ -6817,6 +6826,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
		task->tk_status = nfs4_async_handle_exception(task,
				data->res.server, task->tk_status,
				&exception);
		data->retrans = exception.retrans;
		if (exception.retry)
			goto out_restart;
	}
@@ -7093,6 +7103,7 @@ struct nfs4_unlockdata {
	struct file_lock fl;
	struct nfs_server *server;
	unsigned long timestamp;
	unsigned short retrans;
};

static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
@@ -7147,6 +7158,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
	struct nfs4_exception exception = {
		.inode = calldata->lsp->ls_state->inode,
		.stateid = &calldata->arg.stateid,
		.retrans = calldata->retrans,
	};

	if (!nfs4_sequence_done(task, &calldata->res.seq_res))
@@ -7180,6 +7192,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
			task->tk_status = nfs4_async_handle_exception(task,
					calldata->server, task->tk_status,
					&exception);
			calldata->retrans = exception.retrans;
			if (exception.retry)
				rpc_restart_call_prepare(task);
	}
+1 −0
Original line number Diff line number Diff line
@@ -1659,6 +1659,7 @@ struct nfs_pgio_header {
	void			*netfs;
#endif

	unsigned short		retrans;
	int			pnfs_error;
	int			error;		/* merge with pnfs_error */
	unsigned int		good_bytes;	/* boundary of good data */