summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Schumaker <Anna.Schumaker@Netapp.com>2022-07-21 14:21:33 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2022-07-23 15:38:29 -0400
commite1bd87608d4b6f87813f79b91e834de610f1049b (patch)
tree13357d2ca79492fd1b7caab7b38742a25ab1b323
parent7c4cd5f4d2dd4a028a46bfb696b0cd387caadf33 (diff)
SUNRPC: Add a function for zeroing out a portion of an xdr_stream
This will be used during READ_PLUS decoding for handling HOLE segments. Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
-rw-r--r--include/linux/sunrpc/xdr.h2
-rw-r--r--net/sunrpc/xdr.c23
2 files changed, 25 insertions, 0 deletions
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 8cd38a9994ca..f0ab06acab61 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -265,6 +265,8 @@ extern bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf
unsigned int len);
extern unsigned int xdr_stream_move_subsegment(struct xdr_stream *xdr, unsigned int offset,
unsigned int target, unsigned int length);
+extern unsigned int xdr_stream_zero(struct xdr_stream *xdr, unsigned int offset,
+ unsigned int length);
/**
* xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index e4ac700ca554..f09a7ab1a82b 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1770,6 +1770,29 @@ unsigned int xdr_stream_move_subsegment(struct xdr_stream *xdr, unsigned int off
EXPORT_SYMBOL_GPL(xdr_stream_move_subsegment);
/**
+ * xdr_stream_zero - zero out a portion of an xdr_stream
+ * @xdr: an xdr_stream to zero out
+ * @offset: the starting point in the stream
+ * @length: the number of bytes to zero
+ */
+unsigned int xdr_stream_zero(struct xdr_stream *xdr, unsigned int offset,
+ unsigned int length)
+{
+ struct xdr_buf buf;
+
+ if (xdr_buf_subsegment(xdr->buf, &buf, offset, length) < 0)
+ return 0;
+ if (buf.head[0].iov_len)
+ xdr_buf_iov_zero(buf.head, 0, buf.head[0].iov_len);
+ if (buf.page_len > 0)
+ xdr_buf_pages_zero(&buf, 0, buf.page_len);
+ if (buf.tail[0].iov_len)
+ xdr_buf_iov_zero(buf.tail, 0, buf.tail[0].iov_len);
+ return length;
+}
+EXPORT_SYMBOL_GPL(xdr_stream_zero);
+
+/**
* xdr_buf_trim - lop at most "len" bytes off the end of "buf"
* @buf: buf to be trimmed
* @len: number of bytes to reduce "buf" by