aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2014-03-21 17:57:57 -0400
committerJ. Bruce Fields <bfields@redhat.com>2014-05-30 17:31:55 -0400
commitf5236013a21c118e9d317e90c7a152dfe51fab93 (patch)
treef2fcabe7395531380db28365ac2df0f92480fbcd /fs/nfsd
parent2825a7f90753012babe7ee292f4a1eadd3706f92 (diff)
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: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c28
-rw-r--r--fs/nfsd/nfs4xdr.c2
-rw-r--r--fs/nfsd/xdr4.h2
3 files changed, 16 insertions, 16 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b06f9a00ff8d..8e22ea485f99 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1560,6 +1560,7 @@ out_err:
1560void 1560void
1561nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) 1561nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
1562{ 1562{
1563 struct xdr_buf *buf = resp->xdr.buf;
1563 struct nfsd4_slot *slot = resp->cstate.slot; 1564 struct nfsd4_slot *slot = resp->cstate.slot;
1564 unsigned int base; 1565 unsigned int base;
1565 1566
@@ -1573,11 +1574,9 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
1573 slot->sl_datalen = 0; 1574 slot->sl_datalen = 0;
1574 return; 1575 return;
1575 } 1576 }
1576 slot->sl_datalen = (char *)resp->xdr.p - (char *)resp->cstate.datap; 1577 base = resp->cstate.data_offset;
1577 base = (char *)resp->cstate.datap - 1578 slot->sl_datalen = buf->len - base;
1578 (char *)resp->xdr.buf->head[0].iov_base; 1579 if (read_bytes_from_xdr_buf(buf, base, slot->sl_data, slot->sl_datalen))
1579 if (read_bytes_from_xdr_buf(resp->xdr.buf, base, slot->sl_data,
1580 slot->sl_datalen))
1581 WARN("%s: sessions DRC could not cache compound\n", __func__); 1580 WARN("%s: sessions DRC could not cache compound\n", __func__);
1582 return; 1581 return;
1583} 1582}
@@ -1618,7 +1617,8 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1618 struct nfsd4_sequence *seq) 1617 struct nfsd4_sequence *seq)
1619{ 1618{
1620 struct nfsd4_slot *slot = resp->cstate.slot; 1619 struct nfsd4_slot *slot = resp->cstate.slot;
1621 struct kvec *head = resp->xdr.iov; 1620 struct xdr_stream *xdr = &resp->xdr;
1621 __be32 *p;
1622 __be32 status; 1622 __be32 status;
1623 1623
1624 dprintk("--> %s slot %p\n", __func__, slot); 1624 dprintk("--> %s slot %p\n", __func__, slot);
@@ -1627,16 +1627,16 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1627 if (status) 1627 if (status)
1628 return status; 1628 return status;
1629 1629
1630 /* The sequence operation has been encoded, cstate->datap set. */ 1630 p = xdr_reserve_space(xdr, slot->sl_datalen);
1631 memcpy(resp->cstate.datap, slot->sl_data, slot->sl_datalen); 1631 if (!p) {
1632 WARN_ON_ONCE(1);
1633 return nfserr_serverfault;
1634 }
1635 xdr_encode_opaque_fixed(p, slot->sl_data, slot->sl_datalen);
1636 xdr_commit_encode(xdr);
1632 1637
1633 resp->opcnt = slot->sl_opcnt; 1638 resp->opcnt = slot->sl_opcnt;
1634 resp->xdr.p = resp->cstate.datap + XDR_QUADLEN(slot->sl_datalen); 1639 return slot->sl_status;
1635 head->iov_len = (void *)resp->xdr.p - head->iov_base;
1636 resp->xdr.buf->len = head->iov_len;
1637 status = slot->sl_status;
1638
1639 return status;
1640} 1640}
1641 1641
1642/* 1642/*
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index d3a576dbd99b..a90a1e86614a 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3659,7 +3659,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
3659 WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */ 3659 WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */
3660 WRITE32(seq->status_flags); 3660 WRITE32(seq->status_flags);
3661 3661
3662 resp->cstate.datap = p; /* DRC cache data pointer */ 3662 resp->cstate.data_offset = xdr->buf->len; /* DRC cache data pointer */
3663 return 0; 3663 return 0;
3664} 3664}
3665 3665
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index ea5ad5db655b..ee9ffdc8a0cb 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -58,7 +58,7 @@ struct nfsd4_compound_state {
58 /* For sessions DRC */ 58 /* For sessions DRC */
59 struct nfsd4_session *session; 59 struct nfsd4_session *session;
60 struct nfsd4_slot *slot; 60 struct nfsd4_slot *slot;
61 __be32 *datap; 61 int data_offset;
62 size_t iovlen; 62 size_t iovlen;
63 u32 minorversion; 63 u32 minorversion;
64 __be32 status; 64 __be32 status;