• Trond Myklebust's avatar
    NFSv4: Fix OPEN / CLOSE race · c9399f21
    Trond Myklebust authored
    Ben Coddington has noted the following race between OPEN and CLOSE
    on a single client.
    
    Process 1		Process 2		Server
    =========		=========		======
    
    1)  OPEN file
    2)			OPEN file
    3)						Process OPEN (1) seqid=1
    4)						Process OPEN (2) seqid=2
    5)						Reply OPEN (2)
    6)			Receive reply (2)
    7)			new stateid, seqid=2
    
    8)			CLOSE file, using
    			stateid w/ seqid=2
    9)						Reply OPEN (1)
    10(						Process CLOSE (8)
    11)						Reply CLOSE (8)
    12)						Forget stateid
    						file closed
    
    13)			Receive reply (7)
    14)			Forget stateid
    			file closed.
    
    15) Receive reply (1).
    16) New stateid seqid=1
        is really the same
        stateid that was
        closed.
    
    IOW: the reply to the first OPEN is delayed. Since "Process 2" does
    not wait before closing the file, and it does not cache the closed
    stateid, then when the delayed reply is finally received, it is treated
    as setting up a new stateid by the client.
    
    The fix is to ensure that the client processes the OPEN and CLOSE calls
    in the same order in which the server processed them.
    
    This commit ensures that we examine the seqid of the stateid
    returned by OPEN. If it is a new stateid, we assume the seqid
    must be equal to the value 1, and that each state transition
    increments the seqid value by 1 (See RFC7530, Section 9.1.4.2,
    and RFC5661, Section 8.2.2).
    
    If the tracker sees that an OPEN returns with a seqid that is greater
    than the cached seqid + 1, then it bumps a flag to ensure that the
    caller waits for the RPCs carrying the missing seqids to complete.
    
    Note that there can still be pathologies where the server crashes before
    it can even send us the missing seqids. Since the OPEN call is still
    holding a slot when it waits here, that could cause the recovery to
    stall forever. To avoid that, we time out after a 5 second wait.
    Reported-by: default avatarBenjamin Coddington <bcodding@redhat.com>
    Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
    Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
    c9399f21
nfs4proc.c 256 KB