diff options
author | Andy Adamson <andros@netapp.com> | 2009-07-23 19:02:18 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-07-28 16:12:34 -0400 |
commit | abfabf8cafa60e7876a7193fb344f739f690071d (patch) | |
tree | 1cc9faa1a82d7ac7ef08bdb8af7acb8a30c9903d /fs/nfsd/nfs4state.c | |
parent | c8647947f8c13ee2647505debae284ab1c859e65 (diff) |
nfsd41: encode replay sequence from the slot values
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>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 7729d092c8a5..9295c4b56bce 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1109,6 +1109,36 @@ nfsd41_copy_replay_data(struct nfsd4_compoundres *resp, | |||
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | /* | 1111 | /* |
1112 | * Encode the replay sequence operation from the slot values. | ||
1113 | * If cachethis is FALSE encode the uncached rep error on the next | ||
1114 | * operation which sets resp->p and increments resp->opcnt for | ||
1115 | * nfs4svc_encode_compoundres. | ||
1116 | * | ||
1117 | */ | ||
1118 | static __be32 | ||
1119 | nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args, | ||
1120 | struct nfsd4_compoundres *resp) | ||
1121 | { | ||
1122 | struct nfsd4_op *op; | ||
1123 | struct nfsd4_slot *slot = resp->cstate.slot; | ||
1124 | |||
1125 | dprintk("--> %s resp->opcnt %d cachethis %u \n", __func__, | ||
1126 | resp->opcnt, resp->cstate.slot->sl_cache_entry.ce_cachethis); | ||
1127 | |||
1128 | /* Encode the replayed sequence operation */ | ||
1129 | op = &args->ops[resp->opcnt - 1]; | ||
1130 | nfsd4_encode_operation(resp, op); | ||
1131 | |||
1132 | /* Return nfserr_retry_uncached_rep in next operation. */ | ||
1133 | if (args->opcnt > 1 && slot->sl_cache_entry.ce_cachethis == 0) { | ||
1134 | op = &args->ops[resp->opcnt++]; | ||
1135 | op->status = nfserr_retry_uncached_rep; | ||
1136 | nfsd4_encode_operation(resp, op); | ||
1137 | } | ||
1138 | return op->status; | ||
1139 | } | ||
1140 | |||
1141 | /* | ||
1112 | * Keep the first page of the replay. Copy the NFSv4.1 data from the first | 1142 | * Keep the first page of the replay. Copy the NFSv4.1 data from the first |
1113 | * cached page. Replace any futher replay pages from the cache. | 1143 | * cached page. Replace any futher replay pages from the cache. |
1114 | */ | 1144 | */ |
@@ -1131,10 +1161,12 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, | |||
1131 | * session inactivity timer fires and a solo sequence operation | 1161 | * session inactivity timer fires and a solo sequence operation |
1132 | * is sent (lease renewal). | 1162 | * is sent (lease renewal). |
1133 | */ | 1163 | */ |
1134 | if (seq && nfsd4_not_cached(resp)) { | 1164 | seq->maxslots = resp->cstate.session->se_fchannel.maxreqs; |
1135 | seq->maxslots = resp->cstate.session->se_fchannel.maxreqs; | 1165 | |
1136 | return nfs_ok; | 1166 | /* Either returns 0 or nfserr_retry_uncached */ |
1137 | } | 1167 | status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp); |
1168 | if (status == nfserr_retry_uncached_rep) | ||
1169 | return status; | ||
1138 | 1170 | ||
1139 | if (!nfsd41_copy_replay_data(resp, entry)) { | 1171 | if (!nfsd41_copy_replay_data(resp, entry)) { |
1140 | /* | 1172 | /* |