@@ -229,6 +229,7 @@ extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data);
+extern uint64_t xdr_read_hole(struct xdr_stream *, uint64_t);
#endif /* __KERNEL__ */
@@ -220,6 +220,38 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base,
}
/**
+ * _zero_data_pages
+ * @pages: array of pages
+ * @pgbase: beginning page vector address
+ * @len: length
+ */
+static void
+_zero_data_pages(struct page **pages, size_t pgbase, size_t len)
+{
+ struct page **page;
+ char *vpage;
+ size_t zero;
+
+ page = pages + (pgbase >> PAGE_CACHE_SHIFT);
+ pgbase &= ~PAGE_CACHE_MASK;
+
+ do {
+ zero = len;
+ if (pgbase + zero > PAGE_SIZE)
+ zero = PAGE_SIZE - pgbase;
+
+ vpage = kmap_atomic(*page);
+ memset(vpage + pgbase, 0, zero);
+ flush_dcache_page(*page);
+ kunmap_atomic(vpage);
+
+ page++;
+ pgbase = 0;
+
+ } while ((len -= zero) != 0);
+}
+
+/**
* _copy_to_pages
* @pages: array of pages
* @pgbase: page vector address of destination
@@ -970,6 +1002,19 @@ unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
}
EXPORT_SYMBOL_GPL(xdr_read_pages);
+uint64_t xdr_read_hole(struct xdr_stream *xdr, uint64_t length)
+{
+ struct xdr_buf *buf = xdr->buf;
+
+ if (length > buf->page_len)
+ length = buf->page_len;
+
+ xdr_align_pages(xdr, length);
+ _zero_data_pages(buf->pages, buf->page_base, length);
+ return length;
+}
+EXPORT_SYMBOL_GPL(xdr_read_hole);
+
/**
* xdr_enter_page - decode data from the XDR page
* @xdr: pointer to xdr_stream struct
This patch adds the ability to "read a hole" into a set of XDR data pages attached to a specific request. Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> --- include/linux/sunrpc/xdr.h | 1 + net/sunrpc/xdr.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+)