Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * XDR standard data types and function declarations
0004  *
0005  * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
0006  *
0007  * Based on:
0008  *   RFC 4506 "XDR: External Data Representation Standard", May 2006
0009  */
0010 
0011 #ifndef _SUNRPC_XDR_H_
0012 #define _SUNRPC_XDR_H_
0013 
0014 #include <linux/uio.h>
0015 #include <asm/byteorder.h>
0016 #include <asm/unaligned.h>
0017 #include <linux/scatterlist.h>
0018 
0019 struct bio_vec;
0020 struct rpc_rqst;
0021 
0022 /*
0023  * Size of an XDR encoding unit in bytes, i.e. 32 bits,
0024  * as defined in Section 3 of RFC 4506. All encoded
0025  * XDR data items are aligned on a boundary of 32 bits.
0026  */
0027 #define XDR_UNIT        sizeof(__be32)
0028 
0029 /*
0030  * Buffer adjustment
0031  */
0032 #define XDR_QUADLEN(l)      (((l) + 3) >> 2)
0033 
0034 /*
0035  * Generic opaque `network object.'
0036  */
0037 #define XDR_MAX_NETOBJ      1024
0038 struct xdr_netobj {
0039     unsigned int        len;
0040     u8 *            data;
0041 };
0042 
0043 /*
0044  * Basic structure for transmission/reception of a client XDR message.
0045  * Features a header (for a linear buffer containing RPC headers
0046  * and the data payload for short messages), and then an array of
0047  * pages.
0048  * The tail iovec allows you to append data after the page array. Its
0049  * main interest is for appending padding to the pages in order to
0050  * satisfy the int_32-alignment requirements in RFC1832.
0051  *
0052  * For the future, we might want to string several of these together
0053  * in a list if anybody wants to make use of NFSv4 COMPOUND
0054  * operations and/or has a need for scatter/gather involving pages.
0055  */
0056 struct xdr_buf {
0057     struct kvec head[1],    /* RPC header + non-page data */
0058             tail[1];    /* Appended after page data */
0059 
0060     struct bio_vec  *bvec;
0061     struct page **  pages;      /* Array of pages */
0062     unsigned int    page_base,  /* Start of page data */
0063             page_len,   /* Length of page data */
0064             flags;      /* Flags for data disposition */
0065 #define XDRBUF_READ     0x01        /* target of file read */
0066 #define XDRBUF_WRITE        0x02        /* source of file write */
0067 #define XDRBUF_SPARSE_PAGES 0x04        /* Page array is sparse */
0068 
0069     unsigned int    buflen,     /* Total length of storage buffer */
0070             len;        /* Length of XDR encoded message */
0071 };
0072 
0073 static inline void
0074 xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
0075 {
0076     buf->head[0].iov_base = start;
0077     buf->head[0].iov_len = len;
0078     buf->tail[0].iov_len = 0;
0079     buf->pages = NULL;
0080     buf->page_len = 0;
0081     buf->flags = 0;
0082     buf->len = 0;
0083     buf->buflen = len;
0084 }
0085 
0086 /*
0087  * pre-xdr'ed macros.
0088  */
0089 
0090 #define xdr_zero    cpu_to_be32(0)
0091 #define xdr_one     cpu_to_be32(1)
0092 #define xdr_two     cpu_to_be32(2)
0093 
0094 #define rpc_auth_null   cpu_to_be32(RPC_AUTH_NULL)
0095 #define rpc_auth_unix   cpu_to_be32(RPC_AUTH_UNIX)
0096 #define rpc_auth_short  cpu_to_be32(RPC_AUTH_SHORT)
0097 #define rpc_auth_gss    cpu_to_be32(RPC_AUTH_GSS)
0098 #define rpc_auth_tls    cpu_to_be32(RPC_AUTH_TLS)
0099 
0100 #define rpc_call    cpu_to_be32(RPC_CALL)
0101 #define rpc_reply   cpu_to_be32(RPC_REPLY)
0102 
0103 #define rpc_msg_accepted    cpu_to_be32(RPC_MSG_ACCEPTED)
0104 
0105 #define rpc_success     cpu_to_be32(RPC_SUCCESS)
0106 #define rpc_prog_unavail    cpu_to_be32(RPC_PROG_UNAVAIL)
0107 #define rpc_prog_mismatch   cpu_to_be32(RPC_PROG_MISMATCH)
0108 #define rpc_proc_unavail    cpu_to_be32(RPC_PROC_UNAVAIL)
0109 #define rpc_garbage_args    cpu_to_be32(RPC_GARBAGE_ARGS)
0110 #define rpc_system_err      cpu_to_be32(RPC_SYSTEM_ERR)
0111 #define rpc_drop_reply      cpu_to_be32(RPC_DROP_REPLY)
0112 
0113 #define rpc_mismatch        cpu_to_be32(RPC_MISMATCH)
0114 #define rpc_auth_error      cpu_to_be32(RPC_AUTH_ERROR)
0115 
0116 #define rpc_auth_ok     cpu_to_be32(RPC_AUTH_OK)
0117 #define rpc_autherr_badcred cpu_to_be32(RPC_AUTH_BADCRED)
0118 #define rpc_autherr_rejectedcred cpu_to_be32(RPC_AUTH_REJECTEDCRED)
0119 #define rpc_autherr_badverf cpu_to_be32(RPC_AUTH_BADVERF)
0120 #define rpc_autherr_rejectedverf cpu_to_be32(RPC_AUTH_REJECTEDVERF)
0121 #define rpc_autherr_tooweak cpu_to_be32(RPC_AUTH_TOOWEAK)
0122 #define rpcsec_gsserr_credproblem   cpu_to_be32(RPCSEC_GSS_CREDPROBLEM)
0123 #define rpcsec_gsserr_ctxproblem    cpu_to_be32(RPCSEC_GSS_CTXPROBLEM)
0124 
0125 /*
0126  * Miscellaneous XDR helper functions
0127  */
0128 __be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int len);
0129 __be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int len);
0130 __be32 *xdr_encode_string(__be32 *p, const char *s);
0131 __be32 *xdr_decode_string_inplace(__be32 *p, char **sp, unsigned int *lenp,
0132             unsigned int maxlen);
0133 __be32 *xdr_encode_netobj(__be32 *p, const struct xdr_netobj *);
0134 __be32 *xdr_decode_netobj(__be32 *p, struct xdr_netobj *);
0135 
0136 void    xdr_inline_pages(struct xdr_buf *, unsigned int,
0137              struct page **, unsigned int, unsigned int);
0138 void    xdr_terminate_string(const struct xdr_buf *, const u32);
0139 size_t  xdr_buf_pagecount(const struct xdr_buf *buf);
0140 int xdr_alloc_bvec(struct xdr_buf *buf, gfp_t gfp);
0141 void    xdr_free_bvec(struct xdr_buf *buf);
0142 
0143 static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len)
0144 {
0145     return xdr_encode_opaque(p, s, len);
0146 }
0147 
0148 /*
0149  * Decode 64bit quantities (NFSv3 support)
0150  */
0151 static inline __be32 *
0152 xdr_encode_hyper(__be32 *p, __u64 val)
0153 {
0154     put_unaligned_be64(val, p);
0155     return p + 2;
0156 }
0157 
0158 static inline __be32 *
0159 xdr_decode_hyper(__be32 *p, __u64 *valp)
0160 {
0161     *valp = get_unaligned_be64(p);
0162     return p + 2;
0163 }
0164 
0165 static inline __be32 *
0166 xdr_decode_opaque_fixed(__be32 *p, void *ptr, unsigned int len)
0167 {
0168     memcpy(ptr, p, len);
0169     return p + XDR_QUADLEN(len);
0170 }
0171 
0172 static inline void xdr_netobj_dup(struct xdr_netobj *dst,
0173                   struct xdr_netobj *src, gfp_t gfp_mask)
0174 {
0175     dst->data = kmemdup(src->data, src->len, gfp_mask);
0176     dst->len = src->len;
0177 }
0178 
0179 /*
0180  * Adjust kvec to reflect end of xdr'ed data (RPC client XDR)
0181  */
0182 static inline int
0183 xdr_adjust_iovec(struct kvec *iov, __be32 *p)
0184 {
0185     return iov->iov_len = ((u8 *) p - (u8 *) iov->iov_base);
0186 }
0187 
0188 /*
0189  * XDR buffer helper functions
0190  */
0191 extern void xdr_shift_buf(struct xdr_buf *, size_t);
0192 extern void xdr_buf_from_iov(const struct kvec *, struct xdr_buf *);
0193 extern int xdr_buf_subsegment(const struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int);
0194 extern void xdr_buf_trim(struct xdr_buf *, unsigned int);
0195 extern int read_bytes_from_xdr_buf(const struct xdr_buf *, unsigned int, void *, unsigned int);
0196 extern int write_bytes_to_xdr_buf(const struct xdr_buf *, unsigned int, void *, unsigned int);
0197 
0198 extern int xdr_encode_word(const struct xdr_buf *, unsigned int, u32);
0199 extern int xdr_decode_word(const struct xdr_buf *, unsigned int, u32 *);
0200 
0201 struct xdr_array2_desc;
0202 typedef int (*xdr_xcode_elem_t)(struct xdr_array2_desc *desc, void *elem);
0203 struct xdr_array2_desc {
0204     unsigned int elem_size;
0205     unsigned int array_len;
0206     unsigned int array_maxlen;
0207     xdr_xcode_elem_t xcode;
0208 };
0209 
0210 extern int xdr_decode_array2(const struct xdr_buf *buf, unsigned int base,
0211                  struct xdr_array2_desc *desc);
0212 extern int xdr_encode_array2(const struct xdr_buf *buf, unsigned int base,
0213                  struct xdr_array2_desc *desc);
0214 extern void _copy_from_pages(char *p, struct page **pages, size_t pgbase,
0215                  size_t len);
0216 
0217 /*
0218  * Provide some simple tools for XDR buffer overflow-checking etc.
0219  */
0220 struct xdr_stream {
0221     __be32 *p;      /* start of available buffer */
0222     struct xdr_buf *buf;    /* XDR buffer to read/write */
0223 
0224     __be32 *end;        /* end of available buffer space */
0225     struct kvec *iov;   /* pointer to the current kvec */
0226     struct kvec scratch;    /* Scratch buffer */
0227     struct page **page_ptr; /* pointer to the current page */
0228     unsigned int nwords;    /* Remaining decode buffer length */
0229 
0230     struct rpc_rqst *rqst;  /* For debugging */
0231 };
0232 
0233 /*
0234  * These are the xdr_stream style generic XDR encode and decode functions.
0235  */
0236 typedef void    (*kxdreproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
0237         const void *obj);
0238 typedef int (*kxdrdproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
0239         void *obj);
0240 
0241 extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf,
0242                 __be32 *p, struct rpc_rqst *rqst);
0243 extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
0244 extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec,
0245         size_t nbytes);
0246 extern void __xdr_commit_encode(struct xdr_stream *xdr);
0247 extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len);
0248 extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen);
0249 extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
0250         unsigned int base, unsigned int len);
0251 extern unsigned int xdr_stream_pos(const struct xdr_stream *xdr);
0252 extern unsigned int xdr_page_pos(const struct xdr_stream *xdr);
0253 extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf,
0254                 __be32 *p, struct rpc_rqst *rqst);
0255 extern void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf,
0256         struct page **pages, unsigned int len);
0257 extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
0258 extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
0259 extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
0260 extern int xdr_process_buf(const struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data);
0261 extern void xdr_set_pagelen(struct xdr_stream *, unsigned int len);
0262 extern bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf,
0263                   unsigned int len);
0264 extern unsigned int xdr_stream_move_subsegment(struct xdr_stream *xdr, unsigned int offset,
0265                            unsigned int target, unsigned int length);
0266 extern unsigned int xdr_stream_zero(struct xdr_stream *xdr, unsigned int offset,
0267                     unsigned int length);
0268 
0269 /**
0270  * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
0271  * @xdr: pointer to xdr_stream struct
0272  * @buf: pointer to an empty buffer
0273  * @buflen: size of 'buf'
0274  *
0275  * The scratch buffer is used when decoding from an array of pages.
0276  * If an xdr_inline_decode() call spans across page boundaries, then
0277  * we copy the data into the scratch buffer in order to allow linear
0278  * access.
0279  */
0280 static inline void
0281 xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen)
0282 {
0283     xdr->scratch.iov_base = buf;
0284     xdr->scratch.iov_len = buflen;
0285 }
0286 
0287 /**
0288  * xdr_set_scratch_page - Attach a scratch buffer for decoding data
0289  * @xdr: pointer to xdr_stream struct
0290  * @page: an anonymous page
0291  *
0292  * See xdr_set_scratch_buffer().
0293  */
0294 static inline void
0295 xdr_set_scratch_page(struct xdr_stream *xdr, struct page *page)
0296 {
0297     xdr_set_scratch_buffer(xdr, page_address(page), PAGE_SIZE);
0298 }
0299 
0300 /**
0301  * xdr_reset_scratch_buffer - Clear scratch buffer information
0302  * @xdr: pointer to xdr_stream struct
0303  *
0304  * See xdr_set_scratch_buffer().
0305  */
0306 static inline void
0307 xdr_reset_scratch_buffer(struct xdr_stream *xdr)
0308 {
0309     xdr_set_scratch_buffer(xdr, NULL, 0);
0310 }
0311 
0312 /**
0313  * xdr_commit_encode - Ensure all data is written to xdr->buf
0314  * @xdr: pointer to xdr_stream
0315  *
0316  * Handle encoding across page boundaries by giving the caller a
0317  * temporary location to write to, then later copying the data into
0318  * place. __xdr_commit_encode() does that copying.
0319  */
0320 static inline void xdr_commit_encode(struct xdr_stream *xdr)
0321 {
0322     if (unlikely(xdr->scratch.iov_len))
0323         __xdr_commit_encode(xdr);
0324 }
0325 
0326 /**
0327  * xdr_stream_remaining - Return the number of bytes remaining in the stream
0328  * @xdr: pointer to struct xdr_stream
0329  *
0330  * Return value:
0331  *   Number of bytes remaining in @xdr before xdr->end
0332  */
0333 static inline size_t
0334 xdr_stream_remaining(const struct xdr_stream *xdr)
0335 {
0336     return xdr->nwords << 2;
0337 }
0338 
0339 ssize_t xdr_stream_decode_opaque(struct xdr_stream *xdr, void *ptr,
0340         size_t size);
0341 ssize_t xdr_stream_decode_opaque_dup(struct xdr_stream *xdr, void **ptr,
0342         size_t maxlen, gfp_t gfp_flags);
0343 ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str,
0344         size_t size);
0345 ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
0346         size_t maxlen, gfp_t gfp_flags);
0347 /**
0348  * xdr_align_size - Calculate padded size of an object
0349  * @n: Size of an object being XDR encoded (in bytes)
0350  *
0351  * Return value:
0352  *   Size (in bytes) of the object including xdr padding
0353  */
0354 static inline size_t
0355 xdr_align_size(size_t n)
0356 {
0357     const size_t mask = XDR_UNIT - 1;
0358 
0359     return (n + mask) & ~mask;
0360 }
0361 
0362 /**
0363  * xdr_pad_size - Calculate size of an object's pad
0364  * @n: Size of an object being XDR encoded (in bytes)
0365  *
0366  * This implementation avoids the need for conditional
0367  * branches or modulo division.
0368  *
0369  * Return value:
0370  *   Size (in bytes) of the needed XDR pad
0371  */
0372 static inline size_t xdr_pad_size(size_t n)
0373 {
0374     return xdr_align_size(n) - n;
0375 }
0376 
0377 /**
0378  * xdr_stream_encode_item_present - Encode a "present" list item
0379  * @xdr: pointer to xdr_stream
0380  *
0381  * Return values:
0382  *   On success, returns length in bytes of XDR buffer consumed
0383  *   %-EMSGSIZE on XDR buffer overflow
0384  */
0385 static inline ssize_t xdr_stream_encode_item_present(struct xdr_stream *xdr)
0386 {
0387     const size_t len = XDR_UNIT;
0388     __be32 *p = xdr_reserve_space(xdr, len);
0389 
0390     if (unlikely(!p))
0391         return -EMSGSIZE;
0392     *p = xdr_one;
0393     return len;
0394 }
0395 
0396 /**
0397  * xdr_stream_encode_item_absent - Encode a "not present" list item
0398  * @xdr: pointer to xdr_stream
0399  *
0400  * Return values:
0401  *   On success, returns length in bytes of XDR buffer consumed
0402  *   %-EMSGSIZE on XDR buffer overflow
0403  */
0404 static inline int xdr_stream_encode_item_absent(struct xdr_stream *xdr)
0405 {
0406     const size_t len = XDR_UNIT;
0407     __be32 *p = xdr_reserve_space(xdr, len);
0408 
0409     if (unlikely(!p))
0410         return -EMSGSIZE;
0411     *p = xdr_zero;
0412     return len;
0413 }
0414 
0415 /**
0416  * xdr_encode_bool - Encode a boolean item
0417  * @p: address in a buffer into which to encode
0418  * @n: boolean value to encode
0419  *
0420  * Return value:
0421  *   Address of item following the encoded boolean
0422  */
0423 static inline __be32 *xdr_encode_bool(__be32 *p, u32 n)
0424 {
0425     *p++ = n ? xdr_one : xdr_zero;
0426     return p;
0427 }
0428 
0429 /**
0430  * xdr_stream_encode_bool - Encode a boolean item
0431  * @xdr: pointer to xdr_stream
0432  * @n: boolean value to encode
0433  *
0434  * Return values:
0435  *   On success, returns length in bytes of XDR buffer consumed
0436  *   %-EMSGSIZE on XDR buffer overflow
0437  */
0438 static inline int xdr_stream_encode_bool(struct xdr_stream *xdr, __u32 n)
0439 {
0440     const size_t len = XDR_UNIT;
0441     __be32 *p = xdr_reserve_space(xdr, len);
0442 
0443     if (unlikely(!p))
0444         return -EMSGSIZE;
0445     xdr_encode_bool(p, n);
0446     return len;
0447 }
0448 
0449 /**
0450  * xdr_stream_encode_u32 - Encode a 32-bit integer
0451  * @xdr: pointer to xdr_stream
0452  * @n: integer to encode
0453  *
0454  * Return values:
0455  *   On success, returns length in bytes of XDR buffer consumed
0456  *   %-EMSGSIZE on XDR buffer overflow
0457  */
0458 static inline ssize_t
0459 xdr_stream_encode_u32(struct xdr_stream *xdr, __u32 n)
0460 {
0461     const size_t len = sizeof(n);
0462     __be32 *p = xdr_reserve_space(xdr, len);
0463 
0464     if (unlikely(!p))
0465         return -EMSGSIZE;
0466     *p = cpu_to_be32(n);
0467     return len;
0468 }
0469 
0470 /**
0471  * xdr_stream_encode_u64 - Encode a 64-bit integer
0472  * @xdr: pointer to xdr_stream
0473  * @n: 64-bit integer to encode
0474  *
0475  * Return values:
0476  *   On success, returns length in bytes of XDR buffer consumed
0477  *   %-EMSGSIZE on XDR buffer overflow
0478  */
0479 static inline ssize_t
0480 xdr_stream_encode_u64(struct xdr_stream *xdr, __u64 n)
0481 {
0482     const size_t len = sizeof(n);
0483     __be32 *p = xdr_reserve_space(xdr, len);
0484 
0485     if (unlikely(!p))
0486         return -EMSGSIZE;
0487     xdr_encode_hyper(p, n);
0488     return len;
0489 }
0490 
0491 /**
0492  * xdr_stream_encode_opaque_inline - Encode opaque xdr data
0493  * @xdr: pointer to xdr_stream
0494  * @ptr: pointer to void pointer
0495  * @len: size of object
0496  *
0497  * Return values:
0498  *   On success, returns length in bytes of XDR buffer consumed
0499  *   %-EMSGSIZE on XDR buffer overflow
0500  */
0501 static inline ssize_t
0502 xdr_stream_encode_opaque_inline(struct xdr_stream *xdr, void **ptr, size_t len)
0503 {
0504     size_t count = sizeof(__u32) + xdr_align_size(len);
0505     __be32 *p = xdr_reserve_space(xdr, count);
0506 
0507     if (unlikely(!p)) {
0508         *ptr = NULL;
0509         return -EMSGSIZE;
0510     }
0511     xdr_encode_opaque(p, NULL, len);
0512     *ptr = ++p;
0513     return count;
0514 }
0515 
0516 /**
0517  * xdr_stream_encode_opaque_fixed - Encode fixed length opaque xdr data
0518  * @xdr: pointer to xdr_stream
0519  * @ptr: pointer to opaque data object
0520  * @len: size of object pointed to by @ptr
0521  *
0522  * Return values:
0523  *   On success, returns length in bytes of XDR buffer consumed
0524  *   %-EMSGSIZE on XDR buffer overflow
0525  */
0526 static inline ssize_t
0527 xdr_stream_encode_opaque_fixed(struct xdr_stream *xdr, const void *ptr, size_t len)
0528 {
0529     __be32 *p = xdr_reserve_space(xdr, len);
0530 
0531     if (unlikely(!p))
0532         return -EMSGSIZE;
0533     xdr_encode_opaque_fixed(p, ptr, len);
0534     return xdr_align_size(len);
0535 }
0536 
0537 /**
0538  * xdr_stream_encode_opaque - Encode variable length opaque xdr data
0539  * @xdr: pointer to xdr_stream
0540  * @ptr: pointer to opaque data object
0541  * @len: size of object pointed to by @ptr
0542  *
0543  * Return values:
0544  *   On success, returns length in bytes of XDR buffer consumed
0545  *   %-EMSGSIZE on XDR buffer overflow
0546  */
0547 static inline ssize_t
0548 xdr_stream_encode_opaque(struct xdr_stream *xdr, const void *ptr, size_t len)
0549 {
0550     size_t count = sizeof(__u32) + xdr_align_size(len);
0551     __be32 *p = xdr_reserve_space(xdr, count);
0552 
0553     if (unlikely(!p))
0554         return -EMSGSIZE;
0555     xdr_encode_opaque(p, ptr, len);
0556     return count;
0557 }
0558 
0559 /**
0560  * xdr_stream_encode_uint32_array - Encode variable length array of integers
0561  * @xdr: pointer to xdr_stream
0562  * @array: array of integers
0563  * @array_size: number of elements in @array
0564  *
0565  * Return values:
0566  *   On success, returns length in bytes of XDR buffer consumed
0567  *   %-EMSGSIZE on XDR buffer overflow
0568  */
0569 static inline ssize_t
0570 xdr_stream_encode_uint32_array(struct xdr_stream *xdr,
0571         const __u32 *array, size_t array_size)
0572 {
0573     ssize_t ret = (array_size+1) * sizeof(__u32);
0574     __be32 *p = xdr_reserve_space(xdr, ret);
0575 
0576     if (unlikely(!p))
0577         return -EMSGSIZE;
0578     *p++ = cpu_to_be32(array_size);
0579     for (; array_size > 0; p++, array++, array_size--)
0580         *p = cpu_to_be32p(array);
0581     return ret;
0582 }
0583 
0584 /**
0585  * xdr_item_is_absent - symbolically handle XDR discriminators
0586  * @p: pointer to undecoded discriminator
0587  *
0588  * Return values:
0589  *   %true if the following XDR item is absent
0590  *   %false if the following XDR item is present
0591  */
0592 static inline bool xdr_item_is_absent(const __be32 *p)
0593 {
0594     return *p == xdr_zero;
0595 }
0596 
0597 /**
0598  * xdr_item_is_present - symbolically handle XDR discriminators
0599  * @p: pointer to undecoded discriminator
0600  *
0601  * Return values:
0602  *   %true if the following XDR item is present
0603  *   %false if the following XDR item is absent
0604  */
0605 static inline bool xdr_item_is_present(const __be32 *p)
0606 {
0607     return *p != xdr_zero;
0608 }
0609 
0610 /**
0611  * xdr_stream_decode_bool - Decode a boolean
0612  * @xdr: pointer to xdr_stream
0613  * @ptr: pointer to a u32 in which to store the result
0614  *
0615  * Return values:
0616  *   %0 on success
0617  *   %-EBADMSG on XDR buffer overflow
0618  */
0619 static inline ssize_t
0620 xdr_stream_decode_bool(struct xdr_stream *xdr, __u32 *ptr)
0621 {
0622     const size_t count = sizeof(*ptr);
0623     __be32 *p = xdr_inline_decode(xdr, count);
0624 
0625     if (unlikely(!p))
0626         return -EBADMSG;
0627     *ptr = (*p != xdr_zero);
0628     return 0;
0629 }
0630 
0631 /**
0632  * xdr_stream_decode_u32 - Decode a 32-bit integer
0633  * @xdr: pointer to xdr_stream
0634  * @ptr: location to store integer
0635  *
0636  * Return values:
0637  *   %0 on success
0638  *   %-EBADMSG on XDR buffer overflow
0639  */
0640 static inline ssize_t
0641 xdr_stream_decode_u32(struct xdr_stream *xdr, __u32 *ptr)
0642 {
0643     const size_t count = sizeof(*ptr);
0644     __be32 *p = xdr_inline_decode(xdr, count);
0645 
0646     if (unlikely(!p))
0647         return -EBADMSG;
0648     *ptr = be32_to_cpup(p);
0649     return 0;
0650 }
0651 
0652 /**
0653  * xdr_stream_decode_u64 - Decode a 64-bit integer
0654  * @xdr: pointer to xdr_stream
0655  * @ptr: location to store 64-bit integer
0656  *
0657  * Return values:
0658  *   %0 on success
0659  *   %-EBADMSG on XDR buffer overflow
0660  */
0661 static inline ssize_t
0662 xdr_stream_decode_u64(struct xdr_stream *xdr, __u64 *ptr)
0663 {
0664     const size_t count = sizeof(*ptr);
0665     __be32 *p = xdr_inline_decode(xdr, count);
0666 
0667     if (unlikely(!p))
0668         return -EBADMSG;
0669     xdr_decode_hyper(p, ptr);
0670     return 0;
0671 }
0672 
0673 /**
0674  * xdr_stream_decode_opaque_fixed - Decode fixed length opaque xdr data
0675  * @xdr: pointer to xdr_stream
0676  * @ptr: location to store data
0677  * @len: size of buffer pointed to by @ptr
0678  *
0679  * Return values:
0680  *   On success, returns size of object stored in @ptr
0681  *   %-EBADMSG on XDR buffer overflow
0682  */
0683 static inline ssize_t
0684 xdr_stream_decode_opaque_fixed(struct xdr_stream *xdr, void *ptr, size_t len)
0685 {
0686     __be32 *p = xdr_inline_decode(xdr, len);
0687 
0688     if (unlikely(!p))
0689         return -EBADMSG;
0690     xdr_decode_opaque_fixed(p, ptr, len);
0691     return len;
0692 }
0693 
0694 /**
0695  * xdr_stream_decode_opaque_inline - Decode variable length opaque xdr data
0696  * @xdr: pointer to xdr_stream
0697  * @ptr: location to store pointer to opaque data
0698  * @maxlen: maximum acceptable object size
0699  *
0700  * Note: the pointer stored in @ptr cannot be assumed valid after the XDR
0701  * buffer has been destroyed, or even after calling xdr_inline_decode()
0702  * on @xdr. It is therefore expected that the object it points to should
0703  * be processed immediately.
0704  *
0705  * Return values:
0706  *   On success, returns size of object stored in *@ptr
0707  *   %-EBADMSG on XDR buffer overflow
0708  *   %-EMSGSIZE if the size of the object would exceed @maxlen
0709  */
0710 static inline ssize_t
0711 xdr_stream_decode_opaque_inline(struct xdr_stream *xdr, void **ptr, size_t maxlen)
0712 {
0713     __be32 *p;
0714     __u32 len;
0715 
0716     *ptr = NULL;
0717     if (unlikely(xdr_stream_decode_u32(xdr, &len) < 0))
0718         return -EBADMSG;
0719     if (len != 0) {
0720         p = xdr_inline_decode(xdr, len);
0721         if (unlikely(!p))
0722             return -EBADMSG;
0723         if (unlikely(len > maxlen))
0724             return -EMSGSIZE;
0725         *ptr = p;
0726     }
0727     return len;
0728 }
0729 
0730 /**
0731  * xdr_stream_decode_uint32_array - Decode variable length array of integers
0732  * @xdr: pointer to xdr_stream
0733  * @array: location to store the integer array or NULL
0734  * @array_size: number of elements to store
0735  *
0736  * Return values:
0737  *   On success, returns number of elements stored in @array
0738  *   %-EBADMSG on XDR buffer overflow
0739  *   %-EMSGSIZE if the size of the array exceeds @array_size
0740  */
0741 static inline ssize_t
0742 xdr_stream_decode_uint32_array(struct xdr_stream *xdr,
0743         __u32 *array, size_t array_size)
0744 {
0745     __be32 *p;
0746     __u32 len;
0747     ssize_t retval;
0748 
0749     if (unlikely(xdr_stream_decode_u32(xdr, &len) < 0))
0750         return -EBADMSG;
0751     if (len > SIZE_MAX / sizeof(*p))
0752         return -EBADMSG;
0753     p = xdr_inline_decode(xdr, len * sizeof(*p));
0754     if (unlikely(!p))
0755         return -EBADMSG;
0756     if (array == NULL)
0757         return len;
0758     if (len <= array_size) {
0759         if (len < array_size)
0760             memset(array+len, 0, (array_size-len)*sizeof(*array));
0761         array_size = len;
0762         retval = len;
0763     } else
0764         retval = -EMSGSIZE;
0765     for (; array_size > 0; p++, array++, array_size--)
0766         *array = be32_to_cpup(p);
0767     return retval;
0768 }
0769 
0770 #endif /* _SUNRPC_XDR_H_ */