cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xdr.h (21780B)


      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 <asm/unaligned.h>
     17#include <linux/scatterlist.h>
     18
     19struct bio_vec;
     20struct 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
     38struct 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 */
     56struct 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
     73static inline void
     74xdr_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
    136void	xdr_inline_pages(struct xdr_buf *, unsigned int,
    137			 struct page **, unsigned int, unsigned int);
    138void	xdr_terminate_string(const struct xdr_buf *, const u32);
    139size_t	xdr_buf_pagecount(const struct xdr_buf *buf);
    140int	xdr_alloc_bvec(struct xdr_buf *buf, gfp_t gfp);
    141void	xdr_free_bvec(struct xdr_buf *buf);
    142
    143static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len)
    144{
    145	return xdr_encode_opaque(p, s, len);
    146}
    147
    148/*
    149 * Decode 64bit quantities (NFSv3 support)
    150 */
    151static inline __be32 *
    152xdr_encode_hyper(__be32 *p, __u64 val)
    153{
    154	put_unaligned_be64(val, p);
    155	return p + 2;
    156}
    157
    158static inline __be32 *
    159xdr_decode_hyper(__be32 *p, __u64 *valp)
    160{
    161	*valp = get_unaligned_be64(p);
    162	return p + 2;
    163}
    164
    165static inline __be32 *
    166xdr_decode_opaque_fixed(__be32 *p, void *ptr, unsigned int len)
    167{
    168	memcpy(ptr, p, len);
    169	return p + XDR_QUADLEN(len);
    170}
    171
    172static inline void xdr_netobj_dup(struct xdr_netobj *dst,
    173				  struct xdr_netobj *src, gfp_t gfp_mask)
    174{
    175	dst->data = kmemdup(src->data, src->len, gfp_mask);
    176	dst->len = src->len;
    177}
    178
    179/*
    180 * Adjust kvec to reflect end of xdr'ed data (RPC client XDR)
    181 */
    182static inline int
    183xdr_adjust_iovec(struct kvec *iov, __be32 *p)
    184{
    185	return iov->iov_len = ((u8 *) p - (u8 *) iov->iov_base);
    186}
    187
    188/*
    189 * XDR buffer helper functions
    190 */
    191extern void xdr_shift_buf(struct xdr_buf *, size_t);
    192extern void xdr_buf_from_iov(const struct kvec *, struct xdr_buf *);
    193extern int xdr_buf_subsegment(const struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int);
    194extern void xdr_buf_trim(struct xdr_buf *, unsigned int);
    195extern int read_bytes_from_xdr_buf(const struct xdr_buf *, unsigned int, void *, unsigned int);
    196extern int write_bytes_to_xdr_buf(const struct xdr_buf *, unsigned int, void *, unsigned int);
    197
    198extern int xdr_encode_word(const struct xdr_buf *, unsigned int, u32);
    199extern int xdr_decode_word(const struct xdr_buf *, unsigned int, u32 *);
    200
    201struct xdr_array2_desc;
    202typedef int (*xdr_xcode_elem_t)(struct xdr_array2_desc *desc, void *elem);
    203struct xdr_array2_desc {
    204	unsigned int elem_size;
    205	unsigned int array_len;
    206	unsigned int array_maxlen;
    207	xdr_xcode_elem_t xcode;
    208};
    209
    210extern int xdr_decode_array2(const struct xdr_buf *buf, unsigned int base,
    211			     struct xdr_array2_desc *desc);
    212extern int xdr_encode_array2(const struct xdr_buf *buf, unsigned int base,
    213			     struct xdr_array2_desc *desc);
    214extern void _copy_from_pages(char *p, struct page **pages, size_t pgbase,
    215			     size_t len);
    216
    217/*
    218 * Provide some simple tools for XDR buffer overflow-checking etc.
    219 */
    220struct xdr_stream {
    221	__be32 *p;		/* start of available buffer */
    222	struct xdr_buf *buf;	/* XDR buffer to read/write */
    223
    224	__be32 *end;		/* end of available buffer space */
    225	struct kvec *iov;	/* pointer to the current kvec */
    226	struct kvec scratch;	/* Scratch buffer */
    227	struct page **page_ptr;	/* pointer to the current page */
    228	unsigned int nwords;	/* Remaining decode buffer length */
    229
    230	struct rpc_rqst *rqst;	/* For debugging */
    231};
    232
    233/*
    234 * These are the xdr_stream style generic XDR encode and decode functions.
    235 */
    236typedef void	(*kxdreproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
    237		const void *obj);
    238typedef int	(*kxdrdproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
    239		void *obj);
    240
    241extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf,
    242			    __be32 *p, struct rpc_rqst *rqst);
    243extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
    244extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec,
    245		size_t nbytes);
    246extern void __xdr_commit_encode(struct xdr_stream *xdr);
    247extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len);
    248extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen);
    249extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
    250		unsigned int base, unsigned int len);
    251extern unsigned int xdr_stream_pos(const struct xdr_stream *xdr);
    252extern unsigned int xdr_page_pos(const struct xdr_stream *xdr);
    253extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf,
    254			    __be32 *p, struct rpc_rqst *rqst);
    255extern void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf,
    256		struct page **pages, unsigned int len);
    257extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
    258extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
    259extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
    260extern int xdr_process_buf(const struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data);
    261extern unsigned int xdr_align_data(struct xdr_stream *, unsigned int offset, unsigned int length);
    262extern unsigned int xdr_expand_hole(struct xdr_stream *, unsigned int offset, unsigned int length);
    263extern bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf,
    264				  unsigned int len);
    265
    266/**
    267 * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
    268 * @xdr: pointer to xdr_stream struct
    269 * @buf: pointer to an empty buffer
    270 * @buflen: size of 'buf'
    271 *
    272 * The scratch buffer is used when decoding from an array of pages.
    273 * If an xdr_inline_decode() call spans across page boundaries, then
    274 * we copy the data into the scratch buffer in order to allow linear
    275 * access.
    276 */
    277static inline void
    278xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen)
    279{
    280	xdr->scratch.iov_base = buf;
    281	xdr->scratch.iov_len = buflen;
    282}
    283
    284/**
    285 * xdr_set_scratch_page - Attach a scratch buffer for decoding data
    286 * @xdr: pointer to xdr_stream struct
    287 * @page: an anonymous page
    288 *
    289 * See xdr_set_scratch_buffer().
    290 */
    291static inline void
    292xdr_set_scratch_page(struct xdr_stream *xdr, struct page *page)
    293{
    294	xdr_set_scratch_buffer(xdr, page_address(page), PAGE_SIZE);
    295}
    296
    297/**
    298 * xdr_reset_scratch_buffer - Clear scratch buffer information
    299 * @xdr: pointer to xdr_stream struct
    300 *
    301 * See xdr_set_scratch_buffer().
    302 */
    303static inline void
    304xdr_reset_scratch_buffer(struct xdr_stream *xdr)
    305{
    306	xdr_set_scratch_buffer(xdr, NULL, 0);
    307}
    308
    309/**
    310 * xdr_commit_encode - Ensure all data is written to xdr->buf
    311 * @xdr: pointer to xdr_stream
    312 *
    313 * Handle encoding across page boundaries by giving the caller a
    314 * temporary location to write to, then later copying the data into
    315 * place. __xdr_commit_encode() does that copying.
    316 */
    317static inline void xdr_commit_encode(struct xdr_stream *xdr)
    318{
    319	if (unlikely(xdr->scratch.iov_len))
    320		__xdr_commit_encode(xdr);
    321}
    322
    323/**
    324 * xdr_stream_remaining - Return the number of bytes remaining in the stream
    325 * @xdr: pointer to struct xdr_stream
    326 *
    327 * Return value:
    328 *   Number of bytes remaining in @xdr before xdr->end
    329 */
    330static inline size_t
    331xdr_stream_remaining(const struct xdr_stream *xdr)
    332{
    333	return xdr->nwords << 2;
    334}
    335
    336ssize_t xdr_stream_decode_opaque(struct xdr_stream *xdr, void *ptr,
    337		size_t size);
    338ssize_t xdr_stream_decode_opaque_dup(struct xdr_stream *xdr, void **ptr,
    339		size_t maxlen, gfp_t gfp_flags);
    340ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str,
    341		size_t size);
    342ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
    343		size_t maxlen, gfp_t gfp_flags);
    344/**
    345 * xdr_align_size - Calculate padded size of an object
    346 * @n: Size of an object being XDR encoded (in bytes)
    347 *
    348 * Return value:
    349 *   Size (in bytes) of the object including xdr padding
    350 */
    351static inline size_t
    352xdr_align_size(size_t n)
    353{
    354	const size_t mask = XDR_UNIT - 1;
    355
    356	return (n + mask) & ~mask;
    357}
    358
    359/**
    360 * xdr_pad_size - Calculate size of an object's pad
    361 * @n: Size of an object being XDR encoded (in bytes)
    362 *
    363 * This implementation avoids the need for conditional
    364 * branches or modulo division.
    365 *
    366 * Return value:
    367 *   Size (in bytes) of the needed XDR pad
    368 */
    369static inline size_t xdr_pad_size(size_t n)
    370{
    371	return xdr_align_size(n) - n;
    372}
    373
    374/**
    375 * xdr_stream_encode_item_present - Encode a "present" list item
    376 * @xdr: pointer to xdr_stream
    377 *
    378 * Return values:
    379 *   On success, returns length in bytes of XDR buffer consumed
    380 *   %-EMSGSIZE on XDR buffer overflow
    381 */
    382static inline ssize_t xdr_stream_encode_item_present(struct xdr_stream *xdr)
    383{
    384	const size_t len = XDR_UNIT;
    385	__be32 *p = xdr_reserve_space(xdr, len);
    386
    387	if (unlikely(!p))
    388		return -EMSGSIZE;
    389	*p = xdr_one;
    390	return len;
    391}
    392
    393/**
    394 * xdr_stream_encode_item_absent - Encode a "not present" list item
    395 * @xdr: pointer to xdr_stream
    396 *
    397 * Return values:
    398 *   On success, returns length in bytes of XDR buffer consumed
    399 *   %-EMSGSIZE on XDR buffer overflow
    400 */
    401static inline int xdr_stream_encode_item_absent(struct xdr_stream *xdr)
    402{
    403	const size_t len = XDR_UNIT;
    404	__be32 *p = xdr_reserve_space(xdr, len);
    405
    406	if (unlikely(!p))
    407		return -EMSGSIZE;
    408	*p = xdr_zero;
    409	return len;
    410}
    411
    412/**
    413 * xdr_encode_bool - Encode a boolean item
    414 * @p: address in a buffer into which to encode
    415 * @n: boolean value to encode
    416 *
    417 * Return value:
    418 *   Address of item following the encoded boolean
    419 */
    420static inline __be32 *xdr_encode_bool(__be32 *p, u32 n)
    421{
    422	*p = n ? xdr_one : xdr_zero;
    423	return p++;
    424}
    425
    426/**
    427 * xdr_stream_encode_bool - Encode a boolean item
    428 * @xdr: pointer to xdr_stream
    429 * @n: boolean value to encode
    430 *
    431 * Return values:
    432 *   On success, returns length in bytes of XDR buffer consumed
    433 *   %-EMSGSIZE on XDR buffer overflow
    434 */
    435static inline int xdr_stream_encode_bool(struct xdr_stream *xdr, __u32 n)
    436{
    437	const size_t len = XDR_UNIT;
    438	__be32 *p = xdr_reserve_space(xdr, len);
    439
    440	if (unlikely(!p))
    441		return -EMSGSIZE;
    442	xdr_encode_bool(p, n);
    443	return len;
    444}
    445
    446/**
    447 * xdr_stream_encode_u32 - Encode a 32-bit integer
    448 * @xdr: pointer to xdr_stream
    449 * @n: integer to encode
    450 *
    451 * Return values:
    452 *   On success, returns length in bytes of XDR buffer consumed
    453 *   %-EMSGSIZE on XDR buffer overflow
    454 */
    455static inline ssize_t
    456xdr_stream_encode_u32(struct xdr_stream *xdr, __u32 n)
    457{
    458	const size_t len = sizeof(n);
    459	__be32 *p = xdr_reserve_space(xdr, len);
    460
    461	if (unlikely(!p))
    462		return -EMSGSIZE;
    463	*p = cpu_to_be32(n);
    464	return len;
    465}
    466
    467/**
    468 * xdr_stream_encode_u64 - Encode a 64-bit integer
    469 * @xdr: pointer to xdr_stream
    470 * @n: 64-bit integer to encode
    471 *
    472 * Return values:
    473 *   On success, returns length in bytes of XDR buffer consumed
    474 *   %-EMSGSIZE on XDR buffer overflow
    475 */
    476static inline ssize_t
    477xdr_stream_encode_u64(struct xdr_stream *xdr, __u64 n)
    478{
    479	const size_t len = sizeof(n);
    480	__be32 *p = xdr_reserve_space(xdr, len);
    481
    482	if (unlikely(!p))
    483		return -EMSGSIZE;
    484	xdr_encode_hyper(p, n);
    485	return len;
    486}
    487
    488/**
    489 * xdr_stream_encode_opaque_inline - Encode opaque xdr data
    490 * @xdr: pointer to xdr_stream
    491 * @ptr: pointer to void pointer
    492 * @len: size of object
    493 *
    494 * Return values:
    495 *   On success, returns length in bytes of XDR buffer consumed
    496 *   %-EMSGSIZE on XDR buffer overflow
    497 */
    498static inline ssize_t
    499xdr_stream_encode_opaque_inline(struct xdr_stream *xdr, void **ptr, size_t len)
    500{
    501	size_t count = sizeof(__u32) + xdr_align_size(len);
    502	__be32 *p = xdr_reserve_space(xdr, count);
    503
    504	if (unlikely(!p)) {
    505		*ptr = NULL;
    506		return -EMSGSIZE;
    507	}
    508	xdr_encode_opaque(p, NULL, len);
    509	*ptr = ++p;
    510	return count;
    511}
    512
    513/**
    514 * xdr_stream_encode_opaque_fixed - Encode fixed length opaque xdr data
    515 * @xdr: pointer to xdr_stream
    516 * @ptr: pointer to opaque data object
    517 * @len: size of object pointed to by @ptr
    518 *
    519 * Return values:
    520 *   On success, returns length in bytes of XDR buffer consumed
    521 *   %-EMSGSIZE on XDR buffer overflow
    522 */
    523static inline ssize_t
    524xdr_stream_encode_opaque_fixed(struct xdr_stream *xdr, const void *ptr, size_t len)
    525{
    526	__be32 *p = xdr_reserve_space(xdr, len);
    527
    528	if (unlikely(!p))
    529		return -EMSGSIZE;
    530	xdr_encode_opaque_fixed(p, ptr, len);
    531	return xdr_align_size(len);
    532}
    533
    534/**
    535 * xdr_stream_encode_opaque - Encode variable length opaque xdr data
    536 * @xdr: pointer to xdr_stream
    537 * @ptr: pointer to opaque data object
    538 * @len: size of object pointed to by @ptr
    539 *
    540 * Return values:
    541 *   On success, returns length in bytes of XDR buffer consumed
    542 *   %-EMSGSIZE on XDR buffer overflow
    543 */
    544static inline ssize_t
    545xdr_stream_encode_opaque(struct xdr_stream *xdr, const void *ptr, size_t len)
    546{
    547	size_t count = sizeof(__u32) + xdr_align_size(len);
    548	__be32 *p = xdr_reserve_space(xdr, count);
    549
    550	if (unlikely(!p))
    551		return -EMSGSIZE;
    552	xdr_encode_opaque(p, ptr, len);
    553	return count;
    554}
    555
    556/**
    557 * xdr_stream_encode_uint32_array - Encode variable length array of integers
    558 * @xdr: pointer to xdr_stream
    559 * @array: array of integers
    560 * @array_size: number of elements in @array
    561 *
    562 * Return values:
    563 *   On success, returns length in bytes of XDR buffer consumed
    564 *   %-EMSGSIZE on XDR buffer overflow
    565 */
    566static inline ssize_t
    567xdr_stream_encode_uint32_array(struct xdr_stream *xdr,
    568		const __u32 *array, size_t array_size)
    569{
    570	ssize_t ret = (array_size+1) * sizeof(__u32);
    571	__be32 *p = xdr_reserve_space(xdr, ret);
    572
    573	if (unlikely(!p))
    574		return -EMSGSIZE;
    575	*p++ = cpu_to_be32(array_size);
    576	for (; array_size > 0; p++, array++, array_size--)
    577		*p = cpu_to_be32p(array);
    578	return ret;
    579}
    580
    581/**
    582 * xdr_item_is_absent - symbolically handle XDR discriminators
    583 * @p: pointer to undecoded discriminator
    584 *
    585 * Return values:
    586 *   %true if the following XDR item is absent
    587 *   %false if the following XDR item is present
    588 */
    589static inline bool xdr_item_is_absent(const __be32 *p)
    590{
    591	return *p == xdr_zero;
    592}
    593
    594/**
    595 * xdr_item_is_present - symbolically handle XDR discriminators
    596 * @p: pointer to undecoded discriminator
    597 *
    598 * Return values:
    599 *   %true if the following XDR item is present
    600 *   %false if the following XDR item is absent
    601 */
    602static inline bool xdr_item_is_present(const __be32 *p)
    603{
    604	return *p != xdr_zero;
    605}
    606
    607/**
    608 * xdr_stream_decode_bool - Decode a boolean
    609 * @xdr: pointer to xdr_stream
    610 * @ptr: pointer to a u32 in which to store the result
    611 *
    612 * Return values:
    613 *   %0 on success
    614 *   %-EBADMSG on XDR buffer overflow
    615 */
    616static inline ssize_t
    617xdr_stream_decode_bool(struct xdr_stream *xdr, __u32 *ptr)
    618{
    619	const size_t count = sizeof(*ptr);
    620	__be32 *p = xdr_inline_decode(xdr, count);
    621
    622	if (unlikely(!p))
    623		return -EBADMSG;
    624	*ptr = (*p != xdr_zero);
    625	return 0;
    626}
    627
    628/**
    629 * xdr_stream_decode_u32 - Decode a 32-bit integer
    630 * @xdr: pointer to xdr_stream
    631 * @ptr: location to store integer
    632 *
    633 * Return values:
    634 *   %0 on success
    635 *   %-EBADMSG on XDR buffer overflow
    636 */
    637static inline ssize_t
    638xdr_stream_decode_u32(struct xdr_stream *xdr, __u32 *ptr)
    639{
    640	const size_t count = sizeof(*ptr);
    641	__be32 *p = xdr_inline_decode(xdr, count);
    642
    643	if (unlikely(!p))
    644		return -EBADMSG;
    645	*ptr = be32_to_cpup(p);
    646	return 0;
    647}
    648
    649/**
    650 * xdr_stream_decode_u64 - Decode a 64-bit integer
    651 * @xdr: pointer to xdr_stream
    652 * @ptr: location to store 64-bit integer
    653 *
    654 * Return values:
    655 *   %0 on success
    656 *   %-EBADMSG on XDR buffer overflow
    657 */
    658static inline ssize_t
    659xdr_stream_decode_u64(struct xdr_stream *xdr, __u64 *ptr)
    660{
    661	const size_t count = sizeof(*ptr);
    662	__be32 *p = xdr_inline_decode(xdr, count);
    663
    664	if (unlikely(!p))
    665		return -EBADMSG;
    666	xdr_decode_hyper(p, ptr);
    667	return 0;
    668}
    669
    670/**
    671 * xdr_stream_decode_opaque_fixed - Decode fixed length opaque xdr data
    672 * @xdr: pointer to xdr_stream
    673 * @ptr: location to store data
    674 * @len: size of buffer pointed to by @ptr
    675 *
    676 * Return values:
    677 *   On success, returns size of object stored in @ptr
    678 *   %-EBADMSG on XDR buffer overflow
    679 */
    680static inline ssize_t
    681xdr_stream_decode_opaque_fixed(struct xdr_stream *xdr, void *ptr, size_t len)
    682{
    683	__be32 *p = xdr_inline_decode(xdr, len);
    684
    685	if (unlikely(!p))
    686		return -EBADMSG;
    687	xdr_decode_opaque_fixed(p, ptr, len);
    688	return len;
    689}
    690
    691/**
    692 * xdr_stream_decode_opaque_inline - Decode variable length opaque xdr data
    693 * @xdr: pointer to xdr_stream
    694 * @ptr: location to store pointer to opaque data
    695 * @maxlen: maximum acceptable object size
    696 *
    697 * Note: the pointer stored in @ptr cannot be assumed valid after the XDR
    698 * buffer has been destroyed, or even after calling xdr_inline_decode()
    699 * on @xdr. It is therefore expected that the object it points to should
    700 * be processed immediately.
    701 *
    702 * Return values:
    703 *   On success, returns size of object stored in *@ptr
    704 *   %-EBADMSG on XDR buffer overflow
    705 *   %-EMSGSIZE if the size of the object would exceed @maxlen
    706 */
    707static inline ssize_t
    708xdr_stream_decode_opaque_inline(struct xdr_stream *xdr, void **ptr, size_t maxlen)
    709{
    710	__be32 *p;
    711	__u32 len;
    712
    713	*ptr = NULL;
    714	if (unlikely(xdr_stream_decode_u32(xdr, &len) < 0))
    715		return -EBADMSG;
    716	if (len != 0) {
    717		p = xdr_inline_decode(xdr, len);
    718		if (unlikely(!p))
    719			return -EBADMSG;
    720		if (unlikely(len > maxlen))
    721			return -EMSGSIZE;
    722		*ptr = p;
    723	}
    724	return len;
    725}
    726
    727/**
    728 * xdr_stream_decode_uint32_array - Decode variable length array of integers
    729 * @xdr: pointer to xdr_stream
    730 * @array: location to store the integer array or NULL
    731 * @array_size: number of elements to store
    732 *
    733 * Return values:
    734 *   On success, returns number of elements stored in @array
    735 *   %-EBADMSG on XDR buffer overflow
    736 *   %-EMSGSIZE if the size of the array exceeds @array_size
    737 */
    738static inline ssize_t
    739xdr_stream_decode_uint32_array(struct xdr_stream *xdr,
    740		__u32 *array, size_t array_size)
    741{
    742	__be32 *p;
    743	__u32 len;
    744	ssize_t retval;
    745
    746	if (unlikely(xdr_stream_decode_u32(xdr, &len) < 0))
    747		return -EBADMSG;
    748	if (len > SIZE_MAX / sizeof(*p))
    749		return -EBADMSG;
    750	p = xdr_inline_decode(xdr, len * sizeof(*p));
    751	if (unlikely(!p))
    752		return -EBADMSG;
    753	if (array == NULL)
    754		return len;
    755	if (len <= array_size) {
    756		if (len < array_size)
    757			memset(array+len, 0, (array_size-len)*sizeof(*array));
    758		array_size = len;
    759		retval = len;
    760	} else
    761		retval = -EMSGSIZE;
    762	for (; array_size > 0; p++, array++, array_size--)
    763		*array = be32_to_cpup(p);
    764	return retval;
    765}
    766
    767#endif /* _SUNRPC_XDR_H_ */