.. | .. |
---|
11 | 11 | #ifndef _SUNRPC_XDR_H_ |
---|
12 | 12 | #define _SUNRPC_XDR_H_ |
---|
13 | 13 | |
---|
14 | | -#ifdef __KERNEL__ |
---|
15 | | - |
---|
16 | 14 | #include <linux/uio.h> |
---|
17 | 15 | #include <asm/byteorder.h> |
---|
18 | 16 | #include <asm/unaligned.h> |
---|
19 | 17 | #include <linux/scatterlist.h> |
---|
20 | 18 | |
---|
| 19 | +struct bio_vec; |
---|
21 | 20 | struct rpc_rqst; |
---|
22 | 21 | |
---|
23 | 22 | /* |
---|
.. | .. |
---|
51 | 50 | struct kvec head[1], /* RPC header + non-page data */ |
---|
52 | 51 | tail[1]; /* Appended after page data */ |
---|
53 | 52 | |
---|
| 53 | + struct bio_vec *bvec; |
---|
54 | 54 | struct page ** pages; /* Array of pages */ |
---|
55 | 55 | unsigned int page_base, /* Start of page data */ |
---|
56 | 56 | page_len, /* Length of page data */ |
---|
57 | 57 | flags; /* Flags for data disposition */ |
---|
58 | 58 | #define XDRBUF_READ 0x01 /* target of file read */ |
---|
59 | 59 | #define XDRBUF_WRITE 0x02 /* source of file write */ |
---|
| 60 | +#define XDRBUF_SPARSE_PAGES 0x04 /* Page array is sparse */ |
---|
60 | 61 | |
---|
61 | 62 | unsigned int buflen, /* Total length of storage buffer */ |
---|
62 | 63 | len; /* Length of XDR encoded message */ |
---|
.. | .. |
---|
68 | 69 | buf->head[0].iov_base = start; |
---|
69 | 70 | buf->head[0].iov_len = len; |
---|
70 | 71 | buf->tail[0].iov_len = 0; |
---|
| 72 | + buf->pages = NULL; |
---|
71 | 73 | buf->page_len = 0; |
---|
72 | 74 | buf->flags = 0; |
---|
73 | 75 | buf->len = 0; |
---|
.. | .. |
---|
82 | 84 | #define xdr_one cpu_to_be32(1) |
---|
83 | 85 | #define xdr_two cpu_to_be32(2) |
---|
84 | 86 | |
---|
| 87 | +#define rpc_auth_null cpu_to_be32(RPC_AUTH_NULL) |
---|
| 88 | +#define rpc_auth_unix cpu_to_be32(RPC_AUTH_UNIX) |
---|
| 89 | +#define rpc_auth_short cpu_to_be32(RPC_AUTH_SHORT) |
---|
| 90 | +#define rpc_auth_gss cpu_to_be32(RPC_AUTH_GSS) |
---|
| 91 | + |
---|
| 92 | +#define rpc_call cpu_to_be32(RPC_CALL) |
---|
| 93 | +#define rpc_reply cpu_to_be32(RPC_REPLY) |
---|
| 94 | + |
---|
| 95 | +#define rpc_msg_accepted cpu_to_be32(RPC_MSG_ACCEPTED) |
---|
| 96 | + |
---|
85 | 97 | #define rpc_success cpu_to_be32(RPC_SUCCESS) |
---|
86 | 98 | #define rpc_prog_unavail cpu_to_be32(RPC_PROG_UNAVAIL) |
---|
87 | 99 | #define rpc_prog_mismatch cpu_to_be32(RPC_PROG_MISMATCH) |
---|
.. | .. |
---|
89 | 101 | #define rpc_garbage_args cpu_to_be32(RPC_GARBAGE_ARGS) |
---|
90 | 102 | #define rpc_system_err cpu_to_be32(RPC_SYSTEM_ERR) |
---|
91 | 103 | #define rpc_drop_reply cpu_to_be32(RPC_DROP_REPLY) |
---|
| 104 | + |
---|
| 105 | +#define rpc_mismatch cpu_to_be32(RPC_MISMATCH) |
---|
| 106 | +#define rpc_auth_error cpu_to_be32(RPC_AUTH_ERROR) |
---|
92 | 107 | |
---|
93 | 108 | #define rpc_auth_ok cpu_to_be32(RPC_AUTH_OK) |
---|
94 | 109 | #define rpc_autherr_badcred cpu_to_be32(RPC_AUTH_BADCRED) |
---|
.. | .. |
---|
98 | 113 | #define rpc_autherr_tooweak cpu_to_be32(RPC_AUTH_TOOWEAK) |
---|
99 | 114 | #define rpcsec_gsserr_credproblem cpu_to_be32(RPCSEC_GSS_CREDPROBLEM) |
---|
100 | 115 | #define rpcsec_gsserr_ctxproblem cpu_to_be32(RPCSEC_GSS_CTXPROBLEM) |
---|
101 | | -#define rpc_autherr_oldseqnum cpu_to_be32(101) |
---|
102 | 116 | |
---|
103 | 117 | /* |
---|
104 | 118 | * Miscellaneous XDR helper functions |
---|
.. | .. |
---|
114 | 128 | void xdr_inline_pages(struct xdr_buf *, unsigned int, |
---|
115 | 129 | struct page **, unsigned int, unsigned int); |
---|
116 | 130 | void xdr_terminate_string(struct xdr_buf *, const u32); |
---|
| 131 | +size_t xdr_buf_pagecount(struct xdr_buf *buf); |
---|
| 132 | +int xdr_alloc_bvec(struct xdr_buf *buf, gfp_t gfp); |
---|
| 133 | +void xdr_free_bvec(struct xdr_buf *buf); |
---|
117 | 134 | |
---|
118 | 135 | static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len) |
---|
119 | 136 | { |
---|
.. | .. |
---|
144 | 161 | return p + XDR_QUADLEN(len); |
---|
145 | 162 | } |
---|
146 | 163 | |
---|
| 164 | +static inline void xdr_netobj_dup(struct xdr_netobj *dst, |
---|
| 165 | + struct xdr_netobj *src, gfp_t gfp_mask) |
---|
| 166 | +{ |
---|
| 167 | + dst->data = kmemdup(src->data, src->len, gfp_mask); |
---|
| 168 | + dst->len = src->len; |
---|
| 169 | +} |
---|
| 170 | + |
---|
147 | 171 | /* |
---|
148 | 172 | * Adjust kvec to reflect end of xdr'ed data (RPC client XDR) |
---|
149 | 173 | */ |
---|
.. | .. |
---|
160 | 184 | extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *); |
---|
161 | 185 | extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int); |
---|
162 | 186 | extern void xdr_buf_trim(struct xdr_buf *, unsigned int); |
---|
163 | | -extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, unsigned int); |
---|
164 | 187 | extern int read_bytes_from_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int); |
---|
165 | 188 | extern int write_bytes_to_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int); |
---|
166 | | - |
---|
167 | | -/* |
---|
168 | | - * Helper structure for copying from an sk_buff. |
---|
169 | | - */ |
---|
170 | | -struct xdr_skb_reader { |
---|
171 | | - struct sk_buff *skb; |
---|
172 | | - unsigned int offset; |
---|
173 | | - size_t count; |
---|
174 | | - __wsum csum; |
---|
175 | | -}; |
---|
176 | | - |
---|
177 | | -typedef size_t (*xdr_skb_read_actor)(struct xdr_skb_reader *desc, void *to, size_t len); |
---|
178 | | - |
---|
179 | | -size_t xdr_skb_read_bits(struct xdr_skb_reader *desc, void *to, size_t len); |
---|
180 | | -extern int csum_partial_copy_to_xdr(struct xdr_buf *, struct sk_buff *); |
---|
181 | | -extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int, |
---|
182 | | - struct xdr_skb_reader *, xdr_skb_read_actor); |
---|
183 | 189 | |
---|
184 | 190 | extern int xdr_encode_word(struct xdr_buf *, unsigned int, u32); |
---|
185 | 191 | extern int xdr_decode_word(struct xdr_buf *, unsigned int, u32 *); |
---|
.. | .. |
---|
212 | 218 | struct kvec scratch; /* Scratch buffer */ |
---|
213 | 219 | struct page **page_ptr; /* pointer to the current page */ |
---|
214 | 220 | unsigned int nwords; /* Remaining decode buffer length */ |
---|
| 221 | + |
---|
| 222 | + struct rpc_rqst *rqst; /* For debugging */ |
---|
215 | 223 | }; |
---|
216 | 224 | |
---|
217 | 225 | /* |
---|
.. | .. |
---|
222 | 230 | typedef int (*kxdrdproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr, |
---|
223 | 231 | void *obj); |
---|
224 | 232 | |
---|
225 | | -extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); |
---|
| 233 | +extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, |
---|
| 234 | + __be32 *p, struct rpc_rqst *rqst); |
---|
226 | 235 | extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); |
---|
| 236 | +extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec, |
---|
| 237 | + size_t nbytes); |
---|
227 | 238 | extern void xdr_commit_encode(struct xdr_stream *xdr); |
---|
228 | 239 | extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len); |
---|
229 | 240 | extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen); |
---|
230 | 241 | extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, |
---|
231 | 242 | unsigned int base, unsigned int len); |
---|
232 | 243 | extern unsigned int xdr_stream_pos(const struct xdr_stream *xdr); |
---|
233 | | -extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); |
---|
| 244 | +extern unsigned int xdr_page_pos(const struct xdr_stream *xdr); |
---|
| 245 | +extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, |
---|
| 246 | + __be32 *p, struct rpc_rqst *rqst); |
---|
234 | 247 | extern void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, |
---|
235 | 248 | struct page **pages, unsigned int len); |
---|
236 | 249 | extern void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen); |
---|
.. | .. |
---|
238 | 251 | extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len); |
---|
239 | 252 | extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len); |
---|
240 | 253 | extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data); |
---|
| 254 | +extern uint64_t xdr_align_data(struct xdr_stream *, uint64_t, uint32_t); |
---|
| 255 | +extern uint64_t xdr_expand_hole(struct xdr_stream *, uint64_t, uint64_t); |
---|
241 | 256 | |
---|
242 | 257 | /** |
---|
243 | 258 | * xdr_stream_remaining - Return the number of bytes remaining in the stream |
---|
.. | .. |
---|
273 | 288 | const size_t mask = sizeof(__u32) - 1; |
---|
274 | 289 | |
---|
275 | 290 | return (n + mask) & ~mask; |
---|
| 291 | +} |
---|
| 292 | + |
---|
| 293 | +/** |
---|
| 294 | + * xdr_pad_size - Calculate size of an object's pad |
---|
| 295 | + * @n: Size of an object being XDR encoded (in bytes) |
---|
| 296 | + * |
---|
| 297 | + * This implementation avoids the need for conditional |
---|
| 298 | + * branches or modulo division. |
---|
| 299 | + * |
---|
| 300 | + * Return value: |
---|
| 301 | + * Size (in bytes) of the needed XDR pad |
---|
| 302 | + */ |
---|
| 303 | +static inline size_t xdr_pad_size(size_t n) |
---|
| 304 | +{ |
---|
| 305 | + return xdr_align_size(n) - n; |
---|
| 306 | +} |
---|
| 307 | + |
---|
| 308 | +/** |
---|
| 309 | + * xdr_stream_encode_item_present - Encode a "present" list item |
---|
| 310 | + * @xdr: pointer to xdr_stream |
---|
| 311 | + * |
---|
| 312 | + * Return values: |
---|
| 313 | + * On success, returns length in bytes of XDR buffer consumed |
---|
| 314 | + * %-EMSGSIZE on XDR buffer overflow |
---|
| 315 | + */ |
---|
| 316 | +static inline ssize_t xdr_stream_encode_item_present(struct xdr_stream *xdr) |
---|
| 317 | +{ |
---|
| 318 | + const size_t len = sizeof(__be32); |
---|
| 319 | + __be32 *p = xdr_reserve_space(xdr, len); |
---|
| 320 | + |
---|
| 321 | + if (unlikely(!p)) |
---|
| 322 | + return -EMSGSIZE; |
---|
| 323 | + *p = xdr_one; |
---|
| 324 | + return len; |
---|
| 325 | +} |
---|
| 326 | + |
---|
| 327 | +/** |
---|
| 328 | + * xdr_stream_encode_item_absent - Encode a "not present" list item |
---|
| 329 | + * @xdr: pointer to xdr_stream |
---|
| 330 | + * |
---|
| 331 | + * Return values: |
---|
| 332 | + * On success, returns length in bytes of XDR buffer consumed |
---|
| 333 | + * %-EMSGSIZE on XDR buffer overflow |
---|
| 334 | + */ |
---|
| 335 | +static inline int xdr_stream_encode_item_absent(struct xdr_stream *xdr) |
---|
| 336 | +{ |
---|
| 337 | + const size_t len = sizeof(__be32); |
---|
| 338 | + __be32 *p = xdr_reserve_space(xdr, len); |
---|
| 339 | + |
---|
| 340 | + if (unlikely(!p)) |
---|
| 341 | + return -EMSGSIZE; |
---|
| 342 | + *p = xdr_zero; |
---|
| 343 | + return len; |
---|
276 | 344 | } |
---|
277 | 345 | |
---|
278 | 346 | /** |
---|
.. | .. |
---|
411 | 479 | } |
---|
412 | 480 | |
---|
413 | 481 | /** |
---|
| 482 | + * xdr_item_is_absent - symbolically handle XDR discriminators |
---|
| 483 | + * @p: pointer to undecoded discriminator |
---|
| 484 | + * |
---|
| 485 | + * Return values: |
---|
| 486 | + * %true if the following XDR item is absent |
---|
| 487 | + * %false if the following XDR item is present |
---|
| 488 | + */ |
---|
| 489 | +static inline bool xdr_item_is_absent(const __be32 *p) |
---|
| 490 | +{ |
---|
| 491 | + return *p == xdr_zero; |
---|
| 492 | +} |
---|
| 493 | + |
---|
| 494 | +/** |
---|
| 495 | + * xdr_item_is_present - symbolically handle XDR discriminators |
---|
| 496 | + * @p: pointer to undecoded discriminator |
---|
| 497 | + * |
---|
| 498 | + * Return values: |
---|
| 499 | + * %true if the following XDR item is present |
---|
| 500 | + * %false if the following XDR item is absent |
---|
| 501 | + */ |
---|
| 502 | +static inline bool xdr_item_is_present(const __be32 *p) |
---|
| 503 | +{ |
---|
| 504 | + return *p != xdr_zero; |
---|
| 505 | +} |
---|
| 506 | + |
---|
| 507 | +/** |
---|
414 | 508 | * xdr_stream_decode_u32 - Decode a 32-bit integer |
---|
415 | 509 | * @xdr: pointer to xdr_stream |
---|
416 | 510 | * @ptr: location to store integer |
---|
.. | .. |
---|
509 | 603 | |
---|
510 | 604 | if (unlikely(xdr_stream_decode_u32(xdr, &len) < 0)) |
---|
511 | 605 | return -EBADMSG; |
---|
| 606 | + if (len > SIZE_MAX / sizeof(*p)) |
---|
| 607 | + return -EBADMSG; |
---|
512 | 608 | p = xdr_inline_decode(xdr, len * sizeof(*p)); |
---|
513 | 609 | if (unlikely(!p)) |
---|
514 | 610 | return -EBADMSG; |
---|
.. | .. |
---|
525 | 621 | *array = be32_to_cpup(p); |
---|
526 | 622 | return retval; |
---|
527 | 623 | } |
---|
528 | | -#endif /* __KERNEL__ */ |
---|
529 | 624 | |
---|
530 | 625 | #endif /* _SUNRPC_XDR_H_ */ |
---|