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