diff options
author | J. Bruce Fields <bfields@redhat.com> | 2014-03-21 17:57:57 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-05-30 17:31:55 -0400 |
commit | f5236013a21c118e9d317e90c7a152dfe51fab93 (patch) | |
tree | f2fcabe7395531380db28365ac2df0f92480fbcd /fs/nfsd | |
parent | 2825a7f90753012babe7ee292f4a1eadd3706f92 (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.c | 28 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 2 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 2 |
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: | |||
1560 | void | 1560 | void |
1561 | nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) | 1561 | nfsd4_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; |