diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2006-01-18 20:43:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-18 22:20:26 -0500 |
commit | ae8b625313db4dd4b060962c2a02f3a2837ca61b (patch) | |
tree | 537c4cc4225321099423d37f85da9264e2b69c2b /fs/nfsd/nfs4state.c | |
parent | a525825df15221a95d4c1f5a291d9fde77ef10bc (diff) |
[PATCH] nfsd4: no replays on unconfirmed owners
We shouldn't check for replays until after checking whether the open owner is
confirmed. Clients are allowed to reuse openowners without bumping the seqid.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-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 e13d2233ff8c..dc792b6b4513 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1465,8 +1465,16 @@ nfsd4_process_open1(struct nfsd4_open *open) | |||
1465 | sop = find_openstateowner_str(strhashval, open); | 1465 | sop = find_openstateowner_str(strhashval, open); |
1466 | if (sop) { | 1466 | if (sop) { |
1467 | open->op_stateowner = sop; | 1467 | open->op_stateowner = sop; |
1468 | /* check for replay */ | 1468 | if (!sop->so_confirmed) { |
1469 | if (open->op_seqid == sop->so_seqid - 1){ | 1469 | /* Replace any unconfirmed stateowner without |
1470 | * even checking for replays */ | ||
1471 | clp = sop->so_client; | ||
1472 | release_stateowner(sop); | ||
1473 | } else if (open->op_seqid == sop->so_seqid) { | ||
1474 | /* normal case */ | ||
1475 | goto renew; | ||
1476 | } else if (open->op_seqid == sop->so_seqid - 1) { | ||
1477 | /* replay */ | ||
1470 | if (sop->so_replay.rp_buflen) | 1478 | if (sop->so_replay.rp_buflen) |
1471 | return NFSERR_REPLAY_ME; | 1479 | return NFSERR_REPLAY_ME; |
1472 | else { | 1480 | else { |
@@ -1480,19 +1488,9 @@ nfsd4_process_open1(struct nfsd4_open *open) | |||
1480 | " replay with no replay cache\n"); | 1488 | " replay with no replay cache\n"); |
1481 | goto renew; | 1489 | goto renew; |
1482 | } | 1490 | } |
1483 | } else if (sop->so_confirmed) { | 1491 | } else { |
1484 | if (open->op_seqid == sop->so_seqid) | ||
1485 | goto renew; | ||
1486 | status = nfserr_bad_seqid; | 1492 | status = nfserr_bad_seqid; |
1487 | goto out; | 1493 | goto out; |
1488 | } else { | ||
1489 | /* If we get here, we received an OPEN for an | ||
1490 | * unconfirmed nfs4_stateowner. Since the seqid's are | ||
1491 | * different, purge the existing nfs4_stateowner, and | ||
1492 | * instantiate a new one. | ||
1493 | */ | ||
1494 | clp = sop->so_client; | ||
1495 | release_stateowner(sop); | ||
1496 | } | 1494 | } |
1497 | } else { | 1495 | } else { |
1498 | /* nfs4_stateowner not found. | 1496 | /* nfs4_stateowner not found. |