nfsd41: encode replay sequence from the slot values
authorAndy Adamson <andros@netapp.com>
Thu, 23 Jul 2009 23:02:18 +0000 (19:02 -0400)
committerJ. Bruce Fields <bfields@citi.umich.edu>
Tue, 28 Jul 2009 20:12:34 +0000 (16:12 -0400)
The sequence operation is not cached; always encode the sequence operation on
a replay from the slot table and session values. This simplifies the sessions
replay logic in nfsd4_proc_compound.

If this is a replay of a compound that was specified not to be cached, return
NFS4ERR_RETRY_UNCACHED_REP.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c

index 23cd738..6fde431 100644 (file)
@@ -984,34 +984,6 @@ static struct nfsd4_operation nfsd4_ops[];
 static const char *nfsd4_op_name(unsigned opnum);
 
 /*
- * This is a replay of a compound for which no cache entry pages
- * were used. Encode the sequence operation, and if cachethis is FALSE
- * encode the uncache rep error on the next operation.
- */
-static __be32
-nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
-                        struct nfsd4_compoundres *resp)
-{
-       struct nfsd4_op *op;
-
-       dprintk("--> %s resp->opcnt %d ce_cachethis %u \n", __func__,
-               resp->opcnt, resp->cstate.slot->sl_cache_entry.ce_cachethis);
-
-       /* Encode the replayed sequence operation */
-       BUG_ON(resp->opcnt != 1);
-       op = &args->ops[resp->opcnt - 1];
-       nfsd4_encode_operation(resp, op);
-
-       /*return nfserr_retry_uncached_rep in next operation. */
-       if (resp->cstate.slot->sl_cache_entry.ce_cachethis == 0) {
-               op = &args->ops[resp->opcnt++];
-               op->status = nfserr_retry_uncached_rep;
-               nfsd4_encode_operation(resp, op);
-       }
-       return op->status;
-}
-
-/*
  * Enforce NFSv4.1 COMPOUND ordering rules.
  *
  * TODO:
@@ -1123,10 +1095,7 @@ encode_op:
                /* Only from SEQUENCE */
                if (resp->cstate.status == nfserr_replay_cache) {
                        dprintk("%s NFS4.1 replay from cache\n", __func__);
-                       if (nfsd4_not_cached(resp))
-                               status = nfsd4_enc_sequence_replay(args, resp);
-                       else
-                               status = op->status;
+                       status = op->status;
                        goto out;
                }
                if (op->status == nfserr_replay_me) {
index 7729d09..9295c4b 100644 (file)
@@ -1109,6 +1109,36 @@ nfsd41_copy_replay_data(struct nfsd4_compoundres *resp,
 }
 
 /*
+ * Encode the replay sequence operation from the slot values.
+ * If cachethis is FALSE encode the uncached rep error on the next
+ * operation which sets resp->p and increments resp->opcnt for
+ * nfs4svc_encode_compoundres.
+ *
+ */
+static __be32
+nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
+                         struct nfsd4_compoundres *resp)
+{
+       struct nfsd4_op *op;
+       struct nfsd4_slot *slot = resp->cstate.slot;
+
+       dprintk("--> %s resp->opcnt %d cachethis %u \n", __func__,
+               resp->opcnt, resp->cstate.slot->sl_cache_entry.ce_cachethis);
+
+       /* Encode the replayed sequence operation */
+       op = &args->ops[resp->opcnt - 1];
+       nfsd4_encode_operation(resp, op);
+
+       /* Return nfserr_retry_uncached_rep in next operation. */
+       if (args->opcnt > 1 && slot->sl_cache_entry.ce_cachethis == 0) {
+               op = &args->ops[resp->opcnt++];
+               op->status = nfserr_retry_uncached_rep;
+               nfsd4_encode_operation(resp, op);
+       }
+       return op->status;
+}
+
+/*
  * Keep the first page of the replay. Copy the NFSv4.1 data from the first
  * cached page.  Replace any futher replay pages from the cache.
  */
@@ -1131,10 +1161,12 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
         * session inactivity timer fires and a solo sequence operation
         * is sent (lease renewal).
         */
-       if (seq && nfsd4_not_cached(resp)) {
-               seq->maxslots = resp->cstate.session->se_fchannel.maxreqs;
-               return nfs_ok;
-       }
+       seq->maxslots = resp->cstate.session->se_fchannel.maxreqs;
+
+       /* Either returns 0 or nfserr_retry_uncached */
+       status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp);
+       if (status == nfserr_retry_uncached_rep)
+               return status;
 
        if (!nfsd41_copy_replay_data(resp, entry)) {
                /*