[PATCH] nfsd4: no replays on unconfirmed owners
J. Bruce Fields [Thu, 19 Jan 2006 01:43:32 +0000 (17:43 -0800)]
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>

fs/nfsd/nfs4state.c

index e13d223..dc792b6 100644 (file)
@@ -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.