diff options
-rw-r--r-- | fs/nfsd/nfs4proc.c | 7 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 6 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 11 | ||||
-rw-r--r-- | include/linux/nfsd/xdr4.h | 1 |
4 files changed, 25 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index ec51936d2ce2..9e2ee75e0f7c 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -936,6 +936,12 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
936 | BUG_ON(op->status == nfs_ok); | 936 | BUG_ON(op->status == nfs_ok); |
937 | 937 | ||
938 | encode_op: | 938 | encode_op: |
939 | /* Only from SEQUENCE or CREATE_SESSION */ | ||
940 | if (resp->cstate.status == nfserr_replay_cache) { | ||
941 | dprintk("%s NFS4.1 replay from cache\n", __func__); | ||
942 | status = op->status; | ||
943 | goto out; | ||
944 | } | ||
939 | if (op->status == nfserr_replay_me) { | 945 | if (op->status == nfserr_replay_me) { |
940 | op->replay = &cstate->replay_owner->so_replay; | 946 | op->replay = &cstate->replay_owner->so_replay; |
941 | nfsd4_encode_replay(resp, op); | 947 | nfsd4_encode_replay(resp, op); |
@@ -964,6 +970,7 @@ encode_op: | |||
964 | status = nfserr_jukebox; | 970 | status = nfserr_jukebox; |
965 | } | 971 | } |
966 | 972 | ||
973 | resp->cstate.status = status; | ||
967 | fh_put(&resp->cstate.current_fh); | 974 | fh_put(&resp->cstate.current_fh); |
968 | fh_put(&resp->cstate.save_fh); | 975 | fh_put(&resp->cstate.save_fh); |
969 | BUG_ON(resp->cstate.replay_owner); | 976 | BUG_ON(resp->cstate.replay_owner); |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index a37b91dab1bf..e20d4345040f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -989,6 +989,8 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp) | |||
989 | } | 989 | } |
990 | 990 | ||
991 | resp->rqstp->rq_resused = entry->ce_resused; | 991 | resp->rqstp->rq_resused = entry->ce_resused; |
992 | resp->opcnt = entry->ce_opcnt; | ||
993 | resp->cstate.iovlen = entry->ce_datav.iov_len + entry->ce_rpchdrlen; | ||
992 | status = entry->ce_status; | 994 | status = entry->ce_status; |
993 | 995 | ||
994 | return status; | 996 | return status; |
@@ -1214,6 +1216,10 @@ nfsd4_sequence(struct svc_rqst *rqstp, | |||
1214 | if (status == nfserr_replay_cache) { | 1216 | if (status == nfserr_replay_cache) { |
1215 | cstate->slot = slot; | 1217 | cstate->slot = slot; |
1216 | cstate->session = session; | 1218 | cstate->session = session; |
1219 | /* Return the cached reply status and set cstate->status | ||
1220 | * for nfsd4_svc_encode_compoundres processing*/ | ||
1221 | status = nfsd4_replay_cache_entry(resp); | ||
1222 | cstate->status = nfserr_replay_cache; | ||
1217 | goto replay_cache; | 1223 | goto replay_cache; |
1218 | } | 1224 | } |
1219 | if (status) | 1225 | if (status) |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8556575480ce..09415bcf078e 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -3049,6 +3049,17 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo | |||
3049 | iov = &rqstp->rq_res.head[0]; | 3049 | iov = &rqstp->rq_res.head[0]; |
3050 | iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base; | 3050 | iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base; |
3051 | BUG_ON(iov->iov_len > PAGE_SIZE); | 3051 | BUG_ON(iov->iov_len > PAGE_SIZE); |
3052 | if (resp->cstate.slot != NULL) { | ||
3053 | if (resp->cstate.status == nfserr_replay_cache) { | ||
3054 | iov->iov_len = resp->cstate.iovlen; | ||
3055 | } else { | ||
3056 | nfsd4_store_cache_entry(resp); | ||
3057 | dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__); | ||
3058 | resp->cstate.slot->sl_inuse = 0; | ||
3059 | } | ||
3060 | if (resp->cstate.session) | ||
3061 | nfsd4_put_session(resp->cstate.session); | ||
3062 | } | ||
3052 | return 1; | 3063 | return 1; |
3053 | } | 3064 | } |
3054 | 3065 | ||
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h index d091684325af..69cb467cb720 100644 --- a/include/linux/nfsd/xdr4.h +++ b/include/linux/nfsd/xdr4.h | |||
@@ -52,6 +52,7 @@ struct nfsd4_compound_state { | |||
52 | struct nfsd4_session *session; | 52 | struct nfsd4_session *session; |
53 | struct nfsd4_slot *slot; | 53 | struct nfsd4_slot *slot; |
54 | __be32 *statp; | 54 | __be32 *statp; |
55 | size_t iovlen; | ||
55 | u32 status; | 56 | u32 status; |
56 | }; | 57 | }; |
57 | 58 | ||