提交 abfabf8c 编写于 作者: A Andy Adamson 提交者: J. Bruce Fields

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: NAndy Adamson <andros@netapp.com>
Signed-off-by: NJ. Bruce Fields <bfields@citi.umich.edu>
上级 c8647947
...@@ -983,34 +983,6 @@ static struct nfsd4_operation nfsd4_ops[]; ...@@ -983,34 +983,6 @@ static struct nfsd4_operation nfsd4_ops[];
static const char *nfsd4_op_name(unsigned opnum); static const char *nfsd4_op_name(unsigned opnum);
/*
* This is a replay of a compound for which no cache entry pages
* were used. Encode the sequence operation, and if cachethis is FALSE
* encode the uncache rep error on the next operation.
*/
static __be32
nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
struct nfsd4_compoundres *resp)
{
struct nfsd4_op *op;
dprintk("--> %s resp->opcnt %d ce_cachethis %u \n", __func__,
resp->opcnt, resp->cstate.slot->sl_cache_entry.ce_cachethis);
/* Encode the replayed sequence operation */
BUG_ON(resp->opcnt != 1);
op = &args->ops[resp->opcnt - 1];
nfsd4_encode_operation(resp, op);
/*return nfserr_retry_uncached_rep in next operation. */
if (resp->cstate.slot->sl_cache_entry.ce_cachethis == 0) {
op = &args->ops[resp->opcnt++];
op->status = nfserr_retry_uncached_rep;
nfsd4_encode_operation(resp, op);
}
return op->status;
}
/* /*
* Enforce NFSv4.1 COMPOUND ordering rules. * Enforce NFSv4.1 COMPOUND ordering rules.
* *
...@@ -1123,10 +1095,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, ...@@ -1123,10 +1095,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
/* Only from SEQUENCE */ /* Only from SEQUENCE */
if (resp->cstate.status == nfserr_replay_cache) { if (resp->cstate.status == nfserr_replay_cache) {
dprintk("%s NFS4.1 replay from cache\n", __func__); dprintk("%s NFS4.1 replay from cache\n", __func__);
if (nfsd4_not_cached(resp)) status = op->status;
status = nfsd4_enc_sequence_replay(args, resp);
else
status = op->status;
goto out; goto out;
} }
if (op->status == nfserr_replay_me) { if (op->status == nfserr_replay_me) {
......
...@@ -1108,6 +1108,36 @@ nfsd41_copy_replay_data(struct nfsd4_compoundres *resp, ...@@ -1108,6 +1108,36 @@ nfsd41_copy_replay_data(struct nfsd4_compoundres *resp,
return 1; return 1;
} }
/*
* Encode the replay sequence operation from the slot values.
* If cachethis is FALSE encode the uncached rep error on the next
* operation which sets resp->p and increments resp->opcnt for
* nfs4svc_encode_compoundres.
*
*/
static __be32
nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
struct nfsd4_compoundres *resp)
{
struct nfsd4_op *op;
struct nfsd4_slot *slot = resp->cstate.slot;
dprintk("--> %s resp->opcnt %d cachethis %u \n", __func__,
resp->opcnt, resp->cstate.slot->sl_cache_entry.ce_cachethis);
/* Encode the replayed sequence operation */
op = &args->ops[resp->opcnt - 1];
nfsd4_encode_operation(resp, op);
/* Return nfserr_retry_uncached_rep in next operation. */
if (args->opcnt > 1 && slot->sl_cache_entry.ce_cachethis == 0) {
op = &args->ops[resp->opcnt++];
op->status = nfserr_retry_uncached_rep;
nfsd4_encode_operation(resp, op);
}
return op->status;
}
/* /*
* Keep the first page of the replay. Copy the NFSv4.1 data from the first * Keep the first page of the replay. Copy the NFSv4.1 data from the first
* cached page. Replace any futher replay pages from the cache. * cached page. Replace any futher replay pages from the cache.
...@@ -1131,10 +1161,12 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, ...@@ -1131,10 +1161,12 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
* session inactivity timer fires and a solo sequence operation * session inactivity timer fires and a solo sequence operation
* is sent (lease renewal). * is sent (lease renewal).
*/ */
if (seq && nfsd4_not_cached(resp)) { seq->maxslots = resp->cstate.session->se_fchannel.maxreqs;
seq->maxslots = resp->cstate.session->se_fchannel.maxreqs;
return nfs_ok; /* Either returns 0 or nfserr_retry_uncached */
} status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp);
if (status == nfserr_retry_uncached_rep)
return status;
if (!nfsd41_copy_replay_data(resp, entry)) { if (!nfsd41_copy_replay_data(resp, entry)) {
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册