1#ifndef __CEPH_DECODE_H 2#define __CEPH_DECODE_H 3 4#include <asm/unaligned.h> 5#include <linux/time.h> 6 7#include "types.h" 8 9/* 10 * in all cases, 11 * void **p pointer to position pointer 12 * void *end pointer to end of buffer (last byte + 1) 13 */ 14 15static inline u64 ceph_decode_64(void **p) 16{ 17 u64 v = get_unaligned_le64(*p); 18 *p += sizeof(u64); 19 return v; 20} 21static inline u32 ceph_decode_32(void **p) 22{ 23 u32 v = get_unaligned_le32(*p); 24 *p += sizeof(u32); 25 return v; 26} 27static inline u16 ceph_decode_16(void **p) 28{ 29 u16 v = get_unaligned_le16(*p); 30 *p += sizeof(u16); 31 return v; 32} 33static inline u8 ceph_decode_8(void **p) 34{ 35 u8 v = *(u8 *)*p; 36 (*p)++; 37 return v; 38} 39static inline void ceph_decode_copy(void **p, void *pv, size_t n) 40{ 41 memcpy(pv, *p, n); 42 *p += n; 43} 44 45/* 46 * bounds check input. 47 */ 48#define ceph_decode_need(p, end, n, bad) \ 49 do { \ 50 if (unlikely(*(p) + (n) > (end))) \ 51 goto bad; \ 52 } while (0) 53 54#define ceph_decode_64_safe(p, end, v, bad) \ 55 do { \ 56 ceph_decode_need(p, end, sizeof(u64), bad); \ 57 v = ceph_decode_64(p); \ 58 } while (0) 59#define ceph_decode_32_safe(p, end, v, bad) \ 60 do { \ 61 ceph_decode_need(p, end, sizeof(u32), bad); \ 62 v = ceph_decode_32(p); \ 63 } while (0) 64#define ceph_decode_16_safe(p, end, v, bad) \ 65 do { \ 66 ceph_decode_need(p, end, sizeof(u16), bad); \ 67 v = ceph_decode_16(p); \ 68 } while (0) 69#define ceph_decode_8_safe(p, end, v, bad) \ 70 do { \ 71 ceph_decode_need(p, end, sizeof(u8), bad); \ 72 v = ceph_decode_8(p); \ 73 } while (0) 74 75#define ceph_decode_copy_safe(p, end, pv, n, bad) \ 76 do { \ 77 ceph_decode_need(p, end, n, bad); \ 78 ceph_decode_copy(p, pv, n); \ 79 } while (0) 80 81/* 82 * struct ceph_timespec <-> struct timespec 83 */ 84static inline void ceph_decode_timespec(struct timespec *ts, 85 const struct ceph_timespec *tv) 86{ 87 ts->tv_sec = le32_to_cpu(tv->tv_sec); 88 ts->tv_nsec = le32_to_cpu(tv->tv_nsec); 89} 90static inline void ceph_encode_timespec(struct ceph_timespec *tv, 91 const struct timespec *ts) 92{ 93 tv->tv_sec = cpu_to_le32(ts->tv_sec); 94 tv->tv_nsec = cpu_to_le32(ts->tv_nsec); 95} 96 97/* 98 * sockaddr_storage <-> ceph_sockaddr 99 */ 100static inline void ceph_encode_addr(struct ceph_entity_addr *a) 101{ 102 __be16 ss_family = htons(a->in_addr.ss_family); 103 a->in_addr.ss_family = *(__u16 *)&ss_family; 104} 105static inline void ceph_decode_addr(struct ceph_entity_addr *a) 106{ 107 __be16 ss_family = *(__be16 *)&a->in_addr.ss_family; 108 a->in_addr.ss_family = ntohs(ss_family); 109 WARN_ON(a->in_addr.ss_family == 512); 110} 111 112/* 113 * encoders 114 */ 115static inline void ceph_encode_64(void **p, u64 v) 116{ 117 put_unaligned_le64(v, (__le64 *)*p); 118 *p += sizeof(u64); 119} 120static inline void ceph_encode_32(void **p, u32 v) 121{ 122 put_unaligned_le32(v, (__le32 *)*p); 123 *p += sizeof(u32); 124} 125static inline void ceph_encode_16(void **p, u16 v) 126{ 127 put_unaligned_le16(v, (__le16 *)*p); 128 *p += sizeof(u16); 129} 130static inline void ceph_encode_8(void **p, u8 v) 131{ 132 *(u8 *)*p = v; 133 (*p)++; 134} 135static inline void ceph_encode_copy(void **p, const void *s, int len) 136{ 137 memcpy(*p, s, len); 138 *p += len; 139} 140 141/* 142 * filepath, string encoders 143 */ 144static inline void ceph_encode_filepath(void **p, void *end, 145 u64 ino, const char *path) 146{ 147 u32 len = path ? strlen(path) : 0; 148 BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end); 149 ceph_encode_8(p, 1); 150 ceph_encode_64(p, ino); 151 ceph_encode_32(p, len); 152 if (len) 153 memcpy(*p, path, len); 154 *p += len; 155} 156 157static inline void ceph_encode_string(void **p, void *end, 158 const char *s, u32 len) 159{ 160 BUG_ON(*p + sizeof(len) + len > end); 161 ceph_encode_32(p, len); 162 if (len) 163 memcpy(*p, s, len); 164 *p += len; 165} 166 167#define ceph_encode_need(p, end, n, bad) \ 168 do { \ 169 if (unlikely(*(p) + (n) > (end))) \ 170 goto bad; \ 171 } while (0) 172 173#define ceph_encode_64_safe(p, end, v, bad) \ 174 do { \ 175 ceph_encode_need(p, end, sizeof(u64), bad); \ 176 ceph_encode_64(p, v); \ 177 } while (0) 178#define ceph_encode_32_safe(p, end, v, bad) \ 179 do { \ 180 ceph_encode_need(p, end, sizeof(u32), bad); \ 181 ceph_encode_32(p, v); \ 182 } while (0) 183#define ceph_encode_16_safe(p, end, v, bad) \ 184 do { \ 185 ceph_encode_need(p, end, sizeof(u16), bad); \ 186 ceph_encode_16(p, v); \ 187 } while (0) 188 189#define ceph_encode_copy_safe(p, end, pv, n, bad) \ 190 do { \ 191 ceph_encode_need(p, end, n, bad); \ 192 ceph_encode_copy(p, pv, n); \ 193 } while (0) 194 195 196#endif 197