aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/xdr.h2
-rw-r--r--net/sunrpc/xdr.c34
2 files changed, 36 insertions, 0 deletions
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index dc7e51a769ac..054c8cde18f3 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -242,6 +242,8 @@ extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
242extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len); 242extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
243extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data); 243extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data);
244 244
245ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
246 size_t maxlen, gfp_t gfp_flags);
245/** 247/**
246 * xdr_align_size - Calculate padded size of an object 248 * xdr_align_size - Calculate padded size of an object
247 * @n: Size of an object being XDR encoded (in bytes) 249 * @n: Size of an object being XDR encoded (in bytes)
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 7f1071e103ca..1f7082144e01 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1518,3 +1518,37 @@ out:
1518} 1518}
1519EXPORT_SYMBOL_GPL(xdr_process_buf); 1519EXPORT_SYMBOL_GPL(xdr_process_buf);
1520 1520
1521/**
1522 * xdr_stream_decode_string_dup - Decode and duplicate variable length string
1523 * @xdr: pointer to xdr_stream
1524 * @str: location to store pointer to string
1525 * @maxlen: maximum acceptable string length
1526 * @gfp_flags: GFP mask to use
1527 *
1528 * Return values:
1529 * On success, returns length of NUL-terminated string stored in *@ptr
1530 * %-EBADMSG on XDR buffer overflow
1531 * %-EMSGSIZE if the size of the string would exceed @maxlen
1532 * %-ENOMEM on memory allocation failure
1533 */
1534ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
1535 size_t maxlen, gfp_t gfp_flags)
1536{
1537 void *p;
1538 ssize_t ret;
1539
1540 ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
1541 if (ret > 0) {
1542 char *s = kmalloc(ret + 1, gfp_flags);
1543 if (s != NULL) {
1544 memcpy(s, p, ret);
1545 s[ret] = '\0';
1546 *str = s;
1547 return strlen(s);
1548 }
1549 ret = -ENOMEM;
1550 }
1551 *str = NULL;
1552 return ret;
1553}
1554EXPORT_SYMBOL_GPL(xdr_stream_decode_string_dup);