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 | |
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')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 33 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 40 |
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[]; | |||
984 | static const char *nfsd4_op_name(unsigned opnum); | 984 | static 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 | */ | ||
991 | static __be32 | ||
992 | nfsd4_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 | */ | ||
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 | /* |