ceph: messenger library
[safe/jmp/linux-2.6] / fs / ceph / decode.h
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