Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5236013 authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

nfsd4: convert 4.1 replay encoding



Limits on maxresp_sz mean that we only ever need to replay rpc's that
are contained entirely in the head.

The one exception is very small zero-copy reads.  That's an odd corner
case as clients wouldn't normally ask those to be cached.

in any case, this seems a little more robust.

Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 2825a7f9
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -1560,6 +1560,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_r
void
nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
{
	struct xdr_buf *buf = resp->xdr.buf;
	struct nfsd4_slot *slot = resp->cstate.slot;
	unsigned int base;

@@ -1573,11 +1574,9 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
		slot->sl_datalen = 0;
		return;
	}
	slot->sl_datalen = (char *)resp->xdr.p - (char *)resp->cstate.datap;
	base = (char *)resp->cstate.datap -
					(char *)resp->xdr.buf->head[0].iov_base;
	if (read_bytes_from_xdr_buf(resp->xdr.buf, base, slot->sl_data,
				    slot->sl_datalen))
	base = resp->cstate.data_offset;
	slot->sl_datalen = buf->len - base;
	if (read_bytes_from_xdr_buf(buf, base, slot->sl_data, slot->sl_datalen))
		WARN("%s: sessions DRC could not cache compound\n", __func__);
	return;
}
@@ -1618,7 +1617,8 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
			 struct nfsd4_sequence *seq)
{
	struct nfsd4_slot *slot = resp->cstate.slot;
	struct kvec *head = resp->xdr.iov;
	struct xdr_stream *xdr = &resp->xdr;
	__be32 *p;
	__be32 status;

	dprintk("--> %s slot %p\n", __func__, slot);
@@ -1627,16 +1627,16 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
	if (status)
		return status;

	/* The sequence operation has been encoded, cstate->datap set. */
	memcpy(resp->cstate.datap, slot->sl_data, slot->sl_datalen);
	p = xdr_reserve_space(xdr, slot->sl_datalen);
	if (!p) {
		WARN_ON_ONCE(1);
		return nfserr_serverfault;
	}
	xdr_encode_opaque_fixed(p, slot->sl_data, slot->sl_datalen);
	xdr_commit_encode(xdr);

	resp->opcnt = slot->sl_opcnt;
	resp->xdr.p = resp->cstate.datap + XDR_QUADLEN(slot->sl_datalen);
	head->iov_len = (void *)resp->xdr.p - head->iov_base;
	resp->xdr.buf->len = head->iov_len;
	status = slot->sl_status;

	return status;
	return slot->sl_status;
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -3659,7 +3659,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
	WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */
	WRITE32(seq->status_flags);

	resp->cstate.datap = p; /* DRC cache data pointer */
	resp->cstate.data_offset = xdr->buf->len; /* DRC cache data pointer */
	return 0;
}

+1 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ struct nfsd4_compound_state {
	/* For sessions DRC */
	struct nfsd4_session	*session;
	struct nfsd4_slot	*slot;
	__be32			*datap;
	int			data_offset;
	size_t			iovlen;
	u32			minorversion;
	__be32			status;