Commit abfabf8c authored by Andy Adamson's avatar Andy Adamson Committed by J. Bruce Fields
Browse files

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: default avatarAndy Adamson <andros@netapp.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent c8647947
Loading
Loading
Loading
Loading
+1 −32
Original line number Diff line number Diff line
@@ -983,34 +983,6 @@ static struct nfsd4_operation nfsd4_ops[];

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.
 *
@@ -1123,9 +1095,6 @@ encode_op:
		/* Only from SEQUENCE */
		if (resp->cstate.status == nfserr_replay_cache) {
			dprintk("%s NFS4.1 replay from cache\n", __func__);
			if (nfsd4_not_cached(resp))
				status = nfsd4_enc_sequence_replay(args, resp);
			else
			status = op->status;
			goto out;
		}
+36 −4
Original line number Diff line number Diff line
@@ -1108,6 +1108,36 @@ nfsd41_copy_replay_data(struct nfsd4_compoundres *resp,
	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
 * cached page.  Replace any futher replay pages from the cache.
@@ -1131,10 +1161,12 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
	 * session inactivity timer fires and a solo sequence operation
	 * is sent (lease renewal).
	 */
	if (seq && nfsd4_not_cached(resp)) {
	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)) {
		/*