aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/ceph
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-07-11 09:24:45 -0400
committerSage Weil <sage@inktank.com>2012-07-30 12:29:57 -0400
commitf8c36c58accd5c53a472b5c289910565b3df9f9d (patch)
tree905ff1a9df30c0200732af71b806c39145dcd641 /include/linux/ceph
parentad4f232f28e8059fa1de51f3127d8a6a2759ef16 (diff)
libceph: define ceph_extract_encoded_string()
This adds a new utility routine which will return a dynamically- allocated buffer containing a string that has been decoded from ceph over-the-wire format. It also returns the length of the string if the address of a size variable is supplied to receive it. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'include/linux/ceph')
-rw-r--r--include/linux/ceph/decode.h47
1 files changed, 47 insertions, 0 deletions
diff --git a/include/linux/ceph/decode.h b/include/linux/ceph/decode.h
index bcbd66c84890..4bbf2db45f46 100644
--- a/include/linux/ceph/decode.h
+++ b/include/linux/ceph/decode.h
@@ -1,6 +1,7 @@
1#ifndef __CEPH_DECODE_H 1#ifndef __CEPH_DECODE_H
2#define __CEPH_DECODE_H 2#define __CEPH_DECODE_H
3 3
4#include <linux/err.h>
4#include <linux/bug.h> 5#include <linux/bug.h>
5#include <linux/time.h> 6#include <linux/time.h>
6#include <asm/unaligned.h> 7#include <asm/unaligned.h>
@@ -85,6 +86,52 @@ static inline int ceph_has_room(void **p, void *end, size_t n)
85 } while (0) 86 } while (0)
86 87
87/* 88/*
89 * Allocate a buffer big enough to hold the wire-encoded string, and
90 * decode the string into it. The resulting string will always be
91 * terminated with '\0'. If successful, *p will be advanced
92 * past the decoded data. Also, if lenp is not a null pointer, the
93 * length (not including the terminating '\0') will be recorded in
94 * *lenp. Note that a zero-length string is a valid return value.
95 *
96 * Returns a pointer to the newly-allocated string buffer, or a
97 * pointer-coded errno if an error occurs. Neither *p nor *lenp
98 * will have been updated if an error is returned.
99 *
100 * There are two possible failures:
101 * - converting the string would require accessing memory at or
102 * beyond the "end" pointer provided (-E
103 * - memory could not be allocated for the result
104 */
105static inline char *ceph_extract_encoded_string(void **p, void *end,
106 size_t *lenp, gfp_t gfp)
107{
108 u32 len;
109 void *sp = *p;
110 char *buf;
111
112 ceph_decode_32_safe(&sp, end, len, bad);
113 if (!ceph_has_room(&sp, end, len))
114 goto bad;
115
116 buf = kmalloc(len + 1, gfp);
117 if (!buf)
118 return ERR_PTR(-ENOMEM);
119
120 if (len)
121 memcpy(buf, sp, len);
122 buf[len] = '\0';
123
124 *p = (char *) *p + sizeof (u32) + len;
125 if (lenp)
126 *lenp = (size_t) len;
127
128 return buf;
129
130bad:
131 return ERR_PTR(-ERANGE);
132}
133
134/*
88 * struct ceph_timespec <-> struct timespec 135 * struct ceph_timespec <-> struct timespec
89 */ 136 */
90static inline void ceph_decode_timespec(struct timespec *ts, 137static inline void ceph_decode_timespec(struct timespec *ts,