diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4state.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index e13d2233ff8..dc792b6b451 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1465,8 +1465,16 @@ nfsd4_process_open1(struct nfsd4_open *open) sop = find_openstateowner_str(strhashval, open); if (sop) { open->op_stateowner = sop; - /* check for replay */ - if (open->op_seqid == sop->so_seqid - 1){ + if (!sop->so_confirmed) { + /* Replace any unconfirmed stateowner without + * even checking for replays */ + clp = sop->so_client; + release_stateowner(sop); + } else if (open->op_seqid == sop->so_seqid) { + /* normal case */ + goto renew; + } else if (open->op_seqid == sop->so_seqid - 1) { + /* replay */ if (sop->so_replay.rp_buflen) return NFSERR_REPLAY_ME; else { @@ -1480,19 +1488,9 @@ nfsd4_process_open1(struct nfsd4_open *open) " replay with no replay cache\n"); goto renew; } - } else if (sop->so_confirmed) { - if (open->op_seqid == sop->so_seqid) - goto renew; + } else { status = nfserr_bad_seqid; goto out; - } else { - /* If we get here, we received an OPEN for an - * unconfirmed nfs4_stateowner. Since the seqid's are - * different, purge the existing nfs4_stateowner, and - * instantiate a new one. - */ - clp = sop->so_client; - release_stateowner(sop); } } else { /* nfs4_stateowner not found. |