]> git.baikalelectronics.ru Git - kernel.git/commit
nfsd: serialize state seqid morphing operations
authorJeff Layton <jlayton@poochiereds.net>
Thu, 17 Sep 2015 11:47:08 +0000 (07:47 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Mon, 12 Oct 2015 21:31:03 +0000 (17:31 -0400)
commit5ea12d6ace5c1ab7027a7ebc93355004b84d7629
tree3c844e8991d12036688ece6073cd6f2d4cd17b13
parent19ec1060a5b2c948b3072a0e0674725f1c971414
nfsd: serialize state seqid morphing operations

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: Andrew W Elble <aweits@rit.edu>
Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
Cc: stable@vger.kernel.org
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4state.c
fs/nfsd/state.h