aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-09 09:34:21 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-09 09:34:21 -0400
commit8b23ea7bedb8b45a5bb56745fa3ff11018acf04e (patch)
treeb312b3d0d9e27704792fd7dfcd9bc041b1122bef
parent51d8fa6a109589d522c18a8e9bf3fb167a91b1bc (diff)
RPC: Allow struc xdr_stream to read the page section of an xdr_buf
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--include/linux/sunrpc/xdr.h1
-rw-r--r--net/sunrpc/xdr.c28
2 files changed, 27 insertions, 2 deletions
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 84c35d42d250..e6d3d349506c 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -194,6 +194,7 @@ extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
194extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p); 194extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
195extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); 195extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
196extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); 196extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
197extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
197 198
198#endif /* __KERNEL__ */ 199#endif /* __KERNEL__ */
199 200
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index ca4bfa57e116..49174f0d0a3e 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -568,8 +568,7 @@ EXPORT_SYMBOL(xdr_inline_decode);
568 * 568 *
569 * Moves data beyond the current pointer position from the XDR head[] buffer 569 * Moves data beyond the current pointer position from the XDR head[] buffer
570 * into the page list. Any data that lies beyond current position + "len" 570 * into the page list. Any data that lies beyond current position + "len"
571 * bytes is moved into the XDR tail[]. The current pointer is then 571 * bytes is moved into the XDR tail[].
572 * repositioned at the beginning of the XDR tail.
573 */ 572 */
574void xdr_read_pages(struct xdr_stream *xdr, unsigned int len) 573void xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
575{ 574{
@@ -606,6 +605,31 @@ void xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
606} 605}
607EXPORT_SYMBOL(xdr_read_pages); 606EXPORT_SYMBOL(xdr_read_pages);
608 607
608/**
609 * xdr_enter_page - decode data from the XDR page
610 * @xdr: pointer to xdr_stream struct
611 * @len: number of bytes of page data
612 *
613 * Moves data beyond the current pointer position from the XDR head[] buffer
614 * into the page list. Any data that lies beyond current position + "len"
615 * bytes is moved into the XDR tail[]. The current pointer is then
616 * repositioned at the beginning of the first XDR page.
617 */
618void xdr_enter_page(struct xdr_stream *xdr, unsigned int len)
619{
620 char * kaddr = page_address(xdr->buf->pages[0]);
621 xdr_read_pages(xdr, len);
622 /*
623 * Position current pointer at beginning of tail, and
624 * set remaining message length.
625 */
626 if (len > PAGE_CACHE_SIZE - xdr->buf->page_base)
627 len = PAGE_CACHE_SIZE - xdr->buf->page_base;
628 xdr->p = (uint32_t *)(kaddr + xdr->buf->page_base);
629 xdr->end = (uint32_t *)((char *)xdr->p + len);
630}
631EXPORT_SYMBOL(xdr_enter_page);
632
609static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0}; 633static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0};
610 634
611void 635void