• Jeff Layton's avatar
    nfsd: serialize state seqid morphing operations · 35a92fe8
    Jeff Layton authored
    Andrew was seeing a race occur when an OPEN and OPEN_DOWNGRADE were
    running in parallel. The server would receive the OPEN_DOWNGRADE first
    and check its seqid, but then an OPEN would race in and bump it. The
    OPEN_DOWNGRADE would then complete and bump the seqid again.  The result
    was that the OPEN_DOWNGRADE would be applied after the OPEN, even though
    it should have been rejected since the seqid changed.
    
    The only recourse we have here I think is to serialize operations that
    bump the seqid in a stateid, particularly when we're given a seqid in
    the call. To address this, we add a new rw_semaphore to the
    nfs4_ol_stateid struct. We do a down_write prior to checking the seqid
    after looking up the stateid to ensure that nothing else is going to
    bump it while we're operating on it.
    
    In the case of OPEN, we do a down_read, as the call doesn't contain a
    seqid. Those can run in parallel -- we just need to serialize them when
    there is a concurrent OPEN_DOWNGRADE or CLOSE.
    
    LOCK and LOCKU however always take the write lock as there is no
    opportunity for parallelizing those.
    Reported-and-Tested-by: default avatarAndrew W Elble <aweits@rit.edu>
    Signed-off-by: default avatarJeff Layton <jeff.layton@primarydata.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    35a92fe8
nfs4state.c 172 KB