SUNRPC: Add helpers for decoding opaque and string types
authorTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 20 Mar 2018 21:03:05 +0000 (17:03 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Tue, 10 Apr 2018 20:06:22 +0000 (16:06 -0400)
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
include/linux/sunrpc/xdr.h
net/sunrpc/xdr.c

index d950223c64b1c533ebc624ff3337cb40000bad81..7e609de34d8579eaf9755a794c4aecbd04ee1c1a 100644 (file)
@@ -253,6 +253,12 @@ xdr_stream_remaining(const struct xdr_stream *xdr)
        return xdr->nwords << 2;
 }
 
+ssize_t xdr_stream_decode_opaque(struct xdr_stream *xdr, void *ptr,
+               size_t size);
+ssize_t xdr_stream_decode_opaque_dup(struct xdr_stream *xdr, void **ptr,
+               size_t maxlen, gfp_t gfp_flags);
+ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str,
+               size_t size);
 ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
                size_t maxlen, gfp_t gfp_flags);
 /**
index e34f4ee7f2b6cecdf404daab0d3aab363d94ba01..30afbd236656672e0e9e87d6bfc07a76b742bf4d 100644 (file)
@@ -1518,6 +1518,88 @@ out:
 }
 EXPORT_SYMBOL_GPL(xdr_process_buf);
 
+/**
+ * xdr_stream_decode_opaque - Decode variable length opaque
+ * @xdr: pointer to xdr_stream
+ * @ptr: location to store opaque data
+ * @size: size of storage buffer @ptr
+ *
+ * Return values:
+ *   On success, returns size of object stored in *@ptr
+ *   %-EBADMSG on XDR buffer overflow
+ *   %-EMSGSIZE on overflow of storage buffer @ptr
+ */
+ssize_t xdr_stream_decode_opaque(struct xdr_stream *xdr, void *ptr, size_t size)
+{
+       ssize_t ret;
+       void *p;
+
+       ret = xdr_stream_decode_opaque_inline(xdr, &p, size);
+       if (ret <= 0)
+               return ret;
+       memcpy(ptr, p, ret);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(xdr_stream_decode_opaque);
+
+/**
+ * xdr_stream_decode_opaque_dup - Decode and duplicate variable length opaque
+ * @xdr: pointer to xdr_stream
+ * @ptr: location to store pointer to opaque data
+ * @maxlen: maximum acceptable object size
+ * @gfp_flags: GFP mask to use
+ *
+ * Return values:
+ *   On success, returns size of object stored in *@ptr
+ *   %-EBADMSG on XDR buffer overflow
+ *   %-EMSGSIZE if the size of the object would exceed @maxlen
+ *   %-ENOMEM on memory allocation failure
+ */
+ssize_t xdr_stream_decode_opaque_dup(struct xdr_stream *xdr, void **ptr,
+               size_t maxlen, gfp_t gfp_flags)
+{
+       ssize_t ret;
+       void *p;
+
+       ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
+       if (ret > 0) {
+               *ptr = kmemdup(p, ret, gfp_flags);
+               if (*ptr != NULL)
+                       return ret;
+               ret = -ENOMEM;
+       }
+       *ptr = NULL;
+       return ret;
+}
+EXPORT_SYMBOL_GPL(xdr_stream_decode_opaque_dup);
+
+/**
+ * xdr_stream_decode_string - Decode variable length string
+ * @xdr: pointer to xdr_stream
+ * @str: location to store string
+ * @size: size of storage buffer @str
+ *
+ * Return values:
+ *   On success, returns length of NUL-terminated string stored in *@str
+ *   %-EBADMSG on XDR buffer overflow
+ *   %-EMSGSIZE on overflow of storage buffer @str
+ */
+ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str, size_t size)
+{
+       ssize_t ret;
+       void *p;
+
+       ret = xdr_stream_decode_opaque_inline(xdr, &p, size);
+       if (ret > 0) {
+               memcpy(str, p, ret);
+               str[ret] = '\0';
+               return strlen(str);
+       }
+       *str = '\0';
+       return ret;
+}
+EXPORT_SYMBOL_GPL(xdr_stream_decode_string);
+
 /**
  * xdr_stream_decode_string_dup - Decode and duplicate variable length string
  * @xdr: pointer to xdr_stream