aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2006-01-18 20:43:32 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-18 22:20:26 -0500
commitae8b625313db4dd4b060962c2a02f3a2837ca61b (patch)
tree537c4cc4225321099423d37f85da9264e2b69c2b
parenta525825df15221a95d4c1f5a291d9fde77ef10bc (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.c24
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.