diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2016-06-02 08:23:32 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-07-27 20:55:36 -0400 |
commit | 22748f9d617b8cd0a915c3a4c656c7232645b3b5 (patch) | |
tree | ac7e69c40236ad60fe923bd97391bc151df23c12 /include/linux/ceph | |
parent | 281dbe5db81c6137def9757e07a7aea14b1ed86e (diff) |
libceph: add start en/decoding block helpers
Add ceph_start_encoding() and ceph_start_decoding(), the equivalent of
ENCODE_START and DECODE_START in the userspace ceph code.
This is based on a patch from Mike Christie <michaelc@cs.wisc.edu>.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'include/linux/ceph')
-rw-r--r-- | include/linux/ceph/decode.h | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/include/linux/ceph/decode.h b/include/linux/ceph/decode.h index e83f3c81ef43..f990f2cc907a 100644 --- a/include/linux/ceph/decode.h +++ b/include/linux/ceph/decode.h | |||
@@ -218,6 +218,60 @@ static inline void ceph_encode_string(void **p, void *end, | |||
218 | *p += len; | 218 | *p += len; |
219 | } | 219 | } |
220 | 220 | ||
221 | /* | ||
222 | * version and length starting block encoders/decoders | ||
223 | */ | ||
224 | |||
225 | /* current code version (u8) + compat code version (u8) + len of struct (u32) */ | ||
226 | #define CEPH_ENCODING_START_BLK_LEN 6 | ||
227 | |||
228 | /** | ||
229 | * ceph_start_encoding - start encoding block | ||
230 | * @struct_v: current (code) version of the encoding | ||
231 | * @struct_compat: oldest code version that can decode it | ||
232 | * @struct_len: length of struct encoding | ||
233 | */ | ||
234 | static inline void ceph_start_encoding(void **p, u8 struct_v, u8 struct_compat, | ||
235 | u32 struct_len) | ||
236 | { | ||
237 | ceph_encode_8(p, struct_v); | ||
238 | ceph_encode_8(p, struct_compat); | ||
239 | ceph_encode_32(p, struct_len); | ||
240 | } | ||
241 | |||
242 | /** | ||
243 | * ceph_start_decoding - start decoding block | ||
244 | * @v: current version of the encoding that the code supports | ||
245 | * @name: name of the struct (free-form) | ||
246 | * @struct_v: out param for the encoding version | ||
247 | * @struct_len: out param for the length of struct encoding | ||
248 | * | ||
249 | * Validates the length of struct encoding, so unsafe ceph_decode_* | ||
250 | * variants can be used for decoding. | ||
251 | */ | ||
252 | static inline int ceph_start_decoding(void **p, void *end, u8 v, | ||
253 | const char *name, u8 *struct_v, | ||
254 | u32 *struct_len) | ||
255 | { | ||
256 | u8 struct_compat; | ||
257 | |||
258 | ceph_decode_need(p, end, CEPH_ENCODING_START_BLK_LEN, bad); | ||
259 | *struct_v = ceph_decode_8(p); | ||
260 | struct_compat = ceph_decode_8(p); | ||
261 | if (v < struct_compat) { | ||
262 | pr_warn("got struct_v %d struct_compat %d > %d of %s\n", | ||
263 | *struct_v, struct_compat, v, name); | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | *struct_len = ceph_decode_32(p); | ||
268 | ceph_decode_need(p, end, *struct_len, bad); | ||
269 | return 0; | ||
270 | |||
271 | bad: | ||
272 | return -ERANGE; | ||
273 | } | ||
274 | |||
221 | #define ceph_encode_need(p, end, n, bad) \ | 275 | #define ceph_encode_need(p, end, n, bad) \ |
222 | do { \ | 276 | do { \ |
223 | if (!likely(ceph_has_room(p, end, n))) \ | 277 | if (!likely(ceph_has_room(p, end, n))) \ |