Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
include
linux
ceph
decode.h
Go to the documentation of this file.
1
#ifndef __CEPH_DECODE_H
2
#define __CEPH_DECODE_H
3
4
#include <
linux/err.h
>
5
#include <
linux/bug.h
>
6
#include <linux/time.h>
7
#include <asm/unaligned.h>
8
9
#include <
linux/ceph/types.h
>
10
11
/*
12
* in all cases,
13
* void **p pointer to position pointer
14
* void *end pointer to end of buffer (last byte + 1)
15
*/
16
17
static
inline
u64
ceph_decode_64(
void
**
p
)
18
{
19
u64
v
=
get_unaligned_le64
(*p);
20
*p +=
sizeof
(
u64
);
21
return
v
;
22
}
23
static
inline
u32
ceph_decode_32(
void
**
p
)
24
{
25
u32
v
=
get_unaligned_le32
(*p);
26
*p +=
sizeof
(
u32
);
27
return
v
;
28
}
29
static
inline
u16
ceph_decode_16(
void
**
p
)
30
{
31
u16
v
= get_unaligned_le16(*p);
32
*p +=
sizeof
(
u16
);
33
return
v
;
34
}
35
static
inline
u8
ceph_decode_8(
void
**
p
)
36
{
37
u8
v
= *(
u8
*)*p;
38
(*p)++;
39
return
v
;
40
}
41
static
inline
void
ceph_decode_copy(
void
**
p
,
void
*
pv
,
size_t
n
)
42
{
43
memcpy
(pv, *p, n);
44
*p +=
n
;
45
}
46
47
/*
48
* bounds check input.
49
*/
50
static
inline
int
ceph_has_room(
void
**
p
,
void
*
end
,
size_t
n
)
51
{
52
return
end >= *p && n <= end - *
p
;
53
}
54
55
#define ceph_decode_need(p, end, n, bad) \
56
do { \
57
if (!likely(ceph_has_room(p, end, n))) \
58
goto bad; \
59
} while (0)
60
61
#define ceph_decode_64_safe(p, end, v, bad) \
62
do { \
63
ceph_decode_need(p, end, sizeof(u64), bad); \
64
v = ceph_decode_64(p); \
65
} while (0)
66
#define ceph_decode_32_safe(p, end, v, bad) \
67
do { \
68
ceph_decode_need(p, end, sizeof(u32), bad); \
69
v = ceph_decode_32(p); \
70
} while (0)
71
#define ceph_decode_16_safe(p, end, v, bad) \
72
do { \
73
ceph_decode_need(p, end, sizeof(u16), bad); \
74
v = ceph_decode_16(p); \
75
} while (0)
76
#define ceph_decode_8_safe(p, end, v, bad) \
77
do { \
78
ceph_decode_need(p, end, sizeof(u8), bad); \
79
v = ceph_decode_8(p); \
80
} while (0)
81
82
#define ceph_decode_copy_safe(p, end, pv, n, bad) \
83
do { \
84
ceph_decode_need(p, end, n, bad); \
85
ceph_decode_copy(p, pv, n); \
86
} while (0)
87
88
/*
89
* Allocate a buffer big enough to hold the wire-encoded string, and
90
* decode the string into it. The resulting string will always be
91
* terminated with '\0'. If successful, *p will be advanced
92
* past the decoded data. Also, if lenp is not a null pointer, the
93
* length (not including the terminating '\0') will be recorded in
94
* *lenp. Note that a zero-length string is a valid return value.
95
*
96
* Returns a pointer to the newly-allocated string buffer, or a
97
* pointer-coded errno if an error occurs. Neither *p nor *lenp
98
* will have been updated if an error is returned.
99
*
100
* There are two possible failures:
101
* - converting the string would require accessing memory at or
102
* beyond the "end" pointer provided (-E
103
* - memory could not be allocated for the result
104
*/
105
static
inline
char
*ceph_extract_encoded_string(
void
**
p
,
void
*
end
,
106
size_t
*lenp,
gfp_t
gfp)
107
{
108
u32
len
;
109
void
*
sp
= *
p
;
110
char
*
buf
;
111
112
ceph_decode_32_safe
(&sp, end, len,
bad
);
113
if
(!ceph_has_room(&sp, end, len))
114
goto
bad
;
115
116
buf =
kmalloc
(len + 1, gfp);
117
if
(!buf)
118
return
ERR_PTR(-
ENOMEM
);
119
120
if
(len)
121
memcpy
(buf, sp, len);
122
buf[len] =
'\0'
;
123
124
*p = (
char
*) *p +
sizeof
(
u32
) + len;
125
if
(lenp)
126
*lenp = (
size_t
) len;
127
128
return
buf
;
129
130
bad
:
131
return
ERR_PTR(-
ERANGE
);
132
}
133
134
/*
135
* struct ceph_timespec <-> struct timespec
136
*/
137
static
inline
void
ceph_decode_timespec(
struct
timespec
*
ts
,
138
const
struct
ceph_timespec
*tv)
139
{
140
ts->
tv_sec
=
le32_to_cpu
(tv->
tv_sec
);
141
ts->
tv_nsec
=
le32_to_cpu
(tv->
tv_nsec
);
142
}
143
static
inline
void
ceph_encode_timespec(
struct
ceph_timespec
*tv,
144
const
struct
timespec
*
ts
)
145
{
146
tv->
tv_sec
=
cpu_to_le32
(ts->
tv_sec
);
147
tv->
tv_nsec
=
cpu_to_le32
(ts->
tv_nsec
);
148
}
149
150
/*
151
* sockaddr_storage <-> ceph_sockaddr
152
*/
153
static
inline
void
ceph_encode_addr(
struct
ceph_entity_addr
*
a
)
154
{
155
__be16
ss_family
=
htons
(a->
in_addr
.ss_family);
156
a->
in_addr
.ss_family = *(
__u16
*)&ss_family;
157
}
158
static
inline
void
ceph_decode_addr(
struct
ceph_entity_addr
*
a
)
159
{
160
__be16
ss_family
= *(
__be16
*)&a->
in_addr
.ss_family;
161
a->
in_addr
.ss_family =
ntohs
(ss_family);
162
WARN_ON
(a->
in_addr
.ss_family == 512);
163
}
164
165
/*
166
* encoders
167
*/
168
static
inline
void
ceph_encode_64(
void
**
p
,
u64
v
)
169
{
170
put_unaligned_le64
(v, (
__le64
*)*p);
171
*p +=
sizeof
(
u64
);
172
}
173
static
inline
void
ceph_encode_32(
void
**p,
u32
v)
174
{
175
put_unaligned_le32
(v, (
__le32
*)*p);
176
*p +=
sizeof
(
u32
);
177
}
178
static
inline
void
ceph_encode_16(
void
**p,
u16
v)
179
{
180
put_unaligned_le16(v, (
__le16
*)*p);
181
*p +=
sizeof
(
u16
);
182
}
183
static
inline
void
ceph_encode_8(
void
**p,
u8
v)
184
{
185
*(
u8
*)*p = v;
186
(*p)++;
187
}
188
static
inline
void
ceph_encode_copy(
void
**p,
const
void
*
s
,
int
len)
189
{
190
memcpy
(*p, s, len);
191
*p += len;
192
}
193
194
/*
195
* filepath, string encoders
196
*/
197
static
inline
void
ceph_encode_filepath(
void
**p,
void
*
end
,
198
u64
ino
,
const
char
*
path
)
199
{
200
u32
len
= path ?
strlen
(path) : 0;
201
BUG_ON
(*p + 1 +
sizeof
(ino) +
sizeof
(len) + len > end);
202
ceph_encode_8(p, 1);
203
ceph_encode_64(p, ino);
204
ceph_encode_32(p, len);
205
if
(len)
206
memcpy
(*p, path, len);
207
*p += len;
208
}
209
210
static
inline
void
ceph_encode_string(
void
**p,
void
*end,
211
const
char
*
s
,
u32
len)
212
{
213
BUG_ON
(*p +
sizeof
(len) + len > end);
214
ceph_encode_32(p, len);
215
if
(len)
216
memcpy
(*p, s, len);
217
*p += len;
218
}
219
220
#define ceph_encode_need(p, end, n, bad) \
221
do { \
222
if (!likely(ceph_has_room(p, end, n))) \
223
goto bad; \
224
} while (0)
225
226
#define ceph_encode_64_safe(p, end, v, bad) \
227
do { \
228
ceph_encode_need(p, end, sizeof(u64), bad); \
229
ceph_encode_64(p, v); \
230
} while (0)
231
#define ceph_encode_32_safe(p, end, v, bad) \
232
do { \
233
ceph_encode_need(p, end, sizeof(u32), bad); \
234
ceph_encode_32(p, v); \
235
} while (0)
236
#define ceph_encode_16_safe(p, end, v, bad) \
237
do { \
238
ceph_encode_need(p, end, sizeof(u16), bad); \
239
ceph_encode_16(p, v); \
240
} while (0)
241
242
#define ceph_encode_copy_safe(p, end, pv, n, bad) \
243
do { \
244
ceph_encode_need(p, end, n, bad); \
245
ceph_encode_copy(p, pv, n); \
246
} while (0)
247
#define ceph_encode_string_safe(p, end, s, n, bad) \
248
do { \
249
ceph_encode_need(p, end, n, bad); \
250
ceph_encode_string(p, end, s, n); \
251
} while (0)
252
253
254
#endif
Generated on Thu Jan 10 2013 14:51:10 for Linux Kernel by
1.8.2