summaryrefslogtreecommitdiff
path: root/fs/nfsd/nfs4proc.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-08-31 01:02:48 +0400
committerJ. Bruce Fields <bfields@redhat.com>2011-09-01 15:07:59 +0400
commit5ec094c1096ab3bb795651855d53f18daa26afde (patch)
treecb9cbbd50698cf039cf81823d40e073fbcdf53da /fs/nfsd/nfs4proc.c
parent9072d5c66b17292e3cd055bc8057b2ce6af2fe34 (diff)
downloadlinux-5ec094c1096ab3bb795651855d53f18daa26afde.tar.xz
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: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r--fs/nfsd/nfs4proc.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 50bae7471147..50063a85f505 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -408,8 +408,8 @@ out:
if (open->op_stateowner) {
nfs4_get_stateowner(open->op_stateowner);
cstate->replay_owner = open->op_stateowner;
- }
- nfs4_unlock_state();
+ } else
+ nfs4_unlock_state();
return status;
}
@@ -1227,6 +1227,7 @@ encode_op:
be32_to_cpu(status));
if (cstate->replay_owner) {
+ nfs4_unlock_state();
nfs4_put_stateowner(cstate->replay_owner);
cstate->replay_owner = NULL;
}