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