diff options
Diffstat (limited to 'fs/ceph/decode.h')
-rw-r--r-- | fs/ceph/decode.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h new file mode 100644 index 000000000000..65b3e022eaf5 --- /dev/null +++ b/fs/ceph/decode.h | |||
@@ -0,0 +1,194 @@ | |||
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 | |||
15 | static inline u64 ceph_decode_64(void **p) | ||
16 | { | ||
17 | u64 v = get_unaligned_le64(*p); | ||
18 | *p += sizeof(u64); | ||
19 | return v; | ||
20 | } | ||
21 | static inline u32 ceph_decode_32(void **p) | ||
22 | { | ||
23 | u32 v = get_unaligned_le32(*p); | ||
24 | *p += sizeof(u32); | ||
25 | return v; | ||
26 | } | ||
27 | static inline u16 ceph_decode_16(void **p) | ||
28 | { | ||
29 | u16 v = get_unaligned_le16(*p); | ||
30 | *p += sizeof(u16); | ||
31 | return v; | ||
32 | } | ||
33 | static inline u8 ceph_decode_8(void **p) | ||
34 | { | ||
35 | u8 v = *(u8 *)*p; | ||
36 | (*p)++; | ||
37 | return v; | ||
38 | } | ||
39 | static 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 | */ | ||
84 | static 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 | } | ||
90 | static 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 | */ | ||
100 | static inline void ceph_encode_addr(struct ceph_entity_addr *a) | ||
101 | { | ||
102 | a->in_addr.ss_family = htons(a->in_addr.ss_family); | ||
103 | } | ||
104 | static inline void ceph_decode_addr(struct ceph_entity_addr *a) | ||
105 | { | ||
106 | a->in_addr.ss_family = ntohs(a->in_addr.ss_family); | ||
107 | WARN_ON(a->in_addr.ss_family == 512); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * encoders | ||
112 | */ | ||
113 | static inline void ceph_encode_64(void **p, u64 v) | ||
114 | { | ||
115 | put_unaligned_le64(v, (__le64 *)*p); | ||
116 | *p += sizeof(u64); | ||
117 | } | ||
118 | static inline void ceph_encode_32(void **p, u32 v) | ||
119 | { | ||
120 | put_unaligned_le32(v, (__le32 *)*p); | ||
121 | *p += sizeof(u32); | ||
122 | } | ||
123 | static inline void ceph_encode_16(void **p, u16 v) | ||
124 | { | ||
125 | put_unaligned_le16(v, (__le16 *)*p); | ||
126 | *p += sizeof(u16); | ||
127 | } | ||
128 | static inline void ceph_encode_8(void **p, u8 v) | ||
129 | { | ||
130 | *(u8 *)*p = v; | ||
131 | (*p)++; | ||
132 | } | ||
133 | static inline void ceph_encode_copy(void **p, const void *s, int len) | ||
134 | { | ||
135 | memcpy(*p, s, len); | ||
136 | *p += len; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * filepath, string encoders | ||
141 | */ | ||
142 | static inline void ceph_encode_filepath(void **p, void *end, | ||
143 | u64 ino, const char *path) | ||
144 | { | ||
145 | u32 len = path ? strlen(path) : 0; | ||
146 | BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end); | ||
147 | ceph_encode_8(p, 1); | ||
148 | ceph_encode_64(p, ino); | ||
149 | ceph_encode_32(p, len); | ||
150 | if (len) | ||
151 | memcpy(*p, path, len); | ||
152 | *p += len; | ||
153 | } | ||
154 | |||
155 | static inline void ceph_encode_string(void **p, void *end, | ||
156 | const char *s, u32 len) | ||
157 | { | ||
158 | BUG_ON(*p + sizeof(len) + len > end); | ||
159 | ceph_encode_32(p, len); | ||
160 | if (len) | ||
161 | memcpy(*p, s, len); | ||
162 | *p += len; | ||
163 | } | ||
164 | |||
165 | #define ceph_encode_need(p, end, n, bad) \ | ||
166 | do { \ | ||
167 | if (unlikely(*(p) + (n) > (end))) \ | ||
168 | goto bad; \ | ||
169 | } while (0) | ||
170 | |||
171 | #define ceph_encode_64_safe(p, end, v, bad) \ | ||
172 | do { \ | ||
173 | ceph_encode_need(p, end, sizeof(u64), bad); \ | ||
174 | ceph_encode_64(p, v); \ | ||
175 | } while (0) | ||
176 | #define ceph_encode_32_safe(p, end, v, bad) \ | ||
177 | do { \ | ||
178 | ceph_encode_need(p, end, sizeof(u32), bad); \ | ||
179 | ceph_encode_32(p, v); \ | ||
180 | } while (0) | ||
181 | #define ceph_encode_16_safe(p, end, v, bad) \ | ||
182 | do { \ | ||
183 | ceph_encode_need(p, end, sizeof(u16), bad); \ | ||
184 | ceph_encode_16(p, v); \ | ||
185 | } while (0) | ||
186 | |||
187 | #define ceph_encode_copy_safe(p, end, pv, n, bad) \ | ||
188 | do { \ | ||
189 | ceph_encode_need(p, end, n, bad); \ | ||
190 | ceph_encode_copy(p, pv, n); \ | ||
191 | } while (0) | ||
192 | |||
193 | |||
194 | #endif | ||