diff options
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 9e2ee75e0f7c..ae21a4efe36c 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -828,6 +828,34 @@ static struct nfsd4_operation nfsd4_ops[]; | |||
828 | static const char *nfsd4_op_name(unsigned opnum); | 828 | static const char *nfsd4_op_name(unsigned opnum); |
829 | 829 | ||
830 | /* | 830 | /* |
831 | * This is a replay of a compound for which no cache entry pages | ||
832 | * were used. Encode the sequence operation, and if cachethis is FALSE | ||
833 | * encode the uncache rep error on the next operation. | ||
834 | */ | ||
835 | static __be32 | ||
836 | nfsd4_enc_uncached_replay(struct nfsd4_compoundargs *args, | ||
837 | struct nfsd4_compoundres *resp) | ||
838 | { | ||
839 | struct nfsd4_op *op; | ||
840 | |||
841 | dprintk("--> %s resp->opcnt %d ce_cachethis %u \n", __func__, | ||
842 | resp->opcnt, resp->cstate.slot->sl_cache_entry.ce_cachethis); | ||
843 | |||
844 | /* Encode the replayed sequence operation */ | ||
845 | BUG_ON(resp->opcnt != 1); | ||
846 | op = &args->ops[resp->opcnt - 1]; | ||
847 | nfsd4_encode_operation(resp, op); | ||
848 | |||
849 | /*return nfserr_retry_uncached_rep in next operation. */ | ||
850 | if (resp->cstate.slot->sl_cache_entry.ce_cachethis == 0) { | ||
851 | op = &args->ops[resp->opcnt++]; | ||
852 | op->status = nfserr_retry_uncached_rep; | ||
853 | nfsd4_encode_operation(resp, op); | ||
854 | } | ||
855 | return op->status; | ||
856 | } | ||
857 | |||
858 | /* | ||
831 | * Enforce NFSv4.1 COMPOUND ordering rules. | 859 | * Enforce NFSv4.1 COMPOUND ordering rules. |
832 | * | 860 | * |
833 | * TODO: | 861 | * TODO: |
@@ -895,7 +923,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
895 | dprintk("nfsv4 compound op #%d/%d: %d (%s)\n", | 923 | dprintk("nfsv4 compound op #%d/%d: %d (%s)\n", |
896 | resp->opcnt, args->opcnt, op->opnum, | 924 | resp->opcnt, args->opcnt, op->opnum, |
897 | nfsd4_op_name(op->opnum)); | 925 | nfsd4_op_name(op->opnum)); |
898 | |||
899 | /* | 926 | /* |
900 | * The XDR decode routines may have pre-set op->status; | 927 | * The XDR decode routines may have pre-set op->status; |
901 | * for example, if there is a miscellaneous XDR error | 928 | * for example, if there is a miscellaneous XDR error |
@@ -939,7 +966,10 @@ encode_op: | |||
939 | /* Only from SEQUENCE or CREATE_SESSION */ | 966 | /* Only from SEQUENCE or CREATE_SESSION */ |
940 | if (resp->cstate.status == nfserr_replay_cache) { | 967 | if (resp->cstate.status == nfserr_replay_cache) { |
941 | dprintk("%s NFS4.1 replay from cache\n", __func__); | 968 | dprintk("%s NFS4.1 replay from cache\n", __func__); |
942 | status = op->status; | 969 | if (nfsd4_not_cached(resp)) |
970 | status = nfsd4_enc_uncached_replay(args, resp); | ||
971 | else | ||
972 | status = op->status; | ||
943 | goto out; | 973 | goto out; |
944 | } | 974 | } |
945 | if (op->status == nfserr_replay_me) { | 975 | if (op->status == nfserr_replay_me) { |