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

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
...@@ -1560,6 +1560,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_r ...@@ -1560,6 +1560,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_r
void void
nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
{ {
struct xdr_buf *buf = resp->xdr.buf;
struct nfsd4_slot *slot = resp->cstate.slot; struct nfsd4_slot *slot = resp->cstate.slot;
unsigned int base; unsigned int base;
...@@ -1573,11 +1574,9 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) ...@@ -1573,11 +1574,9 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
slot->sl_datalen = 0; slot->sl_datalen = 0;
return; return;
} }
slot->sl_datalen = (char *)resp->xdr.p - (char *)resp->cstate.datap; base = resp->cstate.data_offset;
base = (char *)resp->cstate.datap - slot->sl_datalen = buf->len - base;
(char *)resp->xdr.buf->head[0].iov_base; if (read_bytes_from_xdr_buf(buf, base, slot->sl_data, slot->sl_datalen))
if (read_bytes_from_xdr_buf(resp->xdr.buf, base, slot->sl_data,
slot->sl_datalen))
WARN("%s: sessions DRC could not cache compound\n", __func__); WARN("%s: sessions DRC could not cache compound\n", __func__);
return; return;
} }
...@@ -1618,7 +1617,8 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, ...@@ -1618,7 +1617,8 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
struct nfsd4_sequence *seq) struct nfsd4_sequence *seq)
{ {
struct nfsd4_slot *slot = resp->cstate.slot; struct nfsd4_slot *slot = resp->cstate.slot;
struct kvec *head = resp->xdr.iov; struct xdr_stream *xdr = &resp->xdr;
__be32 *p;
__be32 status; __be32 status;
dprintk("--> %s slot %p\n", __func__, slot); dprintk("--> %s slot %p\n", __func__, slot);
...@@ -1627,16 +1627,16 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, ...@@ -1627,16 +1627,16 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
if (status) if (status)
return status; return status;
/* The sequence operation has been encoded, cstate->datap set. */ p = xdr_reserve_space(xdr, slot->sl_datalen);
memcpy(resp->cstate.datap, slot->sl_data, 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->opcnt = slot->sl_opcnt;
resp->xdr.p = resp->cstate.datap + XDR_QUADLEN(slot->sl_datalen); return slot->sl_status;
head->iov_len = (void *)resp->xdr.p - head->iov_base;
resp->xdr.buf->len = head->iov_len;
status = slot->sl_status;
return status;
} }
/* /*
......
...@@ -3659,7 +3659,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr, ...@@ -3659,7 +3659,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */ WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */
WRITE32(seq->status_flags); 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; return 0;
} }
......
...@@ -58,7 +58,7 @@ struct nfsd4_compound_state { ...@@ -58,7 +58,7 @@ struct nfsd4_compound_state {
/* For sessions DRC */ /* For sessions DRC */
struct nfsd4_session *session; struct nfsd4_session *session;
struct nfsd4_slot *slot; struct nfsd4_slot *slot;
__be32 *datap; int data_offset;
size_t iovlen; size_t iovlen;
u32 minorversion; u32 minorversion;
__be32 status; __be32 status;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment