aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2009-07-23 19:02:18 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-07-28 16:12:34 -0400
commitabfabf8cafa60e7876a7193fb344f739f690071d (patch)
tree1cc9faa1a82d7ac7ef08bdb8af7acb8a30c9903d /fs/nfsd
parentc8647947f8c13ee2647505debae284ab1c859e65 (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')
-rw-r--r--fs/nfsd/nfs4proc.c33
-rw-r--r--fs/nfsd/nfs4state.c40
2 files changed, 37 insertions, 36 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 23cd73869a21..6fde431df9ee 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -984,34 +984,6 @@ static struct nfsd4_operation nfsd4_ops[];
984static const char *nfsd4_op_name(unsigned opnum); 984static const char *nfsd4_op_name(unsigned opnum);
985 985
986/* 986/*
987 * This is a replay of a compound for which no cache entry pages
988 * were used. Encode the sequence operation, and if cachethis is FALSE
989 * encode the uncache rep error on the next operation.
990 */
991static __be32
992nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
993 struct nfsd4_compoundres *resp)
994{
995 struct nfsd4_op *op;
996
997 dprintk("--> %s resp->opcnt %d ce_cachethis %u \n", __func__,
998 resp->opcnt, resp->cstate.slot->sl_cache_entry.ce_cachethis);
999
1000 /* Encode the replayed sequence operation */
1001 BUG_ON(resp->opcnt != 1);
1002 op = &args->ops[resp->opcnt - 1];
1003 nfsd4_encode_operation(resp, op);
1004
1005 /*return nfserr_retry_uncached_rep in next operation. */
1006 if (resp->cstate.slot->sl_cache_entry.ce_cachethis == 0) {
1007 op = &args->ops[resp->opcnt++];
1008 op->status = nfserr_retry_uncached_rep;
1009 nfsd4_encode_operation(resp, op);
1010 }
1011 return op->status;
1012}
1013
1014/*
1015 * Enforce NFSv4.1 COMPOUND ordering rules. 987 * Enforce NFSv4.1 COMPOUND ordering rules.
1016 * 988 *
1017 * TODO: 989 * TODO:
@@ -1123,10 +1095,7 @@ encode_op:
1123 /* Only from SEQUENCE */ 1095 /* Only from SEQUENCE */
1124 if (resp->cstate.status == nfserr_replay_cache) { 1096 if (resp->cstate.status == nfserr_replay_cache) {
1125 dprintk("%s NFS4.1 replay from cache\n", __func__); 1097 dprintk("%s NFS4.1 replay from cache\n", __func__);
1126 if (nfsd4_not_cached(resp)) 1098 status = op->status;
1127 status = nfsd4_enc_sequence_replay(args, resp);
1128 else
1129 status = op->status;
1130 goto out; 1099 goto out;
1131 } 1100 }
1132 if (op->status == nfserr_replay_me) { 1101 if (op->status == nfserr_replay_me) {
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 */
1118static __be32
1119nfsd4_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 /*