Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c741d4f authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker
Browse files

SUNRPC: Add a helper function xdr_stream_decode_string_dup()



Create a helper function that decodes a xdr string object, allocates a memory
buffer and then store it as a NUL terminated string.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Reviewed-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 1bbe60ff
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -242,6 +242,8 @@ 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);

ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
		size_t maxlen, gfp_t gfp_flags);
/**
 * xdr_align_size - Calculate padded size of an object
 * @n: Size of an object being XDR encoded (in bytes)
+34 −0
Original line number Diff line number Diff line
@@ -1518,3 +1518,37 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
}
EXPORT_SYMBOL_GPL(xdr_process_buf);

/**
 * xdr_stream_decode_string_dup - Decode and duplicate variable length string
 * @xdr: pointer to xdr_stream
 * @str: location to store pointer to string
 * @maxlen: maximum acceptable string length
 * @gfp_flags: GFP mask to use
 *
 * Return values:
 *   On success, returns length of NUL-terminated string stored in *@ptr
 *   %-EBADMSG on XDR buffer overflow
 *   %-EMSGSIZE if the size of the string would exceed @maxlen
 *   %-ENOMEM on memory allocation failure
 */
ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
		size_t maxlen, gfp_t gfp_flags)
{
	void *p;
	ssize_t ret;

	ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
	if (ret > 0) {
		char *s = kmalloc(ret + 1, gfp_flags);
		if (s != NULL) {
			memcpy(s, p, ret);
			s[ret] = '\0';
			*str = s;
			return strlen(s);
		}
		ret = -ENOMEM;
	}
	*str = NULL;
	return ret;
}
EXPORT_SYMBOL_GPL(xdr_stream_decode_string_dup);