/* * bounds check input.
*/ staticinlinebool ceph_has_room(void **p, void *end, size_t n)
{ return end >= *p && n <= end - *p;
}
#define ceph_decode_need(p, end, n, bad) \ do { \ if (!likely(ceph_has_room(p, end, n))) \ goto bad; \
} while (0)
#define ceph_decode_64_safe(p, end, v, bad) \ do { \
ceph_decode_need(p, end, sizeof(u64), bad); \
v = ceph_decode_64(p); \
} while (0) #define ceph_decode_32_safe(p, end, v, bad) \ do { \
ceph_decode_need(p, end, sizeof(u32), bad); \
v = ceph_decode_32(p); \
} while (0) #define ceph_decode_16_safe(p, end, v, bad) \ do { \
ceph_decode_need(p, end, sizeof(u16), bad); \
v = ceph_decode_16(p); \
} while (0) #define ceph_decode_8_safe(p, end, v, bad) \ do { \
ceph_decode_need(p, end, sizeof(u8), bad); \
v = ceph_decode_8(p); \
} while (0)
#define ceph_decode_copy_safe(p, end, pv, n, bad) \ do { \
ceph_decode_need(p, end, n, bad); \
ceph_decode_copy(p, pv, n); \
} while (0)
/* * Allocate a buffer big enough to hold the wire-encoded string, and * decode the string into it. The resulting string will always be * terminated with '\0'. If successful, *p will be advanced * past the decoded data. Also, if lenp is not a null pointer, the * length (not including the terminating '\0') will be recorded in * *lenp. Note that a zero-length string is a valid return value. * * Returns a pointer to the newly-allocated string buffer, or a * pointer-coded errno if an error occurs. Neither *p nor *lenp * will have been updated if an error is returned. * * There are two possible failures: * - converting the string would require accessing memory at or * beyond the "end" pointer provided (-ERANGE) * - memory could not be allocated for the result (-ENOMEM)
*/ staticinlinechar *ceph_extract_encoded_string(void **p, void *end,
size_t *lenp, gfp_t gfp)
{
u32 len; void *sp = *p; char *buf;
ceph_decode_32_safe(&sp, end, len, bad); if (!ceph_has_room(&sp, end, len)) goto bad;
buf = kmalloc(len + 1, gfp); if (!buf) return ERR_PTR(-ENOMEM);
/* * struct ceph_timespec <-> struct timespec64
*/ staticinlinevoid ceph_decode_timespec64(struct timespec64 *ts, conststruct ceph_timespec *tv)
{ /* * This will still overflow in year 2106. We could extend * the protocol to steal two more bits from tv_nsec to * add three more 136 year epochs after that the way ext4 * does if necessary.
*/
ts->tv_sec = (time64_t)le32_to_cpu(tv->tv_sec);
ts->tv_nsec = (long)le32_to_cpu(tv->tv_nsec);
} staticinlinevoid ceph_encode_timespec64(struct ceph_timespec *tv, conststruct timespec64 *ts)
{
tv->tv_sec = cpu_to_le32((u32)ts->tv_sec);
tv->tv_nsec = cpu_to_le32((u32)ts->tv_nsec);
}
/* * version and length starting block encoders/decoders
*/
/* current code version (u8) + compat code version (u8) + len of struct (u32) */ #define CEPH_ENCODING_START_BLK_LEN 6
/** * ceph_start_encoding - start encoding block * @struct_v: current (code) version of the encoding * @struct_compat: oldest code version that can decode it * @struct_len: length of struct encoding
*/ staticinlinevoid ceph_start_encoding(void **p, u8 struct_v, u8 struct_compat,
u32 struct_len)
{
ceph_encode_8(p, struct_v);
ceph_encode_8(p, struct_compat);
ceph_encode_32(p, struct_len);
}
/** * ceph_start_decoding - start decoding block * @v: current version of the encoding that the code supports * @name: name of the struct (free-form) * @struct_v: out param for the encoding version * @struct_len: out param for the length of struct encoding * * Validates the length of struct encoding, so unsafe ceph_decode_* * variants can be used for decoding.
*/ staticinlineint ceph_start_decoding(void **p, void *end, u8 v, constchar *name, u8 *struct_v,
u32 *struct_len)
{
u8 struct_compat;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.