xdr.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * XDR standard data types and function declarations
  4. *
  5. * Copyright (C) 1995-1997 Olaf Kirch <[email protected]>
  6. *
  7. * Based on:
  8. * RFC 4506 "XDR: External Data Representation Standard", May 2006
  9. */
  10. #ifndef _SUNRPC_XDR_H_
  11. #define _SUNRPC_XDR_H_
  12. #include <linux/uio.h>
  13. #include <asm/byteorder.h>
  14. #include <asm/unaligned.h>
  15. #include <linux/scatterlist.h>
  16. struct bio_vec;
  17. struct rpc_rqst;
  18. /*
  19. * Size of an XDR encoding unit in bytes, i.e. 32 bits,
  20. * as defined in Section 3 of RFC 4506. All encoded
  21. * XDR data items are aligned on a boundary of 32 bits.
  22. */
  23. #define XDR_UNIT sizeof(__be32)
  24. /*
  25. * Buffer adjustment
  26. */
  27. #define XDR_QUADLEN(l) (((l) + 3) >> 2)
  28. /*
  29. * Generic opaque `network object.'
  30. */
  31. #define XDR_MAX_NETOBJ 1024
  32. struct xdr_netobj {
  33. unsigned int len;
  34. u8 * data;
  35. };
  36. /*
  37. * Basic structure for transmission/reception of a client XDR message.
  38. * Features a header (for a linear buffer containing RPC headers
  39. * and the data payload for short messages), and then an array of
  40. * pages.
  41. * The tail iovec allows you to append data after the page array. Its
  42. * main interest is for appending padding to the pages in order to
  43. * satisfy the int_32-alignment requirements in RFC1832.
  44. *
  45. * For the future, we might want to string several of these together
  46. * in a list if anybody wants to make use of NFSv4 COMPOUND
  47. * operations and/or has a need for scatter/gather involving pages.
  48. */
  49. struct xdr_buf {
  50. struct kvec head[1], /* RPC header + non-page data */
  51. tail[1]; /* Appended after page data */
  52. struct bio_vec *bvec;
  53. struct page ** pages; /* Array of pages */
  54. unsigned int page_base, /* Start of page data */
  55. page_len, /* Length of page data */
  56. flags; /* Flags for data disposition */
  57. #define XDRBUF_READ 0x01 /* target of file read */
  58. #define XDRBUF_WRITE 0x02 /* source of file write */
  59. #define XDRBUF_SPARSE_PAGES 0x04 /* Page array is sparse */
  60. unsigned int buflen, /* Total length of storage buffer */
  61. len; /* Length of XDR encoded message */
  62. };
  63. static inline void
  64. xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
  65. {
  66. buf->head[0].iov_base = start;
  67. buf->head[0].iov_len = len;
  68. buf->tail[0].iov_len = 0;
  69. buf->pages = NULL;
  70. buf->page_len = 0;
  71. buf->flags = 0;
  72. buf->len = 0;
  73. buf->buflen = len;
  74. }
  75. /*
  76. * pre-xdr'ed macros.
  77. */
  78. #define xdr_zero cpu_to_be32(0)
  79. #define xdr_one cpu_to_be32(1)
  80. #define xdr_two cpu_to_be32(2)
  81. #define rpc_auth_null cpu_to_be32(RPC_AUTH_NULL)
  82. #define rpc_auth_unix cpu_to_be32(RPC_AUTH_UNIX)
  83. #define rpc_auth_short cpu_to_be32(RPC_AUTH_SHORT)
  84. #define rpc_auth_gss cpu_to_be32(RPC_AUTH_GSS)
  85. #define rpc_auth_tls cpu_to_be32(RPC_AUTH_TLS)
  86. #define rpc_call cpu_to_be32(RPC_CALL)
  87. #define rpc_reply cpu_to_be32(RPC_REPLY)
  88. #define rpc_msg_accepted cpu_to_be32(RPC_MSG_ACCEPTED)
  89. #define rpc_success cpu_to_be32(RPC_SUCCESS)
  90. #define rpc_prog_unavail cpu_to_be32(RPC_PROG_UNAVAIL)
  91. #define rpc_prog_mismatch cpu_to_be32(RPC_PROG_MISMATCH)
  92. #define rpc_proc_unavail cpu_to_be32(RPC_PROC_UNAVAIL)
  93. #define rpc_garbage_args cpu_to_be32(RPC_GARBAGE_ARGS)
  94. #define rpc_system_err cpu_to_be32(RPC_SYSTEM_ERR)
  95. #define rpc_drop_reply cpu_to_be32(RPC_DROP_REPLY)
  96. #define rpc_mismatch cpu_to_be32(RPC_MISMATCH)
  97. #define rpc_auth_error cpu_to_be32(RPC_AUTH_ERROR)
  98. #define rpc_auth_ok cpu_to_be32(RPC_AUTH_OK)
  99. #define rpc_autherr_badcred cpu_to_be32(RPC_AUTH_BADCRED)
  100. #define rpc_autherr_rejectedcred cpu_to_be32(RPC_AUTH_REJECTEDCRED)
  101. #define rpc_autherr_badverf cpu_to_be32(RPC_AUTH_BADVERF)
  102. #define rpc_autherr_rejectedverf cpu_to_be32(RPC_AUTH_REJECTEDVERF)
  103. #define rpc_autherr_tooweak cpu_to_be32(RPC_AUTH_TOOWEAK)
  104. #define rpcsec_gsserr_credproblem cpu_to_be32(RPCSEC_GSS_CREDPROBLEM)
  105. #define rpcsec_gsserr_ctxproblem cpu_to_be32(RPCSEC_GSS_CTXPROBLEM)
  106. /*
  107. * Miscellaneous XDR helper functions
  108. */
  109. __be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int len);
  110. __be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int len);
  111. __be32 *xdr_encode_string(__be32 *p, const char *s);
  112. __be32 *xdr_decode_string_inplace(__be32 *p, char **sp, unsigned int *lenp,
  113. unsigned int maxlen);
  114. __be32 *xdr_encode_netobj(__be32 *p, const struct xdr_netobj *);
  115. __be32 *xdr_decode_netobj(__be32 *p, struct xdr_netobj *);
  116. void xdr_inline_pages(struct xdr_buf *, unsigned int,
  117. struct page **, unsigned int, unsigned int);
  118. void xdr_terminate_string(const struct xdr_buf *, const u32);
  119. size_t xdr_buf_pagecount(const struct xdr_buf *buf);
  120. int xdr_alloc_bvec(struct xdr_buf *buf, gfp_t gfp);
  121. void xdr_free_bvec(struct xdr_buf *buf);
  122. static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len)
  123. {
  124. return xdr_encode_opaque(p, s, len);
  125. }
  126. /*
  127. * Decode 64bit quantities (NFSv3 support)
  128. */
  129. static inline __be32 *
  130. xdr_encode_hyper(__be32 *p, __u64 val)
  131. {
  132. put_unaligned_be64(val, p);
  133. return p + 2;
  134. }
  135. static inline __be32 *
  136. xdr_decode_hyper(__be32 *p, __u64 *valp)
  137. {
  138. *valp = get_unaligned_be64(p);
  139. return p + 2;
  140. }
  141. static inline __be32 *
  142. xdr_decode_opaque_fixed(__be32 *p, void *ptr, unsigned int len)
  143. {
  144. memcpy(ptr, p, len);
  145. return p + XDR_QUADLEN(len);
  146. }
  147. static inline void xdr_netobj_dup(struct xdr_netobj *dst,
  148. struct xdr_netobj *src, gfp_t gfp_mask)
  149. {
  150. dst->data = kmemdup(src->data, src->len, gfp_mask);
  151. dst->len = src->len;
  152. }
  153. /*
  154. * Adjust kvec to reflect end of xdr'ed data (RPC client XDR)
  155. */
  156. static inline int
  157. xdr_adjust_iovec(struct kvec *iov, __be32 *p)
  158. {
  159. return iov->iov_len = ((u8 *) p - (u8 *) iov->iov_base);
  160. }
  161. /*
  162. * XDR buffer helper functions
  163. */
  164. extern void xdr_shift_buf(struct xdr_buf *, size_t);
  165. extern void xdr_buf_from_iov(const struct kvec *, struct xdr_buf *);
  166. extern int xdr_buf_subsegment(const struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int);
  167. extern void xdr_buf_trim(struct xdr_buf *, unsigned int);
  168. extern int read_bytes_from_xdr_buf(const struct xdr_buf *, unsigned int, void *, unsigned int);
  169. extern int write_bytes_to_xdr_buf(const struct xdr_buf *, unsigned int, void *, unsigned int);
  170. extern int xdr_encode_word(const struct xdr_buf *, unsigned int, u32);
  171. extern int xdr_decode_word(const struct xdr_buf *, unsigned int, u32 *);
  172. struct xdr_array2_desc;
  173. typedef int (*xdr_xcode_elem_t)(struct xdr_array2_desc *desc, void *elem);
  174. struct xdr_array2_desc {
  175. unsigned int elem_size;
  176. unsigned int array_len;
  177. unsigned int array_maxlen;
  178. xdr_xcode_elem_t xcode;
  179. };
  180. extern int xdr_decode_array2(const struct xdr_buf *buf, unsigned int base,
  181. struct xdr_array2_desc *desc);
  182. extern int xdr_encode_array2(const struct xdr_buf *buf, unsigned int base,
  183. struct xdr_array2_desc *desc);
  184. extern void _copy_from_pages(char *p, struct page **pages, size_t pgbase,
  185. size_t len);
  186. /*
  187. * Provide some simple tools for XDR buffer overflow-checking etc.
  188. */
  189. struct xdr_stream {
  190. __be32 *p; /* start of available buffer */
  191. struct xdr_buf *buf; /* XDR buffer to read/write */
  192. __be32 *end; /* end of available buffer space */
  193. struct kvec *iov; /* pointer to the current kvec */
  194. struct kvec scratch; /* Scratch buffer */
  195. struct page **page_ptr; /* pointer to the current page */
  196. unsigned int nwords; /* Remaining decode buffer length */
  197. struct rpc_rqst *rqst; /* For debugging */
  198. };
  199. /*
  200. * These are the xdr_stream style generic XDR encode and decode functions.
  201. */
  202. typedef void (*kxdreproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  203. const void *obj);
  204. typedef int (*kxdrdproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  205. void *obj);
  206. extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf,
  207. __be32 *p, struct rpc_rqst *rqst);
  208. extern void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf,
  209. struct page **pages, struct rpc_rqst *rqst);
  210. extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
  211. extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec,
  212. size_t nbytes);
  213. extern void __xdr_commit_encode(struct xdr_stream *xdr);
  214. extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len);
  215. extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen);
  216. extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
  217. unsigned int base, unsigned int len);
  218. extern unsigned int xdr_stream_pos(const struct xdr_stream *xdr);
  219. extern unsigned int xdr_page_pos(const struct xdr_stream *xdr);
  220. extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf,
  221. __be32 *p, struct rpc_rqst *rqst);
  222. extern void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf,
  223. struct page **pages, unsigned int len);
  224. extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
  225. extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
  226. extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
  227. extern int xdr_process_buf(const struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data);
  228. extern void xdr_set_pagelen(struct xdr_stream *, unsigned int len);
  229. extern bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf,
  230. unsigned int len);
  231. extern unsigned int xdr_stream_move_subsegment(struct xdr_stream *xdr, unsigned int offset,
  232. unsigned int target, unsigned int length);
  233. extern unsigned int xdr_stream_zero(struct xdr_stream *xdr, unsigned int offset,
  234. unsigned int length);
  235. /**
  236. * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
  237. * @xdr: pointer to xdr_stream struct
  238. * @buf: pointer to an empty buffer
  239. * @buflen: size of 'buf'
  240. *
  241. * The scratch buffer is used when decoding from an array of pages.
  242. * If an xdr_inline_decode() call spans across page boundaries, then
  243. * we copy the data into the scratch buffer in order to allow linear
  244. * access.
  245. */
  246. static inline void
  247. xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen)
  248. {
  249. xdr->scratch.iov_base = buf;
  250. xdr->scratch.iov_len = buflen;
  251. }
  252. /**
  253. * xdr_set_scratch_page - Attach a scratch buffer for decoding data
  254. * @xdr: pointer to xdr_stream struct
  255. * @page: an anonymous page
  256. *
  257. * See xdr_set_scratch_buffer().
  258. */
  259. static inline void
  260. xdr_set_scratch_page(struct xdr_stream *xdr, struct page *page)
  261. {
  262. xdr_set_scratch_buffer(xdr, page_address(page), PAGE_SIZE);
  263. }
  264. /**
  265. * xdr_reset_scratch_buffer - Clear scratch buffer information
  266. * @xdr: pointer to xdr_stream struct
  267. *
  268. * See xdr_set_scratch_buffer().
  269. */
  270. static inline void
  271. xdr_reset_scratch_buffer(struct xdr_stream *xdr)
  272. {
  273. xdr_set_scratch_buffer(xdr, NULL, 0);
  274. }
  275. /**
  276. * xdr_commit_encode - Ensure all data is written to xdr->buf
  277. * @xdr: pointer to xdr_stream
  278. *
  279. * Handle encoding across page boundaries by giving the caller a
  280. * temporary location to write to, then later copying the data into
  281. * place. __xdr_commit_encode() does that copying.
  282. */
  283. static inline void xdr_commit_encode(struct xdr_stream *xdr)
  284. {
  285. if (unlikely(xdr->scratch.iov_len))
  286. __xdr_commit_encode(xdr);
  287. }
  288. /**
  289. * xdr_stream_remaining - Return the number of bytes remaining in the stream
  290. * @xdr: pointer to struct xdr_stream
  291. *
  292. * Return value:
  293. * Number of bytes remaining in @xdr before xdr->end
  294. */
  295. static inline size_t
  296. xdr_stream_remaining(const struct xdr_stream *xdr)
  297. {
  298. return xdr->nwords << 2;
  299. }
  300. ssize_t xdr_stream_decode_opaque(struct xdr_stream *xdr, void *ptr,
  301. size_t size);
  302. ssize_t xdr_stream_decode_opaque_dup(struct xdr_stream *xdr, void **ptr,
  303. size_t maxlen, gfp_t gfp_flags);
  304. ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str,
  305. size_t size);
  306. ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
  307. size_t maxlen, gfp_t gfp_flags);
  308. /**
  309. * xdr_align_size - Calculate padded size of an object
  310. * @n: Size of an object being XDR encoded (in bytes)
  311. *
  312. * Return value:
  313. * Size (in bytes) of the object including xdr padding
  314. */
  315. static inline size_t
  316. xdr_align_size(size_t n)
  317. {
  318. const size_t mask = XDR_UNIT - 1;
  319. return (n + mask) & ~mask;
  320. }
  321. /**
  322. * xdr_pad_size - Calculate size of an object's pad
  323. * @n: Size of an object being XDR encoded (in bytes)
  324. *
  325. * This implementation avoids the need for conditional
  326. * branches or modulo division.
  327. *
  328. * Return value:
  329. * Size (in bytes) of the needed XDR pad
  330. */
  331. static inline size_t xdr_pad_size(size_t n)
  332. {
  333. return xdr_align_size(n) - n;
  334. }
  335. /**
  336. * xdr_stream_encode_item_present - Encode a "present" list item
  337. * @xdr: pointer to xdr_stream
  338. *
  339. * Return values:
  340. * On success, returns length in bytes of XDR buffer consumed
  341. * %-EMSGSIZE on XDR buffer overflow
  342. */
  343. static inline ssize_t xdr_stream_encode_item_present(struct xdr_stream *xdr)
  344. {
  345. const size_t len = XDR_UNIT;
  346. __be32 *p = xdr_reserve_space(xdr, len);
  347. if (unlikely(!p))
  348. return -EMSGSIZE;
  349. *p = xdr_one;
  350. return len;
  351. }
  352. /**
  353. * xdr_stream_encode_item_absent - Encode a "not present" list item
  354. * @xdr: pointer to xdr_stream
  355. *
  356. * Return values:
  357. * On success, returns length in bytes of XDR buffer consumed
  358. * %-EMSGSIZE on XDR buffer overflow
  359. */
  360. static inline int xdr_stream_encode_item_absent(struct xdr_stream *xdr)
  361. {
  362. const size_t len = XDR_UNIT;
  363. __be32 *p = xdr_reserve_space(xdr, len);
  364. if (unlikely(!p))
  365. return -EMSGSIZE;
  366. *p = xdr_zero;
  367. return len;
  368. }
  369. /**
  370. * xdr_encode_bool - Encode a boolean item
  371. * @p: address in a buffer into which to encode
  372. * @n: boolean value to encode
  373. *
  374. * Return value:
  375. * Address of item following the encoded boolean
  376. */
  377. static inline __be32 *xdr_encode_bool(__be32 *p, u32 n)
  378. {
  379. *p++ = n ? xdr_one : xdr_zero;
  380. return p;
  381. }
  382. /**
  383. * xdr_stream_encode_bool - Encode a boolean item
  384. * @xdr: pointer to xdr_stream
  385. * @n: boolean value to encode
  386. *
  387. * Return values:
  388. * On success, returns length in bytes of XDR buffer consumed
  389. * %-EMSGSIZE on XDR buffer overflow
  390. */
  391. static inline int xdr_stream_encode_bool(struct xdr_stream *xdr, __u32 n)
  392. {
  393. const size_t len = XDR_UNIT;
  394. __be32 *p = xdr_reserve_space(xdr, len);
  395. if (unlikely(!p))
  396. return -EMSGSIZE;
  397. xdr_encode_bool(p, n);
  398. return len;
  399. }
  400. /**
  401. * xdr_stream_encode_u32 - Encode a 32-bit integer
  402. * @xdr: pointer to xdr_stream
  403. * @n: integer to encode
  404. *
  405. * Return values:
  406. * On success, returns length in bytes of XDR buffer consumed
  407. * %-EMSGSIZE on XDR buffer overflow
  408. */
  409. static inline ssize_t
  410. xdr_stream_encode_u32(struct xdr_stream *xdr, __u32 n)
  411. {
  412. const size_t len = sizeof(n);
  413. __be32 *p = xdr_reserve_space(xdr, len);
  414. if (unlikely(!p))
  415. return -EMSGSIZE;
  416. *p = cpu_to_be32(n);
  417. return len;
  418. }
  419. /**
  420. * xdr_stream_encode_u64 - Encode a 64-bit integer
  421. * @xdr: pointer to xdr_stream
  422. * @n: 64-bit integer to encode
  423. *
  424. * Return values:
  425. * On success, returns length in bytes of XDR buffer consumed
  426. * %-EMSGSIZE on XDR buffer overflow
  427. */
  428. static inline ssize_t
  429. xdr_stream_encode_u64(struct xdr_stream *xdr, __u64 n)
  430. {
  431. const size_t len = sizeof(n);
  432. __be32 *p = xdr_reserve_space(xdr, len);
  433. if (unlikely(!p))
  434. return -EMSGSIZE;
  435. xdr_encode_hyper(p, n);
  436. return len;
  437. }
  438. /**
  439. * xdr_stream_encode_opaque_inline - Encode opaque xdr data
  440. * @xdr: pointer to xdr_stream
  441. * @ptr: pointer to void pointer
  442. * @len: size of object
  443. *
  444. * Return values:
  445. * On success, returns length in bytes of XDR buffer consumed
  446. * %-EMSGSIZE on XDR buffer overflow
  447. */
  448. static inline ssize_t
  449. xdr_stream_encode_opaque_inline(struct xdr_stream *xdr, void **ptr, size_t len)
  450. {
  451. size_t count = sizeof(__u32) + xdr_align_size(len);
  452. __be32 *p = xdr_reserve_space(xdr, count);
  453. if (unlikely(!p)) {
  454. *ptr = NULL;
  455. return -EMSGSIZE;
  456. }
  457. xdr_encode_opaque(p, NULL, len);
  458. *ptr = ++p;
  459. return count;
  460. }
  461. /**
  462. * xdr_stream_encode_opaque_fixed - Encode fixed length opaque xdr data
  463. * @xdr: pointer to xdr_stream
  464. * @ptr: pointer to opaque data object
  465. * @len: size of object pointed to by @ptr
  466. *
  467. * Return values:
  468. * On success, returns length in bytes of XDR buffer consumed
  469. * %-EMSGSIZE on XDR buffer overflow
  470. */
  471. static inline ssize_t
  472. xdr_stream_encode_opaque_fixed(struct xdr_stream *xdr, const void *ptr, size_t len)
  473. {
  474. __be32 *p = xdr_reserve_space(xdr, len);
  475. if (unlikely(!p))
  476. return -EMSGSIZE;
  477. xdr_encode_opaque_fixed(p, ptr, len);
  478. return xdr_align_size(len);
  479. }
  480. /**
  481. * xdr_stream_encode_opaque - Encode variable length opaque xdr data
  482. * @xdr: pointer to xdr_stream
  483. * @ptr: pointer to opaque data object
  484. * @len: size of object pointed to by @ptr
  485. *
  486. * Return values:
  487. * On success, returns length in bytes of XDR buffer consumed
  488. * %-EMSGSIZE on XDR buffer overflow
  489. */
  490. static inline ssize_t
  491. xdr_stream_encode_opaque(struct xdr_stream *xdr, const void *ptr, size_t len)
  492. {
  493. size_t count = sizeof(__u32) + xdr_align_size(len);
  494. __be32 *p = xdr_reserve_space(xdr, count);
  495. if (unlikely(!p))
  496. return -EMSGSIZE;
  497. xdr_encode_opaque(p, ptr, len);
  498. return count;
  499. }
  500. /**
  501. * xdr_stream_encode_uint32_array - Encode variable length array of integers
  502. * @xdr: pointer to xdr_stream
  503. * @array: array of integers
  504. * @array_size: number of elements in @array
  505. *
  506. * Return values:
  507. * On success, returns length in bytes of XDR buffer consumed
  508. * %-EMSGSIZE on XDR buffer overflow
  509. */
  510. static inline ssize_t
  511. xdr_stream_encode_uint32_array(struct xdr_stream *xdr,
  512. const __u32 *array, size_t array_size)
  513. {
  514. ssize_t ret = (array_size+1) * sizeof(__u32);
  515. __be32 *p = xdr_reserve_space(xdr, ret);
  516. if (unlikely(!p))
  517. return -EMSGSIZE;
  518. *p++ = cpu_to_be32(array_size);
  519. for (; array_size > 0; p++, array++, array_size--)
  520. *p = cpu_to_be32p(array);
  521. return ret;
  522. }
  523. /**
  524. * xdr_item_is_absent - symbolically handle XDR discriminators
  525. * @p: pointer to undecoded discriminator
  526. *
  527. * Return values:
  528. * %true if the following XDR item is absent
  529. * %false if the following XDR item is present
  530. */
  531. static inline bool xdr_item_is_absent(const __be32 *p)
  532. {
  533. return *p == xdr_zero;
  534. }
  535. /**
  536. * xdr_item_is_present - symbolically handle XDR discriminators
  537. * @p: pointer to undecoded discriminator
  538. *
  539. * Return values:
  540. * %true if the following XDR item is present
  541. * %false if the following XDR item is absent
  542. */
  543. static inline bool xdr_item_is_present(const __be32 *p)
  544. {
  545. return *p != xdr_zero;
  546. }
  547. /**
  548. * xdr_stream_decode_bool - Decode a boolean
  549. * @xdr: pointer to xdr_stream
  550. * @ptr: pointer to a u32 in which to store the result
  551. *
  552. * Return values:
  553. * %0 on success
  554. * %-EBADMSG on XDR buffer overflow
  555. */
  556. static inline ssize_t
  557. xdr_stream_decode_bool(struct xdr_stream *xdr, __u32 *ptr)
  558. {
  559. const size_t count = sizeof(*ptr);
  560. __be32 *p = xdr_inline_decode(xdr, count);
  561. if (unlikely(!p))
  562. return -EBADMSG;
  563. *ptr = (*p != xdr_zero);
  564. return 0;
  565. }
  566. /**
  567. * xdr_stream_decode_u32 - Decode a 32-bit integer
  568. * @xdr: pointer to xdr_stream
  569. * @ptr: location to store integer
  570. *
  571. * Return values:
  572. * %0 on success
  573. * %-EBADMSG on XDR buffer overflow
  574. */
  575. static inline ssize_t
  576. xdr_stream_decode_u32(struct xdr_stream *xdr, __u32 *ptr)
  577. {
  578. const size_t count = sizeof(*ptr);
  579. __be32 *p = xdr_inline_decode(xdr, count);
  580. if (unlikely(!p))
  581. return -EBADMSG;
  582. *ptr = be32_to_cpup(p);
  583. return 0;
  584. }
  585. /**
  586. * xdr_stream_decode_u64 - Decode a 64-bit integer
  587. * @xdr: pointer to xdr_stream
  588. * @ptr: location to store 64-bit integer
  589. *
  590. * Return values:
  591. * %0 on success
  592. * %-EBADMSG on XDR buffer overflow
  593. */
  594. static inline ssize_t
  595. xdr_stream_decode_u64(struct xdr_stream *xdr, __u64 *ptr)
  596. {
  597. const size_t count = sizeof(*ptr);
  598. __be32 *p = xdr_inline_decode(xdr, count);
  599. if (unlikely(!p))
  600. return -EBADMSG;
  601. xdr_decode_hyper(p, ptr);
  602. return 0;
  603. }
  604. /**
  605. * xdr_stream_decode_opaque_fixed - Decode fixed length opaque xdr data
  606. * @xdr: pointer to xdr_stream
  607. * @ptr: location to store data
  608. * @len: size of buffer pointed to by @ptr
  609. *
  610. * Return values:
  611. * On success, returns size of object stored in @ptr
  612. * %-EBADMSG on XDR buffer overflow
  613. */
  614. static inline ssize_t
  615. xdr_stream_decode_opaque_fixed(struct xdr_stream *xdr, void *ptr, size_t len)
  616. {
  617. __be32 *p = xdr_inline_decode(xdr, len);
  618. if (unlikely(!p))
  619. return -EBADMSG;
  620. xdr_decode_opaque_fixed(p, ptr, len);
  621. return len;
  622. }
  623. /**
  624. * xdr_stream_decode_opaque_inline - Decode variable length opaque xdr data
  625. * @xdr: pointer to xdr_stream
  626. * @ptr: location to store pointer to opaque data
  627. * @maxlen: maximum acceptable object size
  628. *
  629. * Note: the pointer stored in @ptr cannot be assumed valid after the XDR
  630. * buffer has been destroyed, or even after calling xdr_inline_decode()
  631. * on @xdr. It is therefore expected that the object it points to should
  632. * be processed immediately.
  633. *
  634. * Return values:
  635. * On success, returns size of object stored in *@ptr
  636. * %-EBADMSG on XDR buffer overflow
  637. * %-EMSGSIZE if the size of the object would exceed @maxlen
  638. */
  639. static inline ssize_t
  640. xdr_stream_decode_opaque_inline(struct xdr_stream *xdr, void **ptr, size_t maxlen)
  641. {
  642. __be32 *p;
  643. __u32 len;
  644. *ptr = NULL;
  645. if (unlikely(xdr_stream_decode_u32(xdr, &len) < 0))
  646. return -EBADMSG;
  647. if (len != 0) {
  648. p = xdr_inline_decode(xdr, len);
  649. if (unlikely(!p))
  650. return -EBADMSG;
  651. if (unlikely(len > maxlen))
  652. return -EMSGSIZE;
  653. *ptr = p;
  654. }
  655. return len;
  656. }
  657. /**
  658. * xdr_stream_decode_uint32_array - Decode variable length array of integers
  659. * @xdr: pointer to xdr_stream
  660. * @array: location to store the integer array or NULL
  661. * @array_size: number of elements to store
  662. *
  663. * Return values:
  664. * On success, returns number of elements stored in @array
  665. * %-EBADMSG on XDR buffer overflow
  666. * %-EMSGSIZE if the size of the array exceeds @array_size
  667. */
  668. static inline ssize_t
  669. xdr_stream_decode_uint32_array(struct xdr_stream *xdr,
  670. __u32 *array, size_t array_size)
  671. {
  672. __be32 *p;
  673. __u32 len;
  674. ssize_t retval;
  675. if (unlikely(xdr_stream_decode_u32(xdr, &len) < 0))
  676. return -EBADMSG;
  677. if (len > SIZE_MAX / sizeof(*p))
  678. return -EBADMSG;
  679. p = xdr_inline_decode(xdr, len * sizeof(*p));
  680. if (unlikely(!p))
  681. return -EBADMSG;
  682. if (array == NULL)
  683. return len;
  684. if (len <= array_size) {
  685. if (len < array_size)
  686. memset(array+len, 0, (array_size-len)*sizeof(*array));
  687. array_size = len;
  688. retval = len;
  689. } else
  690. retval = -EMSGSIZE;
  691. for (; array_size > 0; p++, array++, array_size--)
  692. *array = be32_to_cpup(p);
  693. return retval;
  694. }
  695. #endif /* _SUNRPC_XDR_H_ */