diff options
Diffstat (limited to 'fs/ceph/decode.h')
-rw-r--r-- | fs/ceph/decode.h | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h new file mode 100644 index 000000000000..fc2769df062d --- /dev/null +++ b/fs/ceph/decode.h | |||
@@ -0,0 +1,136 @@ | |||
1 | #ifndef __CEPH_DECODE_H | ||
2 | #define __CEPH_DECODE_H | ||
3 | |||
4 | #include <asm/unaligned.h> | ||
5 | |||
6 | /* | ||
7 | * in all cases, | ||
8 | * void **p pointer to position pointer | ||
9 | * void *end pointer to end of buffer (last byte + 1) | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * bounds check input. | ||
14 | */ | ||
15 | #define ceph_decode_need(p, end, n, bad) \ | ||
16 | do { \ | ||
17 | if (unlikely(*(p) + (n) > (end))) \ | ||
18 | goto bad; \ | ||
19 | } while (0) | ||
20 | |||
21 | #define ceph_decode_64(p, v) \ | ||
22 | do { \ | ||
23 | v = get_unaligned_le64(*(p)); \ | ||
24 | *(p) += sizeof(u64); \ | ||
25 | } while (0) | ||
26 | #define ceph_decode_32(p, v) \ | ||
27 | do { \ | ||
28 | v = get_unaligned_le32(*(p)); \ | ||
29 | *(p) += sizeof(u32); \ | ||
30 | } while (0) | ||
31 | #define ceph_decode_16(p, v) \ | ||
32 | do { \ | ||
33 | v = get_unaligned_le16(*(p)); \ | ||
34 | *(p) += sizeof(u16); \ | ||
35 | } while (0) | ||
36 | #define ceph_decode_8(p, v) \ | ||
37 | do { \ | ||
38 | v = *(u8 *)*(p); \ | ||
39 | (*p)++; \ | ||
40 | } while (0) | ||
41 | |||
42 | #define ceph_decode_copy(p, pv, n) \ | ||
43 | do { \ | ||
44 | memcpy(pv, *(p), n); \ | ||
45 | *(p) += n; \ | ||
46 | } while (0) | ||
47 | |||
48 | /* bounds check too */ | ||
49 | #define ceph_decode_64_safe(p, end, v, bad) \ | ||
50 | do { \ | ||
51 | ceph_decode_need(p, end, sizeof(u64), bad); \ | ||
52 | ceph_decode_64(p, v); \ | ||
53 | } while (0) | ||
54 | #define ceph_decode_32_safe(p, end, v, bad) \ | ||
55 | do { \ | ||
56 | ceph_decode_need(p, end, sizeof(u32), bad); \ | ||
57 | ceph_decode_32(p, v); \ | ||
58 | } while (0) | ||
59 | #define ceph_decode_16_safe(p, end, v, bad) \ | ||
60 | do { \ | ||
61 | ceph_decode_need(p, end, sizeof(u16), bad); \ | ||
62 | ceph_decode_16(p, v); \ | ||
63 | } while (0) | ||
64 | |||
65 | #define ceph_decode_copy_safe(p, end, pv, n, bad) \ | ||
66 | do { \ | ||
67 | ceph_decode_need(p, end, n, bad); \ | ||
68 | ceph_decode_copy(p, pv, n); \ | ||
69 | } while (0) | ||
70 | |||
71 | /* | ||
72 | * struct ceph_timespec <-> struct timespec | ||
73 | */ | ||
74 | #define ceph_decode_timespec(ts, tv) \ | ||
75 | do { \ | ||
76 | (ts)->tv_sec = le32_to_cpu((tv)->tv_sec); \ | ||
77 | (ts)->tv_nsec = le32_to_cpu((tv)->tv_nsec); \ | ||
78 | } while (0) | ||
79 | #define ceph_encode_timespec(tv, ts) \ | ||
80 | do { \ | ||
81 | (tv)->tv_sec = cpu_to_le32((ts)->tv_sec); \ | ||
82 | (tv)->tv_nsec = cpu_to_le32((ts)->tv_nsec); \ | ||
83 | } while (0) | ||
84 | |||
85 | |||
86 | /* | ||
87 | * encoders | ||
88 | */ | ||
89 | #define ceph_encode_64(p, v) \ | ||
90 | do { \ | ||
91 | put_unaligned_le64(v, (__le64 *)*(p)); \ | ||
92 | *(p) += sizeof(u64); \ | ||
93 | } while (0) | ||
94 | #define ceph_encode_32(p, v) \ | ||
95 | do { \ | ||
96 | put_unaligned_le32(v, (__le32 *)*(p)); \ | ||
97 | *(p) += sizeof(u32); \ | ||
98 | } while (0) | ||
99 | #define ceph_encode_16(p, v) \ | ||
100 | do { \ | ||
101 | put_unaligned_le16(v), (__le16 *)*(p)); \ | ||
102 | *(p) += sizeof(u16); \ | ||
103 | } while (0) | ||
104 | #define ceph_encode_8(p, v) \ | ||
105 | do { \ | ||
106 | *(u8 *)*(p) = v; \ | ||
107 | (*(p))++; \ | ||
108 | } while (0) | ||
109 | |||
110 | /* | ||
111 | * filepath, string encoders | ||
112 | */ | ||
113 | static inline void ceph_encode_filepath(void **p, void *end, | ||
114 | u64 ino, const char *path) | ||
115 | { | ||
116 | u32 len = path ? strlen(path) : 0; | ||
117 | BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end); | ||
118 | ceph_encode_64(p, ino); | ||
119 | ceph_encode_32(p, len); | ||
120 | if (len) | ||
121 | memcpy(*p, path, len); | ||
122 | *p += len; | ||
123 | } | ||
124 | |||
125 | static inline void ceph_encode_string(void **p, void *end, | ||
126 | const char *s, u32 len) | ||
127 | { | ||
128 | BUG_ON(*p + sizeof(len) + len > end); | ||
129 | ceph_encode_32(p, len); | ||
130 | if (len) | ||
131 | memcpy(*p, s, len); | ||
132 | *p += len; | ||
133 | } | ||
134 | |||
135 | |||
136 | #endif | ||