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

Commit 9c27869d authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

NFSv4: Pass the stateid to the exception handler in nfs4_read/write_done_cb



The actual stateid used in the READ or WRITE can represent a delegation,
a lock or a stateid, so it is useful to pass it as an argument to the
exception handler when an expired/revoked response is received from the
server. It also ensures that we don't re-label the state as needing
recovery if that has already occurred.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Tested-by: default avatarOleg Drokin <green@linuxhacker.ru>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 26f47443
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -4525,12 +4525,19 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_pgio_header *hdr)
	struct nfs_server *server = NFS_SERVER(hdr->inode);

	trace_nfs4_read(hdr, task->tk_status);
	if (nfs4_async_handle_error(task, server,
				    hdr->args.context->state,
				    NULL) == -EAGAIN) {
	if (task->tk_status < 0) {
		struct nfs4_exception exception = {
			.inode = hdr->inode,
			.state = hdr->args.context->state,
			.stateid = &hdr->args.stateid,
		};
		task->tk_status = nfs4_async_handle_exception(task,
				server, task->tk_status, &exception);
		if (exception.retry) {
			rpc_restart_call_prepare(task);
			return -EAGAIN;
		}
	}

	__nfs4_read_done_cb(hdr);
	if (task->tk_status > 0)
@@ -4598,12 +4605,20 @@ static int nfs4_write_done_cb(struct rpc_task *task,
	struct inode *inode = hdr->inode;

	trace_nfs4_write(hdr, task->tk_status);
	if (nfs4_async_handle_error(task, NFS_SERVER(inode),
				    hdr->args.context->state,
				    NULL) == -EAGAIN) {
	if (task->tk_status < 0) {
		struct nfs4_exception exception = {
			.inode = hdr->inode,
			.state = hdr->args.context->state,
			.stateid = &hdr->args.stateid,
		};
		task->tk_status = nfs4_async_handle_exception(task,
				NFS_SERVER(inode), task->tk_status,
				&exception);
		if (exception.retry) {
			rpc_restart_call_prepare(task);
			return -EAGAIN;
		}
	}
	if (task->tk_status >= 0) {
		renew_lease(NFS_SERVER(inode), hdr->timestamp);
		nfs_writeback_update_inode(hdr);