1 #ifndef __CEPH_DECODE_H
2 #define __CEPH_DECODE_H
6 #include <linux/time.h>
7 #include <asm/unaligned.h>
13 * void **p pointer to position pointer
14 * void *end pointer to end of buffer (last byte + 1)
17 static inline u64
ceph_decode_64(void **p
)
19 u64 v
= get_unaligned_le64(*p
);
23 static inline u32
ceph_decode_32(void **p
)
25 u32 v
= get_unaligned_le32(*p
);
29 static inline u16
ceph_decode_16(void **p
)
31 u16 v
= get_unaligned_le16(*p
);
35 static inline u8
ceph_decode_8(void **p
)
41 static inline void ceph_decode_copy(void **p
, void *pv
, size_t n
)
50 static inline int ceph_has_room(void **p
, void *end
, size_t n
)
52 return end
>= *p
&& n
<= end
- *p
;
55 #define ceph_decode_need(p, end, n, bad) \
57 if (!likely(ceph_has_room(p, end, n))) \
61 #define ceph_decode_64_safe(p, end, v, bad) \
63 ceph_decode_need(p, end, sizeof(u64), bad); \
64 v = ceph_decode_64(p); \
66 #define ceph_decode_32_safe(p, end, v, bad) \
68 ceph_decode_need(p, end, sizeof(u32), bad); \
69 v = ceph_decode_32(p); \
71 #define ceph_decode_16_safe(p, end, v, bad) \
73 ceph_decode_need(p, end, sizeof(u16), bad); \
74 v = ceph_decode_16(p); \
76 #define ceph_decode_8_safe(p, end, v, bad) \
78 ceph_decode_need(p, end, sizeof(u8), bad); \
79 v = ceph_decode_8(p); \
82 #define ceph_decode_copy_safe(p, end, pv, n, bad) \
84 ceph_decode_need(p, end, n, bad); \
85 ceph_decode_copy(p, pv, n); \
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.
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.
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
105 static inline char *ceph_extract_encoded_string(void **p
, void *end
,
106 size_t *lenp
, gfp_t gfp
)
112 ceph_decode_32_safe(&sp
, end
, len
, bad
);
113 if (!ceph_has_room(&sp
, end
, len
))
116 buf
= kmalloc(len
+ 1, gfp
);
118 return ERR_PTR(-ENOMEM
);
121 memcpy(buf
, sp
, len
);
124 *p
= (char *) *p
+ sizeof (u32
) + len
;
126 *lenp
= (size_t) len
;
131 return ERR_PTR(-ERANGE
);
135 * struct ceph_timespec <-> struct timespec
137 static inline void ceph_decode_timespec(struct timespec
*ts
,
138 const struct ceph_timespec
*tv
)
140 ts
->tv_sec
= le32_to_cpu(tv
->tv_sec
);
141 ts
->tv_nsec
= le32_to_cpu(tv
->tv_nsec
);
143 static inline void ceph_encode_timespec(struct ceph_timespec
*tv
,
144 const struct timespec
*ts
)
146 tv
->tv_sec
= cpu_to_le32(ts
->tv_sec
);
147 tv
->tv_nsec
= cpu_to_le32(ts
->tv_nsec
);
151 * sockaddr_storage <-> ceph_sockaddr
153 static inline void ceph_encode_addr(struct ceph_entity_addr
*a
)
155 __be16 ss_family
= htons(a
->in_addr
.ss_family
);
156 a
->in_addr
.ss_family
= *(__u16
*)&ss_family
;
158 static inline void ceph_decode_addr(struct ceph_entity_addr
*a
)
160 __be16 ss_family
= *(__be16
*)&a
->in_addr
.ss_family
;
161 a
->in_addr
.ss_family
= ntohs(ss_family
);
162 WARN_ON(a
->in_addr
.ss_family
== 512);
168 static inline void ceph_encode_64(void **p
, u64 v
)
170 put_unaligned_le64(v
, (__le64
*)*p
);
173 static inline void ceph_encode_32(void **p
, u32 v
)
175 put_unaligned_le32(v
, (__le32
*)*p
);
178 static inline void ceph_encode_16(void **p
, u16 v
)
180 put_unaligned_le16(v
, (__le16
*)*p
);
183 static inline void ceph_encode_8(void **p
, u8 v
)
188 static inline void ceph_encode_copy(void **p
, const void *s
, int len
)
195 * filepath, string encoders
197 static inline void ceph_encode_filepath(void **p
, void *end
,
198 u64 ino
, const char *path
)
200 u32 len
= path
? strlen(path
) : 0;
201 BUG_ON(*p
+ 1 + sizeof(ino
) + sizeof(len
) + len
> end
);
203 ceph_encode_64(p
, ino
);
204 ceph_encode_32(p
, len
);
206 memcpy(*p
, path
, len
);
210 static inline void ceph_encode_string(void **p
, void *end
,
211 const char *s
, u32 len
)
213 BUG_ON(*p
+ sizeof(len
) + len
> end
);
214 ceph_encode_32(p
, len
);
220 #define ceph_encode_need(p, end, n, bad) \
222 if (!likely(ceph_has_room(p, end, n))) \
226 #define ceph_encode_64_safe(p, end, v, bad) \
228 ceph_encode_need(p, end, sizeof(u64), bad); \
229 ceph_encode_64(p, v); \
231 #define ceph_encode_32_safe(p, end, v, bad) \
233 ceph_encode_need(p, end, sizeof(u32), bad); \
234 ceph_encode_32(p, v); \
236 #define ceph_encode_16_safe(p, end, v, bad) \
238 ceph_encode_need(p, end, sizeof(u16), bad); \
239 ceph_encode_16(p, v); \
242 #define ceph_encode_copy_safe(p, end, pv, n, bad) \
244 ceph_encode_need(p, end, n, bad); \
245 ceph_encode_copy(p, pv, n); \
247 #define ceph_encode_string_safe(p, end, s, n, bad) \
249 ceph_encode_need(p, end, n, bad); \
250 ceph_encode_string(p, end, s, n); \