nfsd4: decoding errors can still be cached and require space
authorJ. Bruce Fields <bfields@redhat.com>
Mon, 19 May 2014 16:27:11 +0000 (12:27 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 23 May 2014 13:03:44 +0000 (09:03 -0400)
Currently a non-idempotent op reply may be cached if it fails in the
proc code but not if it fails at xdr decoding.  I doubt there are any
xdr-decoding-time errors that would make this a problem in practice, so
this probably isn't a serious bug.

The space estimates should also take into account space required for
encoding of error returns.  Again, not a practical problem, though it
would become one after future patches which will tighten the space
estimates.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4xdr.c

index 9d60a1c08105ca07afe29abfb2e0ec8ec877366e..b0e075cd6c9924c1b27f2173d65fc7818deda6d9 100644 (file)
@@ -1215,6 +1215,8 @@ static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op)
 
 bool nfsd4_cache_this_op(struct nfsd4_op *op)
 {
+       if (op->opnum == OP_ILLEGAL)
+               return false;
        return OPDESC(op)->op_flags & OP_CACHEME;
 }
 
index 18881f34737ad89e8259042fd33ee5d6a9c26edc..e866a06b66bdde9efefbfb052c2d3a7c98b7a9c5 100644 (file)
@@ -1677,11 +1677,6 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
                        op->opnum = OP_ILLEGAL;
                        op->status = nfserr_op_illegal;
                }
-
-               if (op->status) {
-                       argp->opcnt = i+1;
-                       break;
-               }
                /*
                 * We'll try to cache the result in the DRC if any one
                 * op in the compound wants to be cached:
@@ -1689,6 +1684,11 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
                cachethis |= nfsd4_cache_this_op(op);
 
                max_reply = max(max_reply, nfsd4_max_reply(op->opnum));
+
+               if (op->status) {
+                       argp->opcnt = i+1;
+                       break;
+               }
        }
        /* Sessions make the DRC unnecessary: */
        if (argp->minorversion)