|
|
@@ -1518,3 +1518,37 @@ out:
|
|
|
}
|
|
|
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);
|