diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-09 09:34:21 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-09 09:34:21 -0400 |
commit | 8b23ea7bedb8b45a5bb56745fa3ff11018acf04e (patch) | |
tree | b312b3d0d9e27704792fd7dfcd9bc041b1122bef | |
parent | 51d8fa6a109589d522c18a8e9bf3fb167a91b1bc (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.h | 1 | ||||
-rw-r--r-- | net/sunrpc/xdr.c | 28 |
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, | |||
194 | extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p); | 194 | extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p); |
195 | extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); | 195 | extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); |
196 | extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); | 196 | extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); |
197 | extern 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 | */ |
574 | void xdr_read_pages(struct xdr_stream *xdr, unsigned int len) | 573 | void 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 | } |
607 | EXPORT_SYMBOL(xdr_read_pages); | 606 | EXPORT_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 | */ | ||
618 | void 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 | } | ||
631 | EXPORT_SYMBOL(xdr_enter_page); | ||
632 | |||
609 | static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0}; | 633 | static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0}; |
610 | 634 | ||
611 | void | 635 | void |