1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef __CEPH_DECODE_H
3*4882a593Smuzhiyun #define __CEPH_DECODE_H
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun #include <linux/err.h>
6*4882a593Smuzhiyun #include <linux/bug.h>
7*4882a593Smuzhiyun #include <linux/slab.h>
8*4882a593Smuzhiyun #include <linux/time.h>
9*4882a593Smuzhiyun #include <asm/unaligned.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/ceph/types.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun /*
14*4882a593Smuzhiyun * in all cases,
15*4882a593Smuzhiyun * void **p pointer to position pointer
16*4882a593Smuzhiyun * void *end pointer to end of buffer (last byte + 1)
17*4882a593Smuzhiyun */
18*4882a593Smuzhiyun
ceph_decode_64(void ** p)19*4882a593Smuzhiyun static inline u64 ceph_decode_64(void **p)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun u64 v = get_unaligned_le64(*p);
22*4882a593Smuzhiyun *p += sizeof(u64);
23*4882a593Smuzhiyun return v;
24*4882a593Smuzhiyun }
ceph_decode_32(void ** p)25*4882a593Smuzhiyun static inline u32 ceph_decode_32(void **p)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun u32 v = get_unaligned_le32(*p);
28*4882a593Smuzhiyun *p += sizeof(u32);
29*4882a593Smuzhiyun return v;
30*4882a593Smuzhiyun }
ceph_decode_16(void ** p)31*4882a593Smuzhiyun static inline u16 ceph_decode_16(void **p)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun u16 v = get_unaligned_le16(*p);
34*4882a593Smuzhiyun *p += sizeof(u16);
35*4882a593Smuzhiyun return v;
36*4882a593Smuzhiyun }
ceph_decode_8(void ** p)37*4882a593Smuzhiyun static inline u8 ceph_decode_8(void **p)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun u8 v = *(u8 *)*p;
40*4882a593Smuzhiyun (*p)++;
41*4882a593Smuzhiyun return v;
42*4882a593Smuzhiyun }
ceph_decode_copy(void ** p,void * pv,size_t n)43*4882a593Smuzhiyun static inline void ceph_decode_copy(void **p, void *pv, size_t n)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun memcpy(pv, *p, n);
46*4882a593Smuzhiyun *p += n;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun /*
50*4882a593Smuzhiyun * bounds check input.
51*4882a593Smuzhiyun */
ceph_has_room(void ** p,void * end,size_t n)52*4882a593Smuzhiyun static inline bool ceph_has_room(void **p, void *end, size_t n)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun return end >= *p && n <= end - *p;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun #define ceph_decode_need(p, end, n, bad) \
58*4882a593Smuzhiyun do { \
59*4882a593Smuzhiyun if (!likely(ceph_has_room(p, end, n))) \
60*4882a593Smuzhiyun goto bad; \
61*4882a593Smuzhiyun } while (0)
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #define ceph_decode_64_safe(p, end, v, bad) \
64*4882a593Smuzhiyun do { \
65*4882a593Smuzhiyun ceph_decode_need(p, end, sizeof(u64), bad); \
66*4882a593Smuzhiyun v = ceph_decode_64(p); \
67*4882a593Smuzhiyun } while (0)
68*4882a593Smuzhiyun #define ceph_decode_32_safe(p, end, v, bad) \
69*4882a593Smuzhiyun do { \
70*4882a593Smuzhiyun ceph_decode_need(p, end, sizeof(u32), bad); \
71*4882a593Smuzhiyun v = ceph_decode_32(p); \
72*4882a593Smuzhiyun } while (0)
73*4882a593Smuzhiyun #define ceph_decode_16_safe(p, end, v, bad) \
74*4882a593Smuzhiyun do { \
75*4882a593Smuzhiyun ceph_decode_need(p, end, sizeof(u16), bad); \
76*4882a593Smuzhiyun v = ceph_decode_16(p); \
77*4882a593Smuzhiyun } while (0)
78*4882a593Smuzhiyun #define ceph_decode_8_safe(p, end, v, bad) \
79*4882a593Smuzhiyun do { \
80*4882a593Smuzhiyun ceph_decode_need(p, end, sizeof(u8), bad); \
81*4882a593Smuzhiyun v = ceph_decode_8(p); \
82*4882a593Smuzhiyun } while (0)
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun #define ceph_decode_copy_safe(p, end, pv, n, bad) \
85*4882a593Smuzhiyun do { \
86*4882a593Smuzhiyun ceph_decode_need(p, end, n, bad); \
87*4882a593Smuzhiyun ceph_decode_copy(p, pv, n); \
88*4882a593Smuzhiyun } while (0)
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun /*
91*4882a593Smuzhiyun * Allocate a buffer big enough to hold the wire-encoded string, and
92*4882a593Smuzhiyun * decode the string into it. The resulting string will always be
93*4882a593Smuzhiyun * terminated with '\0'. If successful, *p will be advanced
94*4882a593Smuzhiyun * past the decoded data. Also, if lenp is not a null pointer, the
95*4882a593Smuzhiyun * length (not including the terminating '\0') will be recorded in
96*4882a593Smuzhiyun * *lenp. Note that a zero-length string is a valid return value.
97*4882a593Smuzhiyun *
98*4882a593Smuzhiyun * Returns a pointer to the newly-allocated string buffer, or a
99*4882a593Smuzhiyun * pointer-coded errno if an error occurs. Neither *p nor *lenp
100*4882a593Smuzhiyun * will have been updated if an error is returned.
101*4882a593Smuzhiyun *
102*4882a593Smuzhiyun * There are two possible failures:
103*4882a593Smuzhiyun * - converting the string would require accessing memory at or
104*4882a593Smuzhiyun * beyond the "end" pointer provided (-ERANGE)
105*4882a593Smuzhiyun * - memory could not be allocated for the result (-ENOMEM)
106*4882a593Smuzhiyun */
ceph_extract_encoded_string(void ** p,void * end,size_t * lenp,gfp_t gfp)107*4882a593Smuzhiyun static inline char *ceph_extract_encoded_string(void **p, void *end,
108*4882a593Smuzhiyun size_t *lenp, gfp_t gfp)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun u32 len;
111*4882a593Smuzhiyun void *sp = *p;
112*4882a593Smuzhiyun char *buf;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun ceph_decode_32_safe(&sp, end, len, bad);
115*4882a593Smuzhiyun if (!ceph_has_room(&sp, end, len))
116*4882a593Smuzhiyun goto bad;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun buf = kmalloc(len + 1, gfp);
119*4882a593Smuzhiyun if (!buf)
120*4882a593Smuzhiyun return ERR_PTR(-ENOMEM);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun if (len)
123*4882a593Smuzhiyun memcpy(buf, sp, len);
124*4882a593Smuzhiyun buf[len] = '\0';
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun *p = (char *) *p + sizeof (u32) + len;
127*4882a593Smuzhiyun if (lenp)
128*4882a593Smuzhiyun *lenp = (size_t) len;
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun return buf;
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun bad:
133*4882a593Smuzhiyun return ERR_PTR(-ERANGE);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun /*
137*4882a593Smuzhiyun * skip helpers
138*4882a593Smuzhiyun */
139*4882a593Smuzhiyun #define ceph_decode_skip_n(p, end, n, bad) \
140*4882a593Smuzhiyun do { \
141*4882a593Smuzhiyun ceph_decode_need(p, end, n, bad); \
142*4882a593Smuzhiyun *p += n; \
143*4882a593Smuzhiyun } while (0)
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun #define ceph_decode_skip_64(p, end, bad) \
146*4882a593Smuzhiyun ceph_decode_skip_n(p, end, sizeof(u64), bad)
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun #define ceph_decode_skip_32(p, end, bad) \
149*4882a593Smuzhiyun ceph_decode_skip_n(p, end, sizeof(u32), bad)
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun #define ceph_decode_skip_16(p, end, bad) \
152*4882a593Smuzhiyun ceph_decode_skip_n(p, end, sizeof(u16), bad)
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun #define ceph_decode_skip_8(p, end, bad) \
155*4882a593Smuzhiyun ceph_decode_skip_n(p, end, sizeof(u8), bad)
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun #define ceph_decode_skip_string(p, end, bad) \
158*4882a593Smuzhiyun do { \
159*4882a593Smuzhiyun u32 len; \
160*4882a593Smuzhiyun \
161*4882a593Smuzhiyun ceph_decode_32_safe(p, end, len, bad); \
162*4882a593Smuzhiyun ceph_decode_skip_n(p, end, len, bad); \
163*4882a593Smuzhiyun } while (0)
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun #define ceph_decode_skip_set(p, end, type, bad) \
166*4882a593Smuzhiyun do { \
167*4882a593Smuzhiyun u32 len; \
168*4882a593Smuzhiyun \
169*4882a593Smuzhiyun ceph_decode_32_safe(p, end, len, bad); \
170*4882a593Smuzhiyun while (len--) \
171*4882a593Smuzhiyun ceph_decode_skip_##type(p, end, bad); \
172*4882a593Smuzhiyun } while (0)
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun #define ceph_decode_skip_map(p, end, ktype, vtype, bad) \
175*4882a593Smuzhiyun do { \
176*4882a593Smuzhiyun u32 len; \
177*4882a593Smuzhiyun \
178*4882a593Smuzhiyun ceph_decode_32_safe(p, end, len, bad); \
179*4882a593Smuzhiyun while (len--) { \
180*4882a593Smuzhiyun ceph_decode_skip_##ktype(p, end, bad); \
181*4882a593Smuzhiyun ceph_decode_skip_##vtype(p, end, bad); \
182*4882a593Smuzhiyun } \
183*4882a593Smuzhiyun } while (0)
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun #define ceph_decode_skip_map_of_map(p, end, ktype1, ktype2, vtype2, bad) \
186*4882a593Smuzhiyun do { \
187*4882a593Smuzhiyun u32 len; \
188*4882a593Smuzhiyun \
189*4882a593Smuzhiyun ceph_decode_32_safe(p, end, len, bad); \
190*4882a593Smuzhiyun while (len--) { \
191*4882a593Smuzhiyun ceph_decode_skip_##ktype1(p, end, bad); \
192*4882a593Smuzhiyun ceph_decode_skip_map(p, end, ktype2, vtype2, bad); \
193*4882a593Smuzhiyun } \
194*4882a593Smuzhiyun } while (0)
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun /*
197*4882a593Smuzhiyun * struct ceph_timespec <-> struct timespec64
198*4882a593Smuzhiyun */
ceph_decode_timespec64(struct timespec64 * ts,const struct ceph_timespec * tv)199*4882a593Smuzhiyun static inline void ceph_decode_timespec64(struct timespec64 *ts,
200*4882a593Smuzhiyun const struct ceph_timespec *tv)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun /*
203*4882a593Smuzhiyun * This will still overflow in year 2106. We could extend
204*4882a593Smuzhiyun * the protocol to steal two more bits from tv_nsec to
205*4882a593Smuzhiyun * add three more 136 year epochs after that the way ext4
206*4882a593Smuzhiyun * does if necessary.
207*4882a593Smuzhiyun */
208*4882a593Smuzhiyun ts->tv_sec = (time64_t)le32_to_cpu(tv->tv_sec);
209*4882a593Smuzhiyun ts->tv_nsec = (long)le32_to_cpu(tv->tv_nsec);
210*4882a593Smuzhiyun }
ceph_encode_timespec64(struct ceph_timespec * tv,const struct timespec64 * ts)211*4882a593Smuzhiyun static inline void ceph_encode_timespec64(struct ceph_timespec *tv,
212*4882a593Smuzhiyun const struct timespec64 *ts)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun tv->tv_sec = cpu_to_le32((u32)ts->tv_sec);
215*4882a593Smuzhiyun tv->tv_nsec = cpu_to_le32((u32)ts->tv_nsec);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun /*
219*4882a593Smuzhiyun * sockaddr_storage <-> ceph_sockaddr
220*4882a593Smuzhiyun */
221*4882a593Smuzhiyun #define CEPH_ENTITY_ADDR_TYPE_NONE 0
222*4882a593Smuzhiyun #define CEPH_ENTITY_ADDR_TYPE_LEGACY __cpu_to_le32(1)
223*4882a593Smuzhiyun
ceph_encode_banner_addr(struct ceph_entity_addr * a)224*4882a593Smuzhiyun static inline void ceph_encode_banner_addr(struct ceph_entity_addr *a)
225*4882a593Smuzhiyun {
226*4882a593Smuzhiyun __be16 ss_family = htons(a->in_addr.ss_family);
227*4882a593Smuzhiyun a->in_addr.ss_family = *(__u16 *)&ss_family;
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun /* Banner addresses require TYPE_NONE */
230*4882a593Smuzhiyun a->type = CEPH_ENTITY_ADDR_TYPE_NONE;
231*4882a593Smuzhiyun }
ceph_decode_banner_addr(struct ceph_entity_addr * a)232*4882a593Smuzhiyun static inline void ceph_decode_banner_addr(struct ceph_entity_addr *a)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun __be16 ss_family = *(__be16 *)&a->in_addr.ss_family;
235*4882a593Smuzhiyun a->in_addr.ss_family = ntohs(ss_family);
236*4882a593Smuzhiyun WARN_ON(a->in_addr.ss_family == 512);
237*4882a593Smuzhiyun a->type = CEPH_ENTITY_ADDR_TYPE_LEGACY;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun extern int ceph_decode_entity_addr(void **p, void *end,
241*4882a593Smuzhiyun struct ceph_entity_addr *addr);
242*4882a593Smuzhiyun /*
243*4882a593Smuzhiyun * encoders
244*4882a593Smuzhiyun */
ceph_encode_64(void ** p,u64 v)245*4882a593Smuzhiyun static inline void ceph_encode_64(void **p, u64 v)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun put_unaligned_le64(v, (__le64 *)*p);
248*4882a593Smuzhiyun *p += sizeof(u64);
249*4882a593Smuzhiyun }
ceph_encode_32(void ** p,u32 v)250*4882a593Smuzhiyun static inline void ceph_encode_32(void **p, u32 v)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun put_unaligned_le32(v, (__le32 *)*p);
253*4882a593Smuzhiyun *p += sizeof(u32);
254*4882a593Smuzhiyun }
ceph_encode_16(void ** p,u16 v)255*4882a593Smuzhiyun static inline void ceph_encode_16(void **p, u16 v)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun put_unaligned_le16(v, (__le16 *)*p);
258*4882a593Smuzhiyun *p += sizeof(u16);
259*4882a593Smuzhiyun }
ceph_encode_8(void ** p,u8 v)260*4882a593Smuzhiyun static inline void ceph_encode_8(void **p, u8 v)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun *(u8 *)*p = v;
263*4882a593Smuzhiyun (*p)++;
264*4882a593Smuzhiyun }
ceph_encode_copy(void ** p,const void * s,int len)265*4882a593Smuzhiyun static inline void ceph_encode_copy(void **p, const void *s, int len)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun memcpy(*p, s, len);
268*4882a593Smuzhiyun *p += len;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun /*
272*4882a593Smuzhiyun * filepath, string encoders
273*4882a593Smuzhiyun */
ceph_encode_filepath(void ** p,void * end,u64 ino,const char * path)274*4882a593Smuzhiyun static inline void ceph_encode_filepath(void **p, void *end,
275*4882a593Smuzhiyun u64 ino, const char *path)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun u32 len = path ? strlen(path) : 0;
278*4882a593Smuzhiyun BUG_ON(*p + 1 + sizeof(ino) + sizeof(len) + len > end);
279*4882a593Smuzhiyun ceph_encode_8(p, 1);
280*4882a593Smuzhiyun ceph_encode_64(p, ino);
281*4882a593Smuzhiyun ceph_encode_32(p, len);
282*4882a593Smuzhiyun if (len)
283*4882a593Smuzhiyun memcpy(*p, path, len);
284*4882a593Smuzhiyun *p += len;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
ceph_encode_string(void ** p,void * end,const char * s,u32 len)287*4882a593Smuzhiyun static inline void ceph_encode_string(void **p, void *end,
288*4882a593Smuzhiyun const char *s, u32 len)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun BUG_ON(*p + sizeof(len) + len > end);
291*4882a593Smuzhiyun ceph_encode_32(p, len);
292*4882a593Smuzhiyun if (len)
293*4882a593Smuzhiyun memcpy(*p, s, len);
294*4882a593Smuzhiyun *p += len;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun /*
298*4882a593Smuzhiyun * version and length starting block encoders/decoders
299*4882a593Smuzhiyun */
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun /* current code version (u8) + compat code version (u8) + len of struct (u32) */
302*4882a593Smuzhiyun #define CEPH_ENCODING_START_BLK_LEN 6
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun /**
305*4882a593Smuzhiyun * ceph_start_encoding - start encoding block
306*4882a593Smuzhiyun * @struct_v: current (code) version of the encoding
307*4882a593Smuzhiyun * @struct_compat: oldest code version that can decode it
308*4882a593Smuzhiyun * @struct_len: length of struct encoding
309*4882a593Smuzhiyun */
ceph_start_encoding(void ** p,u8 struct_v,u8 struct_compat,u32 struct_len)310*4882a593Smuzhiyun static inline void ceph_start_encoding(void **p, u8 struct_v, u8 struct_compat,
311*4882a593Smuzhiyun u32 struct_len)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun ceph_encode_8(p, struct_v);
314*4882a593Smuzhiyun ceph_encode_8(p, struct_compat);
315*4882a593Smuzhiyun ceph_encode_32(p, struct_len);
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun /**
319*4882a593Smuzhiyun * ceph_start_decoding - start decoding block
320*4882a593Smuzhiyun * @v: current version of the encoding that the code supports
321*4882a593Smuzhiyun * @name: name of the struct (free-form)
322*4882a593Smuzhiyun * @struct_v: out param for the encoding version
323*4882a593Smuzhiyun * @struct_len: out param for the length of struct encoding
324*4882a593Smuzhiyun *
325*4882a593Smuzhiyun * Validates the length of struct encoding, so unsafe ceph_decode_*
326*4882a593Smuzhiyun * variants can be used for decoding.
327*4882a593Smuzhiyun */
ceph_start_decoding(void ** p,void * end,u8 v,const char * name,u8 * struct_v,u32 * struct_len)328*4882a593Smuzhiyun static inline int ceph_start_decoding(void **p, void *end, u8 v,
329*4882a593Smuzhiyun const char *name, u8 *struct_v,
330*4882a593Smuzhiyun u32 *struct_len)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun u8 struct_compat;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun ceph_decode_need(p, end, CEPH_ENCODING_START_BLK_LEN, bad);
335*4882a593Smuzhiyun *struct_v = ceph_decode_8(p);
336*4882a593Smuzhiyun struct_compat = ceph_decode_8(p);
337*4882a593Smuzhiyun if (v < struct_compat) {
338*4882a593Smuzhiyun pr_warn("got struct_v %d struct_compat %d > %d of %s\n",
339*4882a593Smuzhiyun *struct_v, struct_compat, v, name);
340*4882a593Smuzhiyun return -EINVAL;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun *struct_len = ceph_decode_32(p);
344*4882a593Smuzhiyun ceph_decode_need(p, end, *struct_len, bad);
345*4882a593Smuzhiyun return 0;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun bad:
348*4882a593Smuzhiyun return -ERANGE;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun #define ceph_encode_need(p, end, n, bad) \
352*4882a593Smuzhiyun do { \
353*4882a593Smuzhiyun if (!likely(ceph_has_room(p, end, n))) \
354*4882a593Smuzhiyun goto bad; \
355*4882a593Smuzhiyun } while (0)
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun #define ceph_encode_64_safe(p, end, v, bad) \
358*4882a593Smuzhiyun do { \
359*4882a593Smuzhiyun ceph_encode_need(p, end, sizeof(u64), bad); \
360*4882a593Smuzhiyun ceph_encode_64(p, v); \
361*4882a593Smuzhiyun } while (0)
362*4882a593Smuzhiyun #define ceph_encode_32_safe(p, end, v, bad) \
363*4882a593Smuzhiyun do { \
364*4882a593Smuzhiyun ceph_encode_need(p, end, sizeof(u32), bad); \
365*4882a593Smuzhiyun ceph_encode_32(p, v); \
366*4882a593Smuzhiyun } while (0)
367*4882a593Smuzhiyun #define ceph_encode_16_safe(p, end, v, bad) \
368*4882a593Smuzhiyun do { \
369*4882a593Smuzhiyun ceph_encode_need(p, end, sizeof(u16), bad); \
370*4882a593Smuzhiyun ceph_encode_16(p, v); \
371*4882a593Smuzhiyun } while (0)
372*4882a593Smuzhiyun #define ceph_encode_8_safe(p, end, v, bad) \
373*4882a593Smuzhiyun do { \
374*4882a593Smuzhiyun ceph_encode_need(p, end, sizeof(u8), bad); \
375*4882a593Smuzhiyun ceph_encode_8(p, v); \
376*4882a593Smuzhiyun } while (0)
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun #define ceph_encode_copy_safe(p, end, pv, n, bad) \
379*4882a593Smuzhiyun do { \
380*4882a593Smuzhiyun ceph_encode_need(p, end, n, bad); \
381*4882a593Smuzhiyun ceph_encode_copy(p, pv, n); \
382*4882a593Smuzhiyun } while (0)
383*4882a593Smuzhiyun #define ceph_encode_string_safe(p, end, s, n, bad) \
384*4882a593Smuzhiyun do { \
385*4882a593Smuzhiyun ceph_encode_need(p, end, n, bad); \
386*4882a593Smuzhiyun ceph_encode_string(p, end, s, n); \
387*4882a593Smuzhiyun } while (0)
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun #endif
391