Repository navigation
Conversation
…ached response Motivation: For every nfsv4.0 open-owner and lock-owner the server must keep the last sequence id together with the response of the last request, and answer a retransmission of that request with the cached response (rfc7530 9.1.7). The server validates the sequence id but consumes it immediately, before the operation is executed, and treats every retransmission as NFS4ERR_BAD_SEQID. Clients retransmit with an unchanged sequence id after a lost or timed out reply and, notably, when the server answers with NFS4ERR_DELAY: the macOS client resends the identical request from the RPC layer with a new xid (so a transport level duplicate request cache does not recognize it), and the Linux client behaves alike. A server answering NFS4ERR_DELAY after having consumed the sequence id, e.g. because the virtual file system delays a reply while a backend operation is pending, therefore rejects the retry with NFS4ERR_BAD_SEQID. As neither side advances its sequence id on that error and it does not trigger client state recovery, the owner remains out of sync for good and every subsequent OPEN, CLOSE or LOCK of that owner fails. Modification: Move the consumption of the sequence id behind the execution of the operation. StateOwner validates the sequence id up front and detects retransmissions, the operation executes, and the sequence id is consumed together with the response, or with the recorded failure, unless the request failed with one of the errors that do not consume a sequence id per rfc7530 9.1.7, or with NFS4ERR_DELAY, which clients retry with an unchanged sequence id. A retransmission is answered with the cached response or recorded failure without executing the operation again. OPEN, OPEN_CONFIRM, OPEN_DOWNGRADE, CLOSE, LOCK and LOCKU follow this pattern through a shared SequencedRequest helper; LOCK with a new lock owner checks both sequence values and answers the request as a retransmission when either of them matches a previous request, as required by rfc7530 9.1.9, and consumes both the open-owner and the lock-owner sequence id, mirroring the client. NFS4Client#getOrCreateOwner now only creates the owner, validation and consumption happen in the operation. Minor versions with sessions are unaffected. A retransmission of a successful CLOSE is out of scope, as the state referenced by the retransmitted request is already disposed; detecting it would require retaining recently closed state ids. Result: Retransmissions of sequenced nfsv4.0 requests are answered with the cached response of the original request, and NFS4ERR_DELAY no longer consumes a sequence id, keeping owners in sync with retrying clients. New tests cover replay detection, replay of failures and the NFS4ERR_DELAY retry at both the StateOwner and the compound level. Fixes: dCache#179 Target: master Signed-off-by: Yves Langisch <yla@iterate.ch>
Member
|
@ylangisc thanks for the contribution. While I am going through your changes, I have a question. Why are you not using v4.1, as the latest macOS clients already support it? |
Contributor
Author
macOS Tahoe is the first version supporting v4.1 but we still have plenty of users using older macOS versions. We try to mount with v4.1 and fallback to v4.0 if it's not supported. |
Member
|
I am still trying to understand the changes, the pynfs tests looks more happy with our changes: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation:
For every nfsv4.0 open-owner and lock-owner the server must keep the last
sequence id together with the response of the last request, and answer a
retransmission of that request with the cached response (rfc7530 9.1.7).
The server validates the sequence id but consumes it immediately, before
the operation is executed, and treats every retransmission as
NFS4ERR_BAD_SEQID. Clients retransmit with an unchanged sequence id after
a lost or timed out reply and, notably, when the server answers with
NFS4ERR_DELAY: the macOS client resends the identical request from the
RPC layer with a new xid (so a transport level duplicate request cache
does not recognize it), and the Linux client behaves alike. A server
answering NFS4ERR_DELAY after having consumed the sequence id, e.g.
because the virtual file system delays a reply while a backend operation
is pending, therefore rejects the retry with NFS4ERR_BAD_SEQID. As
neither side advances its sequence id on that error and it does not
trigger client state recovery, the owner remains out of sync for good and
every subsequent OPEN, CLOSE or LOCK of that owner fails.
Modification:
Move the consumption of the sequence id behind the execution of the
operation. StateOwner validates the sequence id up front and detects
retransmissions, the operation executes, and the sequence id is consumed
together with the response, or with the recorded failure, unless the
request failed with one of the errors that do not consume a sequence id
per rfc7530 9.1.7, or with NFS4ERR_DELAY, which clients retry with an
unchanged sequence id. A retransmission is answered with the cached
response or recorded failure without executing the operation again.
OPEN, OPEN_CONFIRM, OPEN_DOWNGRADE, CLOSE, LOCK and LOCKU follow this
pattern through a shared SequencedRequest helper; LOCK with a new lock
owner checks both sequence values and answers the request as a
retransmission when either of them matches a previous request, as
required by rfc7530 9.1.9, and consumes both the open-owner and the
lock-owner sequence id, mirroring the client. NFS4Client#getOrCreateOwner now only creates the
owner, validation and consumption happen in the operation. Minor
versions with sessions are unaffected. A retransmission of a successful
CLOSE is out of scope, as the state referenced by the retransmitted
request is already disposed; detecting it would require retaining
recently closed state ids.
Result:
Retransmissions of sequenced nfsv4.0 requests are answered with the
cached response of the original request, and NFS4ERR_DELAY no longer
consumes a sequence id, keeping owners in sync with retrying clients.
New tests cover replay detection, replay of failures and the
NFS4ERR_DELAY retry at both the StateOwner and the compound level.
Fixes: #179
Target: master