Skip to content

Commit 7c4cd5f

Browse files
amschuma-ntapTrond Myklebust
authored andcommitted
SUNRPC: Add a function for directly setting the xdr page len
We need to do this step during READ_PLUS decoding so that we know pages are the right length and any extra data has been preserved in the tail. Signed-off-by: Anna Schumaker <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent 4f5f3b6 commit 7c4cd5f

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

include/linux/sunrpc/xdr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
258258
extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
259259
extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
260260
extern int xdr_process_buf(const struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data);
261+
extern void xdr_set_pagelen(struct xdr_stream *, unsigned int len);
261262
extern unsigned int xdr_align_data(struct xdr_stream *, unsigned int offset, unsigned int length);
262263
extern unsigned int xdr_expand_hole(struct xdr_stream *, unsigned int offset, unsigned int length);
263264
extern bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf,

net/sunrpc/xdr.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,36 @@ unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
15001500
}
15011501
EXPORT_SYMBOL_GPL(xdr_read_pages);
15021502

1503+
/**
1504+
* xdr_set_pagelen - Sets the length of the XDR pages
1505+
* @xdr: pointer to xdr_stream struct
1506+
* @len: new length of the XDR page data
1507+
*
1508+
* Either grows or shrinks the length of the xdr pages by setting pagelen to
1509+
* @len bytes. When shrinking, any extra data is moved into buf->tail, whereas
1510+
* when growing any data beyond the current pointer is moved into the tail.
1511+
*
1512+
* Returns True if the operation was successful, and False otherwise.
1513+
*/
1514+
void xdr_set_pagelen(struct xdr_stream *xdr, unsigned int len)
1515+
{
1516+
struct xdr_buf *buf = xdr->buf;
1517+
size_t remaining = xdr_stream_remaining(xdr);
1518+
size_t base = 0;
1519+
1520+
if (len < buf->page_len) {
1521+
base = buf->page_len - len;
1522+
xdr_shrink_pagelen(buf, len);
1523+
} else {
1524+
xdr_buf_head_shift_right(buf, xdr_stream_pos(xdr),
1525+
buf->page_len, remaining);
1526+
if (len > buf->page_len)
1527+
xdr_buf_try_expand(buf, len - buf->page_len);
1528+
}
1529+
xdr_set_tail_base(xdr, base, remaining);
1530+
}
1531+
EXPORT_SYMBOL_GPL(xdr_set_pagelen);
1532+
15031533
unsigned int xdr_align_data(struct xdr_stream *xdr, unsigned int offset,
15041534
unsigned int length)
15051535
{

0 commit comments

Comments
 (0)