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

Commit 5ec094c1 authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

nfsd4: extend state lock over seqid replay logic



There are currently a couple races in the seqid replay code: a
retransmission could come while we're still encoding the original reply,
or a new seqid-mutating call could come as we're encoding a replay.

So, extend the state lock over the encoding (both encoding of a replayed
reply and caching of the original encoded reply).

I really hate doing this, and previously added the stateowner
reference-counting code to avoid it (which was insufficient)--but I
don't see a less complicated alternative at the moment.

Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 9072d5c6
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -408,7 +408,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	if (open->op_stateowner) {
		nfs4_get_stateowner(open->op_stateowner);
		cstate->replay_owner = open->op_stateowner;
	}
	} else
		nfs4_unlock_state();
	return status;
}
@@ -1227,6 +1227,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
			be32_to_cpu(status));

		if (cstate->replay_owner) {
			nfs4_unlock_state();
			nfs4_put_stateowner(cstate->replay_owner);
			cstate->replay_owner = NULL;
		}
+8 −4
Original line number Diff line number Diff line
@@ -3501,6 +3501,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,

	nfsd4_create_clid_dir(sop->so_client);
out:
	if (!cstate->replay_owner)
		nfs4_unlock_state();
	return status;
}
@@ -3568,6 +3569,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
	memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
	status = nfs_ok;
out:
	if (!cstate->replay_owner)
		nfs4_unlock_state();
	return status;
}
@@ -3609,6 +3611,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
	if (list_empty(&so->so_stateids))
		move_to_close_lru(so);
out:
	if (!cstate->replay_owner)
		nfs4_unlock_state();
	return status;
}
@@ -4071,6 +4074,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
out:
	if (status && lock->lk_is_new && lock_sop)
		release_lockowner(lock_sop);
	if (!cstate->replay_owner)
		nfs4_unlock_state();
	return status;
}