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 | |
| 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>
| -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. |
