root/net/sunrpc/xdr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xdr_encode_netobj
  2. xdr_decode_netobj
  3. xdr_encode_opaque_fixed
  4. xdr_encode_opaque
  5. xdr_encode_string
  6. xdr_decode_string_inplace
  7. xdr_terminate_string
  8. xdr_buf_pagecount
  9. xdr_alloc_bvec
  10. xdr_free_bvec
  11. xdr_inline_pages
  12. _shift_data_right_pages
  13. _copy_to_pages
  14. _copy_from_pages
  15. xdr_shrink_bufhead
  16. xdr_shrink_pagelen
  17. xdr_shift_buf
  18. xdr_stream_pos
  19. xdr_init_encode
  20. xdr_commit_encode
  21. xdr_get_next_encode_buffer
  22. xdr_reserve_space
  23. xdr_truncate_encode
  24. xdr_restrict_buflen
  25. xdr_write_pages
  26. xdr_set_iov
  27. xdr_set_page_base
  28. xdr_set_next_page
  29. xdr_set_next_buffer
  30. xdr_init_decode
  31. xdr_init_decode_pages
  32. __xdr_inline_decode
  33. xdr_set_scratch_buffer
  34. xdr_copy_to_scratch
  35. xdr_inline_decode
  36. xdr_align_pages
  37. xdr_read_pages
  38. xdr_enter_page
  39. xdr_buf_from_iov
  40. xdr_buf_subsegment
  41. xdr_buf_trim
  42. __read_bytes_from_xdr_buf
  43. read_bytes_from_xdr_buf
  44. __write_bytes_to_xdr_buf
  45. write_bytes_to_xdr_buf
  46. xdr_decode_word
  47. xdr_encode_word
  48. xdr_buf_read_mic
  49. xdr_xcode_array2
  50. xdr_decode_array2
  51. xdr_encode_array2
  52. xdr_process_buf
  53. xdr_stream_decode_opaque
  54. xdr_stream_decode_opaque_dup
  55. xdr_stream_decode_string
  56. xdr_stream_decode_string_dup

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/net/sunrpc/xdr.c
   4  *
   5  * Generic XDR support.
   6  *
   7  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
   8  */
   9 
  10 #include <linux/module.h>
  11 #include <linux/slab.h>
  12 #include <linux/types.h>
  13 #include <linux/string.h>
  14 #include <linux/kernel.h>
  15 #include <linux/pagemap.h>
  16 #include <linux/errno.h>
  17 #include <linux/sunrpc/xdr.h>
  18 #include <linux/sunrpc/msg_prot.h>
  19 #include <linux/bvec.h>
  20 #include <trace/events/sunrpc.h>
  21 
  22 /*
  23  * XDR functions for basic NFS types
  24  */
  25 __be32 *
  26 xdr_encode_netobj(__be32 *p, const struct xdr_netobj *obj)
  27 {
  28         unsigned int    quadlen = XDR_QUADLEN(obj->len);
  29 
  30         p[quadlen] = 0;         /* zero trailing bytes */
  31         *p++ = cpu_to_be32(obj->len);
  32         memcpy(p, obj->data, obj->len);
  33         return p + XDR_QUADLEN(obj->len);
  34 }
  35 EXPORT_SYMBOL_GPL(xdr_encode_netobj);
  36 
  37 __be32 *
  38 xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj)
  39 {
  40         unsigned int    len;
  41 
  42         if ((len = be32_to_cpu(*p++)) > XDR_MAX_NETOBJ)
  43                 return NULL;
  44         obj->len  = len;
  45         obj->data = (u8 *) p;
  46         return p + XDR_QUADLEN(len);
  47 }
  48 EXPORT_SYMBOL_GPL(xdr_decode_netobj);
  49 
  50 /**
  51  * xdr_encode_opaque_fixed - Encode fixed length opaque data
  52  * @p: pointer to current position in XDR buffer.
  53  * @ptr: pointer to data to encode (or NULL)
  54  * @nbytes: size of data.
  55  *
  56  * Copy the array of data of length nbytes at ptr to the XDR buffer
  57  * at position p, then align to the next 32-bit boundary by padding
  58  * with zero bytes (see RFC1832).
  59  * Note: if ptr is NULL, only the padding is performed.
  60  *
  61  * Returns the updated current XDR buffer position
  62  *
  63  */
  64 __be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int nbytes)
  65 {
  66         if (likely(nbytes != 0)) {
  67                 unsigned int quadlen = XDR_QUADLEN(nbytes);
  68                 unsigned int padding = (quadlen << 2) - nbytes;
  69 
  70                 if (ptr != NULL)
  71                         memcpy(p, ptr, nbytes);
  72                 if (padding != 0)
  73                         memset((char *)p + nbytes, 0, padding);
  74                 p += quadlen;
  75         }
  76         return p;
  77 }
  78 EXPORT_SYMBOL_GPL(xdr_encode_opaque_fixed);
  79 
  80 /**
  81  * xdr_encode_opaque - Encode variable length opaque data
  82  * @p: pointer to current position in XDR buffer.
  83  * @ptr: pointer to data to encode (or NULL)
  84  * @nbytes: size of data.
  85  *
  86  * Returns the updated current XDR buffer position
  87  */
  88 __be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int nbytes)
  89 {
  90         *p++ = cpu_to_be32(nbytes);
  91         return xdr_encode_opaque_fixed(p, ptr, nbytes);
  92 }
  93 EXPORT_SYMBOL_GPL(xdr_encode_opaque);
  94 
  95 __be32 *
  96 xdr_encode_string(__be32 *p, const char *string)
  97 {
  98         return xdr_encode_array(p, string, strlen(string));
  99 }
 100 EXPORT_SYMBOL_GPL(xdr_encode_string);
 101 
 102 __be32 *
 103 xdr_decode_string_inplace(__be32 *p, char **sp,
 104                           unsigned int *lenp, unsigned int maxlen)
 105 {
 106         u32 len;
 107 
 108         len = be32_to_cpu(*p++);
 109         if (len > maxlen)
 110                 return NULL;
 111         *lenp = len;
 112         *sp = (char *) p;
 113         return p + XDR_QUADLEN(len);
 114 }
 115 EXPORT_SYMBOL_GPL(xdr_decode_string_inplace);
 116 
 117 /**
 118  * xdr_terminate_string - '\0'-terminate a string residing in an xdr_buf
 119  * @buf: XDR buffer where string resides
 120  * @len: length of string, in bytes
 121  *
 122  */
 123 void
 124 xdr_terminate_string(struct xdr_buf *buf, const u32 len)
 125 {
 126         char *kaddr;
 127 
 128         kaddr = kmap_atomic(buf->pages[0]);
 129         kaddr[buf->page_base + len] = '\0';
 130         kunmap_atomic(kaddr);
 131 }
 132 EXPORT_SYMBOL_GPL(xdr_terminate_string);
 133 
 134 size_t
 135 xdr_buf_pagecount(struct xdr_buf *buf)
 136 {
 137         if (!buf->page_len)
 138                 return 0;
 139         return (buf->page_base + buf->page_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
 140 }
 141 
 142 int
 143 xdr_alloc_bvec(struct xdr_buf *buf, gfp_t gfp)
 144 {
 145         size_t i, n = xdr_buf_pagecount(buf);
 146 
 147         if (n != 0 && buf->bvec == NULL) {
 148                 buf->bvec = kmalloc_array(n, sizeof(buf->bvec[0]), gfp);
 149                 if (!buf->bvec)
 150                         return -ENOMEM;
 151                 for (i = 0; i < n; i++) {
 152                         buf->bvec[i].bv_page = buf->pages[i];
 153                         buf->bvec[i].bv_len = PAGE_SIZE;
 154                         buf->bvec[i].bv_offset = 0;
 155                 }
 156         }
 157         return 0;
 158 }
 159 
 160 void
 161 xdr_free_bvec(struct xdr_buf *buf)
 162 {
 163         kfree(buf->bvec);
 164         buf->bvec = NULL;
 165 }
 166 
 167 /**
 168  * xdr_inline_pages - Prepare receive buffer for a large reply
 169  * @xdr: xdr_buf into which reply will be placed
 170  * @offset: expected offset where data payload will start, in bytes
 171  * @pages: vector of struct page pointers
 172  * @base: offset in first page where receive should start, in bytes
 173  * @len: expected size of the upper layer data payload, in bytes
 174  *
 175  */
 176 void
 177 xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
 178                  struct page **pages, unsigned int base, unsigned int len)
 179 {
 180         struct kvec *head = xdr->head;
 181         struct kvec *tail = xdr->tail;
 182         char *buf = (char *)head->iov_base;
 183         unsigned int buflen = head->iov_len;
 184 
 185         head->iov_len  = offset;
 186 
 187         xdr->pages = pages;
 188         xdr->page_base = base;
 189         xdr->page_len = len;
 190 
 191         tail->iov_base = buf + offset;
 192         tail->iov_len = buflen - offset;
 193         if ((xdr->page_len & 3) == 0)
 194                 tail->iov_len -= sizeof(__be32);
 195 
 196         xdr->buflen += len;
 197 }
 198 EXPORT_SYMBOL_GPL(xdr_inline_pages);
 199 
 200 /*
 201  * Helper routines for doing 'memmove' like operations on a struct xdr_buf
 202  */
 203 
 204 /**
 205  * _shift_data_right_pages
 206  * @pages: vector of pages containing both the source and dest memory area.
 207  * @pgto_base: page vector address of destination
 208  * @pgfrom_base: page vector address of source
 209  * @len: number of bytes to copy
 210  *
 211  * Note: the addresses pgto_base and pgfrom_base are both calculated in
 212  *       the same way:
 213  *            if a memory area starts at byte 'base' in page 'pages[i]',
 214  *            then its address is given as (i << PAGE_SHIFT) + base
 215  * Also note: pgfrom_base must be < pgto_base, but the memory areas
 216  *      they point to may overlap.
 217  */
 218 static void
 219 _shift_data_right_pages(struct page **pages, size_t pgto_base,
 220                 size_t pgfrom_base, size_t len)
 221 {
 222         struct page **pgfrom, **pgto;
 223         char *vfrom, *vto;
 224         size_t copy;
 225 
 226         BUG_ON(pgto_base <= pgfrom_base);
 227 
 228         pgto_base += len;
 229         pgfrom_base += len;
 230 
 231         pgto = pages + (pgto_base >> PAGE_SHIFT);
 232         pgfrom = pages + (pgfrom_base >> PAGE_SHIFT);
 233 
 234         pgto_base &= ~PAGE_MASK;
 235         pgfrom_base &= ~PAGE_MASK;
 236 
 237         do {
 238                 /* Are any pointers crossing a page boundary? */
 239                 if (pgto_base == 0) {
 240                         pgto_base = PAGE_SIZE;
 241                         pgto--;
 242                 }
 243                 if (pgfrom_base == 0) {
 244                         pgfrom_base = PAGE_SIZE;
 245                         pgfrom--;
 246                 }
 247 
 248                 copy = len;
 249                 if (copy > pgto_base)
 250                         copy = pgto_base;
 251                 if (copy > pgfrom_base)
 252                         copy = pgfrom_base;
 253                 pgto_base -= copy;
 254                 pgfrom_base -= copy;
 255 
 256                 vto = kmap_atomic(*pgto);
 257                 if (*pgto != *pgfrom) {
 258                         vfrom = kmap_atomic(*pgfrom);
 259                         memcpy(vto + pgto_base, vfrom + pgfrom_base, copy);
 260                         kunmap_atomic(vfrom);
 261                 } else
 262                         memmove(vto + pgto_base, vto + pgfrom_base, copy);
 263                 flush_dcache_page(*pgto);
 264                 kunmap_atomic(vto);
 265 
 266         } while ((len -= copy) != 0);
 267 }
 268 
 269 /**
 270  * _copy_to_pages
 271  * @pages: array of pages
 272  * @pgbase: page vector address of destination
 273  * @p: pointer to source data
 274  * @len: length
 275  *
 276  * Copies data from an arbitrary memory location into an array of pages
 277  * The copy is assumed to be non-overlapping.
 278  */
 279 static void
 280 _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
 281 {
 282         struct page **pgto;
 283         char *vto;
 284         size_t copy;
 285 
 286         pgto = pages + (pgbase >> PAGE_SHIFT);
 287         pgbase &= ~PAGE_MASK;
 288 
 289         for (;;) {
 290                 copy = PAGE_SIZE - pgbase;
 291                 if (copy > len)
 292                         copy = len;
 293 
 294                 vto = kmap_atomic(*pgto);
 295                 memcpy(vto + pgbase, p, copy);
 296                 kunmap_atomic(vto);
 297 
 298                 len -= copy;
 299                 if (len == 0)
 300                         break;
 301 
 302                 pgbase += copy;
 303                 if (pgbase == PAGE_SIZE) {
 304                         flush_dcache_page(*pgto);
 305                         pgbase = 0;
 306                         pgto++;
 307                 }
 308                 p += copy;
 309         }
 310         flush_dcache_page(*pgto);
 311 }
 312 
 313 /**
 314  * _copy_from_pages
 315  * @p: pointer to destination
 316  * @pages: array of pages
 317  * @pgbase: offset of source data
 318  * @len: length
 319  *
 320  * Copies data into an arbitrary memory location from an array of pages
 321  * The copy is assumed to be non-overlapping.
 322  */
 323 void
 324 _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
 325 {
 326         struct page **pgfrom;
 327         char *vfrom;
 328         size_t copy;
 329 
 330         pgfrom = pages + (pgbase >> PAGE_SHIFT);
 331         pgbase &= ~PAGE_MASK;
 332 
 333         do {
 334                 copy = PAGE_SIZE - pgbase;
 335                 if (copy > len)
 336                         copy = len;
 337 
 338                 vfrom = kmap_atomic(*pgfrom);
 339                 memcpy(p, vfrom + pgbase, copy);
 340                 kunmap_atomic(vfrom);
 341 
 342                 pgbase += copy;
 343                 if (pgbase == PAGE_SIZE) {
 344                         pgbase = 0;
 345                         pgfrom++;
 346                 }
 347                 p += copy;
 348 
 349         } while ((len -= copy) != 0);
 350 }
 351 EXPORT_SYMBOL_GPL(_copy_from_pages);
 352 
 353 /**
 354  * xdr_shrink_bufhead
 355  * @buf: xdr_buf
 356  * @len: bytes to remove from buf->head[0]
 357  *
 358  * Shrinks XDR buffer's header kvec buf->head[0] by
 359  * 'len' bytes. The extra data is not lost, but is instead
 360  * moved into the inlined pages and/or the tail.
 361  */
 362 static unsigned int
 363 xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
 364 {
 365         struct kvec *head, *tail;
 366         size_t copy, offs;
 367         unsigned int pglen = buf->page_len;
 368         unsigned int result;
 369 
 370         result = 0;
 371         tail = buf->tail;
 372         head = buf->head;
 373 
 374         WARN_ON_ONCE(len > head->iov_len);
 375         if (len > head->iov_len)
 376                 len = head->iov_len;
 377 
 378         /* Shift the tail first */
 379         if (tail->iov_len != 0) {
 380                 if (tail->iov_len > len) {
 381                         copy = tail->iov_len - len;
 382                         memmove((char *)tail->iov_base + len,
 383                                         tail->iov_base, copy);
 384                         result += copy;
 385                 }
 386                 /* Copy from the inlined pages into the tail */
 387                 copy = len;
 388                 if (copy > pglen)
 389                         copy = pglen;
 390                 offs = len - copy;
 391                 if (offs >= tail->iov_len)
 392                         copy = 0;
 393                 else if (copy > tail->iov_len - offs)
 394                         copy = tail->iov_len - offs;
 395                 if (copy != 0) {
 396                         _copy_from_pages((char *)tail->iov_base + offs,
 397                                         buf->pages,
 398                                         buf->page_base + pglen + offs - len,
 399                                         copy);
 400                         result += copy;
 401                 }
 402                 /* Do we also need to copy data from the head into the tail ? */
 403                 if (len > pglen) {
 404                         offs = copy = len - pglen;
 405                         if (copy > tail->iov_len)
 406                                 copy = tail->iov_len;
 407                         memcpy(tail->iov_base,
 408                                         (char *)head->iov_base +
 409                                         head->iov_len - offs,
 410                                         copy);
 411                         result += copy;
 412                 }
 413         }
 414         /* Now handle pages */
 415         if (pglen != 0) {
 416                 if (pglen > len)
 417                         _shift_data_right_pages(buf->pages,
 418                                         buf->page_base + len,
 419                                         buf->page_base,
 420                                         pglen - len);
 421                 copy = len;
 422                 if (len > pglen)
 423                         copy = pglen;
 424                 _copy_to_pages(buf->pages, buf->page_base,
 425                                 (char *)head->iov_base + head->iov_len - len,
 426                                 copy);
 427                 result += copy;
 428         }
 429         head->iov_len -= len;
 430         buf->buflen -= len;
 431         /* Have we truncated the message? */
 432         if (buf->len > buf->buflen)
 433                 buf->len = buf->buflen;
 434 
 435         return result;
 436 }
 437 
 438 /**
 439  * xdr_shrink_pagelen - shrinks buf->pages by up to @len bytes
 440  * @buf: xdr_buf
 441  * @len: bytes to remove from buf->pages
 442  *
 443  * The extra data is not lost, but is instead moved into buf->tail.
 444  * Returns the actual number of bytes moved.
 445  */
 446 static unsigned int
 447 xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
 448 {
 449         struct kvec *tail;
 450         size_t copy;
 451         unsigned int pglen = buf->page_len;
 452         unsigned int tailbuf_len;
 453         unsigned int result;
 454 
 455         result = 0;
 456         tail = buf->tail;
 457         if (len > buf->page_len)
 458                 len = buf-> page_len;
 459         tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len;
 460 
 461         /* Shift the tail first */
 462         if (tailbuf_len != 0) {
 463                 unsigned int free_space = tailbuf_len - tail->iov_len;
 464 
 465                 if (len < free_space)
 466                         free_space = len;
 467                 tail->iov_len += free_space;
 468 
 469                 copy = len;
 470                 if (tail->iov_len > len) {
 471                         char *p = (char *)tail->iov_base + len;
 472                         memmove(p, tail->iov_base, tail->iov_len - len);
 473                         result += tail->iov_len - len;
 474                 } else
 475                         copy = tail->iov_len;
 476                 /* Copy from the inlined pages into the tail */
 477                 _copy_from_pages((char *)tail->iov_base,
 478                                 buf->pages, buf->page_base + pglen - len,
 479                                 copy);
 480                 result += copy;
 481         }
 482         buf->page_len -= len;
 483         buf->buflen -= len;
 484         /* Have we truncated the message? */
 485         if (buf->len > buf->buflen)
 486                 buf->len = buf->buflen;
 487 
 488         return result;
 489 }
 490 
 491 void
 492 xdr_shift_buf(struct xdr_buf *buf, size_t len)
 493 {
 494         xdr_shrink_bufhead(buf, len);
 495 }
 496 EXPORT_SYMBOL_GPL(xdr_shift_buf);
 497 
 498 /**
 499  * xdr_stream_pos - Return the current offset from the start of the xdr_stream
 500  * @xdr: pointer to struct xdr_stream
 501  */
 502 unsigned int xdr_stream_pos(const struct xdr_stream *xdr)
 503 {
 504         return (unsigned int)(XDR_QUADLEN(xdr->buf->len) - xdr->nwords) << 2;
 505 }
 506 EXPORT_SYMBOL_GPL(xdr_stream_pos);
 507 
 508 /**
 509  * xdr_init_encode - Initialize a struct xdr_stream for sending data.
 510  * @xdr: pointer to xdr_stream struct
 511  * @buf: pointer to XDR buffer in which to encode data
 512  * @p: current pointer inside XDR buffer
 513  * @rqst: pointer to controlling rpc_rqst, for debugging
 514  *
 515  * Note: at the moment the RPC client only passes the length of our
 516  *       scratch buffer in the xdr_buf's header kvec. Previously this
 517  *       meant we needed to call xdr_adjust_iovec() after encoding the
 518  *       data. With the new scheme, the xdr_stream manages the details
 519  *       of the buffer length, and takes care of adjusting the kvec
 520  *       length for us.
 521  */
 522 void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
 523                      struct rpc_rqst *rqst)
 524 {
 525         struct kvec *iov = buf->head;
 526         int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
 527 
 528         xdr_set_scratch_buffer(xdr, NULL, 0);
 529         BUG_ON(scratch_len < 0);
 530         xdr->buf = buf;
 531         xdr->iov = iov;
 532         xdr->p = (__be32 *)((char *)iov->iov_base + iov->iov_len);
 533         xdr->end = (__be32 *)((char *)iov->iov_base + scratch_len);
 534         BUG_ON(iov->iov_len > scratch_len);
 535 
 536         if (p != xdr->p && p != NULL) {
 537                 size_t len;
 538 
 539                 BUG_ON(p < xdr->p || p > xdr->end);
 540                 len = (char *)p - (char *)xdr->p;
 541                 xdr->p = p;
 542                 buf->len += len;
 543                 iov->iov_len += len;
 544         }
 545         xdr->rqst = rqst;
 546 }
 547 EXPORT_SYMBOL_GPL(xdr_init_encode);
 548 
 549 /**
 550  * xdr_commit_encode - Ensure all data is written to buffer
 551  * @xdr: pointer to xdr_stream
 552  *
 553  * We handle encoding across page boundaries by giving the caller a
 554  * temporary location to write to, then later copying the data into
 555  * place; xdr_commit_encode does that copying.
 556  *
 557  * Normally the caller doesn't need to call this directly, as the
 558  * following xdr_reserve_space will do it.  But an explicit call may be
 559  * required at the end of encoding, or any other time when the xdr_buf
 560  * data might be read.
 561  */
 562 inline void xdr_commit_encode(struct xdr_stream *xdr)
 563 {
 564         int shift = xdr->scratch.iov_len;
 565         void *page;
 566 
 567         if (shift == 0)
 568                 return;
 569         page = page_address(*xdr->page_ptr);
 570         memcpy(xdr->scratch.iov_base, page, shift);
 571         memmove(page, page + shift, (void *)xdr->p - page);
 572         xdr->scratch.iov_len = 0;
 573 }
 574 EXPORT_SYMBOL_GPL(xdr_commit_encode);
 575 
 576 static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
 577                 size_t nbytes)
 578 {
 579         __be32 *p;
 580         int space_left;
 581         int frag1bytes, frag2bytes;
 582 
 583         if (nbytes > PAGE_SIZE)
 584                 goto out_overflow; /* Bigger buffers require special handling */
 585         if (xdr->buf->len + nbytes > xdr->buf->buflen)
 586                 goto out_overflow; /* Sorry, we're totally out of space */
 587         frag1bytes = (xdr->end - xdr->p) << 2;
 588         frag2bytes = nbytes - frag1bytes;
 589         if (xdr->iov)
 590                 xdr->iov->iov_len += frag1bytes;
 591         else
 592                 xdr->buf->page_len += frag1bytes;
 593         xdr->page_ptr++;
 594         xdr->iov = NULL;
 595         /*
 596          * If the last encode didn't end exactly on a page boundary, the
 597          * next one will straddle boundaries.  Encode into the next
 598          * page, then copy it back later in xdr_commit_encode.  We use
 599          * the "scratch" iov to track any temporarily unused fragment of
 600          * space at the end of the previous buffer:
 601          */
 602         xdr->scratch.iov_base = xdr->p;
 603         xdr->scratch.iov_len = frag1bytes;
 604         p = page_address(*xdr->page_ptr);
 605         /*
 606          * Note this is where the next encode will start after we've
 607          * shifted this one back:
 608          */
 609         xdr->p = (void *)p + frag2bytes;
 610         space_left = xdr->buf->buflen - xdr->buf->len;
 611         xdr->end = (void *)p + min_t(int, space_left, PAGE_SIZE);
 612         xdr->buf->page_len += frag2bytes;
 613         xdr->buf->len += nbytes;
 614         return p;
 615 out_overflow:
 616         trace_rpc_xdr_overflow(xdr, nbytes);
 617         return NULL;
 618 }
 619 
 620 /**
 621  * xdr_reserve_space - Reserve buffer space for sending
 622  * @xdr: pointer to xdr_stream
 623  * @nbytes: number of bytes to reserve
 624  *
 625  * Checks that we have enough buffer space to encode 'nbytes' more
 626  * bytes of data. If so, update the total xdr_buf length, and
 627  * adjust the length of the current kvec.
 628  */
 629 __be32 * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
 630 {
 631         __be32 *p = xdr->p;
 632         __be32 *q;
 633 
 634         xdr_commit_encode(xdr);
 635         /* align nbytes on the next 32-bit boundary */
 636         nbytes += 3;
 637         nbytes &= ~3;
 638         q = p + (nbytes >> 2);
 639         if (unlikely(q > xdr->end || q < p))
 640                 return xdr_get_next_encode_buffer(xdr, nbytes);
 641         xdr->p = q;
 642         if (xdr->iov)
 643                 xdr->iov->iov_len += nbytes;
 644         else
 645                 xdr->buf->page_len += nbytes;
 646         xdr->buf->len += nbytes;
 647         return p;
 648 }
 649 EXPORT_SYMBOL_GPL(xdr_reserve_space);
 650 
 651 /**
 652  * xdr_truncate_encode - truncate an encode buffer
 653  * @xdr: pointer to xdr_stream
 654  * @len: new length of buffer
 655  *
 656  * Truncates the xdr stream, so that xdr->buf->len == len,
 657  * and xdr->p points at offset len from the start of the buffer, and
 658  * head, tail, and page lengths are adjusted to correspond.
 659  *
 660  * If this means moving xdr->p to a different buffer, we assume that
 661  * that the end pointer should be set to the end of the current page,
 662  * except in the case of the head buffer when we assume the head
 663  * buffer's current length represents the end of the available buffer.
 664  *
 665  * This is *not* safe to use on a buffer that already has inlined page
 666  * cache pages (as in a zero-copy server read reply), except for the
 667  * simple case of truncating from one position in the tail to another.
 668  *
 669  */
 670 void xdr_truncate_encode(struct xdr_stream *xdr, size_t len)
 671 {
 672         struct xdr_buf *buf = xdr->buf;
 673         struct kvec *head = buf->head;
 674         struct kvec *tail = buf->tail;
 675         int fraglen;
 676         int new;
 677 
 678         if (len > buf->len) {
 679                 WARN_ON_ONCE(1);
 680                 return;
 681         }
 682         xdr_commit_encode(xdr);
 683 
 684         fraglen = min_t(int, buf->len - len, tail->iov_len);
 685         tail->iov_len -= fraglen;
 686         buf->len -= fraglen;
 687         if (tail->iov_len) {
 688                 xdr->p = tail->iov_base + tail->iov_len;
 689                 WARN_ON_ONCE(!xdr->end);
 690                 WARN_ON_ONCE(!xdr->iov);
 691                 return;
 692         }
 693         WARN_ON_ONCE(fraglen);
 694         fraglen = min_t(int, buf->len - len, buf->page_len);
 695         buf->page_len -= fraglen;
 696         buf->len -= fraglen;
 697 
 698         new = buf->page_base + buf->page_len;
 699 
 700         xdr->page_ptr = buf->pages + (new >> PAGE_SHIFT);
 701 
 702         if (buf->page_len) {
 703                 xdr->p = page_address(*xdr->page_ptr);
 704                 xdr->end = (void *)xdr->p + PAGE_SIZE;
 705                 xdr->p = (void *)xdr->p + (new % PAGE_SIZE);
 706                 WARN_ON_ONCE(xdr->iov);
 707                 return;
 708         }
 709         if (fraglen)
 710                 xdr->end = head->iov_base + head->iov_len;
 711         /* (otherwise assume xdr->end is already set) */
 712         xdr->page_ptr--;
 713         head->iov_len = len;
 714         buf->len = len;
 715         xdr->p = head->iov_base + head->iov_len;
 716         xdr->iov = buf->head;
 717 }
 718 EXPORT_SYMBOL(xdr_truncate_encode);
 719 
 720 /**
 721  * xdr_restrict_buflen - decrease available buffer space
 722  * @xdr: pointer to xdr_stream
 723  * @newbuflen: new maximum number of bytes available
 724  *
 725  * Adjust our idea of how much space is available in the buffer.
 726  * If we've already used too much space in the buffer, returns -1.
 727  * If the available space is already smaller than newbuflen, returns 0
 728  * and does nothing.  Otherwise, adjusts xdr->buf->buflen to newbuflen
 729  * and ensures xdr->end is set at most offset newbuflen from the start
 730  * of the buffer.
 731  */
 732 int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen)
 733 {
 734         struct xdr_buf *buf = xdr->buf;
 735         int left_in_this_buf = (void *)xdr->end - (void *)xdr->p;
 736         int end_offset = buf->len + left_in_this_buf;
 737 
 738         if (newbuflen < 0 || newbuflen < buf->len)
 739                 return -1;
 740         if (newbuflen > buf->buflen)
 741                 return 0;
 742         if (newbuflen < end_offset)
 743                 xdr->end = (void *)xdr->end + newbuflen - end_offset;
 744         buf->buflen = newbuflen;
 745         return 0;
 746 }
 747 EXPORT_SYMBOL(xdr_restrict_buflen);
 748 
 749 /**
 750  * xdr_write_pages - Insert a list of pages into an XDR buffer for sending
 751  * @xdr: pointer to xdr_stream
 752  * @pages: list of pages
 753  * @base: offset of first byte
 754  * @len: length of data in bytes
 755  *
 756  */
 757 void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int base,
 758                  unsigned int len)
 759 {
 760         struct xdr_buf *buf = xdr->buf;
 761         struct kvec *iov = buf->tail;
 762         buf->pages = pages;
 763         buf->page_base = base;
 764         buf->page_len = len;
 765 
 766         iov->iov_base = (char *)xdr->p;
 767         iov->iov_len  = 0;
 768         xdr->iov = iov;
 769 
 770         if (len & 3) {
 771                 unsigned int pad = 4 - (len & 3);
 772 
 773                 BUG_ON(xdr->p >= xdr->end);
 774                 iov->iov_base = (char *)xdr->p + (len & 3);
 775                 iov->iov_len  += pad;
 776                 len += pad;
 777                 *xdr->p++ = 0;
 778         }
 779         buf->buflen += len;
 780         buf->len += len;
 781 }
 782 EXPORT_SYMBOL_GPL(xdr_write_pages);
 783 
 784 static void xdr_set_iov(struct xdr_stream *xdr, struct kvec *iov,
 785                 unsigned int len)
 786 {
 787         if (len > iov->iov_len)
 788                 len = iov->iov_len;
 789         xdr->p = (__be32*)iov->iov_base;
 790         xdr->end = (__be32*)(iov->iov_base + len);
 791         xdr->iov = iov;
 792         xdr->page_ptr = NULL;
 793 }
 794 
 795 static int xdr_set_page_base(struct xdr_stream *xdr,
 796                 unsigned int base, unsigned int len)
 797 {
 798         unsigned int pgnr;
 799         unsigned int maxlen;
 800         unsigned int pgoff;
 801         unsigned int pgend;
 802         void *kaddr;
 803 
 804         maxlen = xdr->buf->page_len;
 805         if (base >= maxlen)
 806                 return -EINVAL;
 807         maxlen -= base;
 808         if (len > maxlen)
 809                 len = maxlen;
 810 
 811         base += xdr->buf->page_base;
 812 
 813         pgnr = base >> PAGE_SHIFT;
 814         xdr->page_ptr = &xdr->buf->pages[pgnr];
 815         kaddr = page_address(*xdr->page_ptr);
 816 
 817         pgoff = base & ~PAGE_MASK;
 818         xdr->p = (__be32*)(kaddr + pgoff);
 819 
 820         pgend = pgoff + len;
 821         if (pgend > PAGE_SIZE)
 822                 pgend = PAGE_SIZE;
 823         xdr->end = (__be32*)(kaddr + pgend);
 824         xdr->iov = NULL;
 825         return 0;
 826 }
 827 
 828 static void xdr_set_next_page(struct xdr_stream *xdr)
 829 {
 830         unsigned int newbase;
 831 
 832         newbase = (1 + xdr->page_ptr - xdr->buf->pages) << PAGE_SHIFT;
 833         newbase -= xdr->buf->page_base;
 834 
 835         if (xdr_set_page_base(xdr, newbase, PAGE_SIZE) < 0)
 836                 xdr_set_iov(xdr, xdr->buf->tail, xdr->nwords << 2);
 837 }
 838 
 839 static bool xdr_set_next_buffer(struct xdr_stream *xdr)
 840 {
 841         if (xdr->page_ptr != NULL)
 842                 xdr_set_next_page(xdr);
 843         else if (xdr->iov == xdr->buf->head) {
 844                 if (xdr_set_page_base(xdr, 0, PAGE_SIZE) < 0)
 845                         xdr_set_iov(xdr, xdr->buf->tail, xdr->nwords << 2);
 846         }
 847         return xdr->p != xdr->end;
 848 }
 849 
 850 /**
 851  * xdr_init_decode - Initialize an xdr_stream for decoding data.
 852  * @xdr: pointer to xdr_stream struct
 853  * @buf: pointer to XDR buffer from which to decode data
 854  * @p: current pointer inside XDR buffer
 855  * @rqst: pointer to controlling rpc_rqst, for debugging
 856  */
 857 void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
 858                      struct rpc_rqst *rqst)
 859 {
 860         xdr->buf = buf;
 861         xdr->scratch.iov_base = NULL;
 862         xdr->scratch.iov_len = 0;
 863         xdr->nwords = XDR_QUADLEN(buf->len);
 864         if (buf->head[0].iov_len != 0)
 865                 xdr_set_iov(xdr, buf->head, buf->len);
 866         else if (buf->page_len != 0)
 867                 xdr_set_page_base(xdr, 0, buf->len);
 868         else
 869                 xdr_set_iov(xdr, buf->head, buf->len);
 870         if (p != NULL && p > xdr->p && xdr->end >= p) {
 871                 xdr->nwords -= p - xdr->p;
 872                 xdr->p = p;
 873         }
 874         xdr->rqst = rqst;
 875 }
 876 EXPORT_SYMBOL_GPL(xdr_init_decode);
 877 
 878 /**
 879  * xdr_init_decode_pages - Initialize an xdr_stream for decoding into pages
 880  * @xdr: pointer to xdr_stream struct
 881  * @buf: pointer to XDR buffer from which to decode data
 882  * @pages: list of pages to decode into
 883  * @len: length in bytes of buffer in pages
 884  */
 885 void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf,
 886                            struct page **pages, unsigned int len)
 887 {
 888         memset(buf, 0, sizeof(*buf));
 889         buf->pages =  pages;
 890         buf->page_len =  len;
 891         buf->buflen =  len;
 892         buf->len = len;
 893         xdr_init_decode(xdr, buf, NULL, NULL);
 894 }
 895 EXPORT_SYMBOL_GPL(xdr_init_decode_pages);
 896 
 897 static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
 898 {
 899         unsigned int nwords = XDR_QUADLEN(nbytes);
 900         __be32 *p = xdr->p;
 901         __be32 *q = p + nwords;
 902 
 903         if (unlikely(nwords > xdr->nwords || q > xdr->end || q < p))
 904                 return NULL;
 905         xdr->p = q;
 906         xdr->nwords -= nwords;
 907         return p;
 908 }
 909 
 910 /**
 911  * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
 912  * @xdr: pointer to xdr_stream struct
 913  * @buf: pointer to an empty buffer
 914  * @buflen: size of 'buf'
 915  *
 916  * The scratch buffer is used when decoding from an array of pages.
 917  * If an xdr_inline_decode() call spans across page boundaries, then
 918  * we copy the data into the scratch buffer in order to allow linear
 919  * access.
 920  */
 921 void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen)
 922 {
 923         xdr->scratch.iov_base = buf;
 924         xdr->scratch.iov_len = buflen;
 925 }
 926 EXPORT_SYMBOL_GPL(xdr_set_scratch_buffer);
 927 
 928 static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes)
 929 {
 930         __be32 *p;
 931         char *cpdest = xdr->scratch.iov_base;
 932         size_t cplen = (char *)xdr->end - (char *)xdr->p;
 933 
 934         if (nbytes > xdr->scratch.iov_len)
 935                 goto out_overflow;
 936         p = __xdr_inline_decode(xdr, cplen);
 937         if (p == NULL)
 938                 return NULL;
 939         memcpy(cpdest, p, cplen);
 940         if (!xdr_set_next_buffer(xdr))
 941                 goto out_overflow;
 942         cpdest += cplen;
 943         nbytes -= cplen;
 944         p = __xdr_inline_decode(xdr, nbytes);
 945         if (p == NULL)
 946                 return NULL;
 947         memcpy(cpdest, p, nbytes);
 948         return xdr->scratch.iov_base;
 949 out_overflow:
 950         trace_rpc_xdr_overflow(xdr, nbytes);
 951         return NULL;
 952 }
 953 
 954 /**
 955  * xdr_inline_decode - Retrieve XDR data to decode
 956  * @xdr: pointer to xdr_stream struct
 957  * @nbytes: number of bytes of data to decode
 958  *
 959  * Check if the input buffer is long enough to enable us to decode
 960  * 'nbytes' more bytes of data starting at the current position.
 961  * If so return the current pointer, then update the current
 962  * pointer position.
 963  */
 964 __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
 965 {
 966         __be32 *p;
 967 
 968         if (unlikely(nbytes == 0))
 969                 return xdr->p;
 970         if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr))
 971                 goto out_overflow;
 972         p = __xdr_inline_decode(xdr, nbytes);
 973         if (p != NULL)
 974                 return p;
 975         return xdr_copy_to_scratch(xdr, nbytes);
 976 out_overflow:
 977         trace_rpc_xdr_overflow(xdr, nbytes);
 978         return NULL;
 979 }
 980 EXPORT_SYMBOL_GPL(xdr_inline_decode);
 981 
 982 static unsigned int xdr_align_pages(struct xdr_stream *xdr, unsigned int len)
 983 {
 984         struct xdr_buf *buf = xdr->buf;
 985         struct kvec *iov;
 986         unsigned int nwords = XDR_QUADLEN(len);
 987         unsigned int cur = xdr_stream_pos(xdr);
 988         unsigned int copied, offset;
 989 
 990         if (xdr->nwords == 0)
 991                 return 0;
 992 
 993         /* Realign pages to current pointer position */
 994         iov = buf->head;
 995         if (iov->iov_len > cur) {
 996                 offset = iov->iov_len - cur;
 997                 copied = xdr_shrink_bufhead(buf, offset);
 998                 trace_rpc_xdr_alignment(xdr, offset, copied);
 999                 xdr->nwords = XDR_QUADLEN(buf->len - cur);
1000         }
1001 
1002         if (nwords > xdr->nwords) {
1003                 nwords = xdr->nwords;
1004                 len = nwords << 2;
1005         }
1006         if (buf->page_len <= len)
1007                 len = buf->page_len;
1008         else if (nwords < xdr->nwords) {
1009                 /* Truncate page data and move it into the tail */
1010                 offset = buf->page_len - len;
1011                 copied = xdr_shrink_pagelen(buf, offset);
1012                 trace_rpc_xdr_alignment(xdr, offset, copied);
1013                 xdr->nwords = XDR_QUADLEN(buf->len - cur);
1014         }
1015         return len;
1016 }
1017 
1018 /**
1019  * xdr_read_pages - Ensure page-based XDR data to decode is aligned at current pointer position
1020  * @xdr: pointer to xdr_stream struct
1021  * @len: number of bytes of page data
1022  *
1023  * Moves data beyond the current pointer position from the XDR head[] buffer
1024  * into the page list. Any data that lies beyond current position + "len"
1025  * bytes is moved into the XDR tail[].
1026  *
1027  * Returns the number of XDR encoded bytes now contained in the pages
1028  */
1029 unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
1030 {
1031         struct xdr_buf *buf = xdr->buf;
1032         struct kvec *iov;
1033         unsigned int nwords;
1034         unsigned int end;
1035         unsigned int padding;
1036 
1037         len = xdr_align_pages(xdr, len);
1038         if (len == 0)
1039                 return 0;
1040         nwords = XDR_QUADLEN(len);
1041         padding = (nwords << 2) - len;
1042         xdr->iov = iov = buf->tail;
1043         /* Compute remaining message length.  */
1044         end = ((xdr->nwords - nwords) << 2) + padding;
1045         if (end > iov->iov_len)
1046                 end = iov->iov_len;
1047 
1048         /*
1049          * Position current pointer at beginning of tail, and
1050          * set remaining message length.
1051          */
1052         xdr->p = (__be32 *)((char *)iov->iov_base + padding);
1053         xdr->end = (__be32 *)((char *)iov->iov_base + end);
1054         xdr->page_ptr = NULL;
1055         xdr->nwords = XDR_QUADLEN(end - padding);
1056         return len;
1057 }
1058 EXPORT_SYMBOL_GPL(xdr_read_pages);
1059 
1060 /**
1061  * xdr_enter_page - decode data from the XDR page
1062  * @xdr: pointer to xdr_stream struct
1063  * @len: number of bytes of page data
1064  *
1065  * Moves data beyond the current pointer position from the XDR head[] buffer
1066  * into the page list. Any data that lies beyond current position + "len"
1067  * bytes is moved into the XDR tail[]. The current pointer is then
1068  * repositioned at the beginning of the first XDR page.
1069  */
1070 void xdr_enter_page(struct xdr_stream *xdr, unsigned int len)
1071 {
1072         len = xdr_align_pages(xdr, len);
1073         /*
1074          * Position current pointer at beginning of tail, and
1075          * set remaining message length.
1076          */
1077         if (len != 0)
1078                 xdr_set_page_base(xdr, 0, len);
1079 }
1080 EXPORT_SYMBOL_GPL(xdr_enter_page);
1081 
1082 static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0};
1083 
1084 void
1085 xdr_buf_from_iov(struct kvec *iov, struct xdr_buf *buf)
1086 {
1087         buf->head[0] = *iov;
1088         buf->tail[0] = empty_iov;
1089         buf->page_len = 0;
1090         buf->buflen = buf->len = iov->iov_len;
1091 }
1092 EXPORT_SYMBOL_GPL(xdr_buf_from_iov);
1093 
1094 /**
1095  * xdr_buf_subsegment - set subbuf to a portion of buf
1096  * @buf: an xdr buffer
1097  * @subbuf: the result buffer
1098  * @base: beginning of range in bytes
1099  * @len: length of range in bytes
1100  *
1101  * sets @subbuf to an xdr buffer representing the portion of @buf of
1102  * length @len starting at offset @base.
1103  *
1104  * @buf and @subbuf may be pointers to the same struct xdr_buf.
1105  *
1106  * Returns -1 if base of length are out of bounds.
1107  */
1108 int
1109 xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
1110                         unsigned int base, unsigned int len)
1111 {
1112         subbuf->buflen = subbuf->len = len;
1113         if (base < buf->head[0].iov_len) {
1114                 subbuf->head[0].iov_base = buf->head[0].iov_base + base;
1115                 subbuf->head[0].iov_len = min_t(unsigned int, len,
1116                                                 buf->head[0].iov_len - base);
1117                 len -= subbuf->head[0].iov_len;
1118                 base = 0;
1119         } else {
1120                 base -= buf->head[0].iov_len;
1121                 subbuf->head[0].iov_len = 0;
1122         }
1123 
1124         if (base < buf->page_len) {
1125                 subbuf->page_len = min(buf->page_len - base, len);
1126                 base += buf->page_base;
1127                 subbuf->page_base = base & ~PAGE_MASK;
1128                 subbuf->pages = &buf->pages[base >> PAGE_SHIFT];
1129                 len -= subbuf->page_len;
1130                 base = 0;
1131         } else {
1132                 base -= buf->page_len;
1133                 subbuf->page_len = 0;
1134         }
1135 
1136         if (base < buf->tail[0].iov_len) {
1137                 subbuf->tail[0].iov_base = buf->tail[0].iov_base + base;
1138                 subbuf->tail[0].iov_len = min_t(unsigned int, len,
1139                                                 buf->tail[0].iov_len - base);
1140                 len -= subbuf->tail[0].iov_len;
1141                 base = 0;
1142         } else {
1143                 base -= buf->tail[0].iov_len;
1144                 subbuf->tail[0].iov_len = 0;
1145         }
1146 
1147         if (base || len)
1148                 return -1;
1149         return 0;
1150 }
1151 EXPORT_SYMBOL_GPL(xdr_buf_subsegment);
1152 
1153 /**
1154  * xdr_buf_trim - lop at most "len" bytes off the end of "buf"
1155  * @buf: buf to be trimmed
1156  * @len: number of bytes to reduce "buf" by
1157  *
1158  * Trim an xdr_buf by the given number of bytes by fixing up the lengths. Note
1159  * that it's possible that we'll trim less than that amount if the xdr_buf is
1160  * too small, or if (for instance) it's all in the head and the parser has
1161  * already read too far into it.
1162  */
1163 void xdr_buf_trim(struct xdr_buf *buf, unsigned int len)
1164 {
1165         size_t cur;
1166         unsigned int trim = len;
1167 
1168         if (buf->tail[0].iov_len) {
1169                 cur = min_t(size_t, buf->tail[0].iov_len, trim);
1170                 buf->tail[0].iov_len -= cur;
1171                 trim -= cur;
1172                 if (!trim)
1173                         goto fix_len;
1174         }
1175 
1176         if (buf->page_len) {
1177                 cur = min_t(unsigned int, buf->page_len, trim);
1178                 buf->page_len -= cur;
1179                 trim -= cur;
1180                 if (!trim)
1181                         goto fix_len;
1182         }
1183 
1184         if (buf->head[0].iov_len) {
1185                 cur = min_t(size_t, buf->head[0].iov_len, trim);
1186                 buf->head[0].iov_len -= cur;
1187                 trim -= cur;
1188         }
1189 fix_len:
1190         buf->len -= (len - trim);
1191 }
1192 EXPORT_SYMBOL_GPL(xdr_buf_trim);
1193 
1194 static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len)
1195 {
1196         unsigned int this_len;
1197 
1198         this_len = min_t(unsigned int, len, subbuf->head[0].iov_len);
1199         memcpy(obj, subbuf->head[0].iov_base, this_len);
1200         len -= this_len;
1201         obj += this_len;
1202         this_len = min_t(unsigned int, len, subbuf->page_len);
1203         if (this_len)
1204                 _copy_from_pages(obj, subbuf->pages, subbuf->page_base, this_len);
1205         len -= this_len;
1206         obj += this_len;
1207         this_len = min_t(unsigned int, len, subbuf->tail[0].iov_len);
1208         memcpy(obj, subbuf->tail[0].iov_base, this_len);
1209 }
1210 
1211 /* obj is assumed to point to allocated memory of size at least len: */
1212 int read_bytes_from_xdr_buf(struct xdr_buf *buf, unsigned int base, void *obj, unsigned int len)
1213 {
1214         struct xdr_buf subbuf;
1215         int status;
1216 
1217         status = xdr_buf_subsegment(buf, &subbuf, base, len);
1218         if (status != 0)
1219                 return status;
1220         __read_bytes_from_xdr_buf(&subbuf, obj, len);
1221         return 0;
1222 }
1223 EXPORT_SYMBOL_GPL(read_bytes_from_xdr_buf);
1224 
1225 static void __write_bytes_to_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len)
1226 {
1227         unsigned int this_len;
1228 
1229         this_len = min_t(unsigned int, len, subbuf->head[0].iov_len);
1230         memcpy(subbuf->head[0].iov_base, obj, this_len);
1231         len -= this_len;
1232         obj += this_len;
1233         this_len = min_t(unsigned int, len, subbuf->page_len);
1234         if (this_len)
1235                 _copy_to_pages(subbuf->pages, subbuf->page_base, obj, this_len);
1236         len -= this_len;
1237         obj += this_len;
1238         this_len = min_t(unsigned int, len, subbuf->tail[0].iov_len);
1239         memcpy(subbuf->tail[0].iov_base, obj, this_len);
1240 }
1241 
1242 /* obj is assumed to point to allocated memory of size at least len: */
1243 int write_bytes_to_xdr_buf(struct xdr_buf *buf, unsigned int base, void *obj, unsigned int len)
1244 {
1245         struct xdr_buf subbuf;
1246         int status;
1247 
1248         status = xdr_buf_subsegment(buf, &subbuf, base, len);
1249         if (status != 0)
1250                 return status;
1251         __write_bytes_to_xdr_buf(&subbuf, obj, len);
1252         return 0;
1253 }
1254 EXPORT_SYMBOL_GPL(write_bytes_to_xdr_buf);
1255 
1256 int
1257 xdr_decode_word(struct xdr_buf *buf, unsigned int base, u32 *obj)
1258 {
1259         __be32  raw;
1260         int     status;
1261 
1262         status = read_bytes_from_xdr_buf(buf, base, &raw, sizeof(*obj));
1263         if (status)
1264                 return status;
1265         *obj = be32_to_cpu(raw);
1266         return 0;
1267 }
1268 EXPORT_SYMBOL_GPL(xdr_decode_word);
1269 
1270 int
1271 xdr_encode_word(struct xdr_buf *buf, unsigned int base, u32 obj)
1272 {
1273         __be32  raw = cpu_to_be32(obj);
1274 
1275         return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj));
1276 }
1277 EXPORT_SYMBOL_GPL(xdr_encode_word);
1278 
1279 /**
1280  * xdr_buf_read_mic() - obtain the address of the GSS mic from xdr buf
1281  * @buf: pointer to buffer containing a mic
1282  * @mic: on success, returns the address of the mic
1283  * @offset: the offset in buf where mic may be found
1284  *
1285  * This function may modify the xdr buf if the mic is found to be straddling
1286  * a boundary between head, pages, and tail.  On success the mic can be read
1287  * from the address returned.  There is no need to free the mic.
1288  *
1289  * Return: Success returns 0, otherwise an integer error.
1290  */
1291 int xdr_buf_read_mic(struct xdr_buf *buf, struct xdr_netobj *mic, unsigned int offset)
1292 {
1293         struct xdr_buf subbuf;
1294         unsigned int boundary;
1295 
1296         if (xdr_decode_word(buf, offset, &mic->len))
1297                 return -EFAULT;
1298         offset += 4;
1299 
1300         /* Is the mic partially in the head? */
1301         boundary = buf->head[0].iov_len;
1302         if (offset < boundary && (offset + mic->len) > boundary)
1303                 xdr_shift_buf(buf, boundary - offset);
1304 
1305         /* Is the mic partially in the pages? */
1306         boundary += buf->page_len;
1307         if (offset < boundary && (offset + mic->len) > boundary)
1308                 xdr_shrink_pagelen(buf, boundary - offset);
1309 
1310         if (xdr_buf_subsegment(buf, &subbuf, offset, mic->len))
1311                 return -EFAULT;
1312 
1313         /* Is the mic contained entirely in the head? */
1314         mic->data = subbuf.head[0].iov_base;
1315         if (subbuf.head[0].iov_len == mic->len)
1316                 return 0;
1317         /* ..or is the mic contained entirely in the tail? */
1318         mic->data = subbuf.tail[0].iov_base;
1319         if (subbuf.tail[0].iov_len == mic->len)
1320                 return 0;
1321 
1322         /* Find a contiguous area in @buf to hold all of @mic */
1323         if (mic->len > buf->buflen - buf->len)
1324                 return -ENOMEM;
1325         if (buf->tail[0].iov_len != 0)
1326                 mic->data = buf->tail[0].iov_base + buf->tail[0].iov_len;
1327         else
1328                 mic->data = buf->head[0].iov_base + buf->head[0].iov_len;
1329         __read_bytes_from_xdr_buf(&subbuf, mic->data, mic->len);
1330         return 0;
1331 }
1332 EXPORT_SYMBOL_GPL(xdr_buf_read_mic);
1333 
1334 /* Returns 0 on success, or else a negative error code. */
1335 static int
1336 xdr_xcode_array2(struct xdr_buf *buf, unsigned int base,
1337                  struct xdr_array2_desc *desc, int encode)
1338 {
1339         char *elem = NULL, *c;
1340         unsigned int copied = 0, todo, avail_here;
1341         struct page **ppages = NULL;
1342         int err;
1343 
1344         if (encode) {
1345                 if (xdr_encode_word(buf, base, desc->array_len) != 0)
1346                         return -EINVAL;
1347         } else {
1348                 if (xdr_decode_word(buf, base, &desc->array_len) != 0 ||
1349                     desc->array_len > desc->array_maxlen ||
1350                     (unsigned long) base + 4 + desc->array_len *
1351                                     desc->elem_size > buf->len)
1352                         return -EINVAL;
1353         }
1354         base += 4;
1355 
1356         if (!desc->xcode)
1357                 return 0;
1358 
1359         todo = desc->array_len * desc->elem_size;
1360 
1361         /* process head */
1362         if (todo && base < buf->head->iov_len) {
1363                 c = buf->head->iov_base + base;
1364                 avail_here = min_t(unsigned int, todo,
1365                                    buf->head->iov_len - base);
1366                 todo -= avail_here;
1367 
1368                 while (avail_here >= desc->elem_size) {
1369                         err = desc->xcode(desc, c);
1370                         if (err)
1371                                 goto out;
1372                         c += desc->elem_size;
1373                         avail_here -= desc->elem_size;
1374                 }
1375                 if (avail_here) {
1376                         if (!elem) {
1377                                 elem = kmalloc(desc->elem_size, GFP_KERNEL);
1378                                 err = -ENOMEM;
1379                                 if (!elem)
1380                                         goto out;
1381                         }
1382                         if (encode) {
1383                                 err = desc->xcode(desc, elem);
1384                                 if (err)
1385                                         goto out;
1386                                 memcpy(c, elem, avail_here);
1387                         } else
1388                                 memcpy(elem, c, avail_here);
1389                         copied = avail_here;
1390                 }
1391                 base = buf->head->iov_len;  /* align to start of pages */
1392         }
1393 
1394         /* process pages array */
1395         base -= buf->head->iov_len;
1396         if (todo && base < buf->page_len) {
1397                 unsigned int avail_page;
1398 
1399                 avail_here = min(todo, buf->page_len - base);
1400                 todo -= avail_here;
1401 
1402                 base += buf->page_base;
1403                 ppages = buf->pages + (base >> PAGE_SHIFT);
1404                 base &= ~PAGE_MASK;
1405                 avail_page = min_t(unsigned int, PAGE_SIZE - base,
1406                                         avail_here);
1407                 c = kmap(*ppages) + base;
1408 
1409                 while (avail_here) {
1410                         avail_here -= avail_page;
1411                         if (copied || avail_page < desc->elem_size) {
1412                                 unsigned int l = min(avail_page,
1413                                         desc->elem_size - copied);
1414                                 if (!elem) {
1415                                         elem = kmalloc(desc->elem_size,
1416                                                        GFP_KERNEL);
1417                                         err = -ENOMEM;
1418                                         if (!elem)
1419                                                 goto out;
1420                                 }
1421                                 if (encode) {
1422                                         if (!copied) {
1423                                                 err = desc->xcode(desc, elem);
1424                                                 if (err)
1425                                                         goto out;
1426                                         }
1427                                         memcpy(c, elem + copied, l);
1428                                         copied += l;
1429                                         if (copied == desc->elem_size)
1430                                                 copied = 0;
1431                                 } else {
1432                                         memcpy(elem + copied, c, l);
1433                                         copied += l;
1434                                         if (copied == desc->elem_size) {
1435                                                 err = desc->xcode(desc, elem);
1436                                                 if (err)
1437                                                         goto out;
1438                                                 copied = 0;
1439                                         }
1440                                 }
1441                                 avail_page -= l;
1442                                 c += l;
1443                         }
1444                         while (avail_page >= desc->elem_size) {
1445                                 err = desc->xcode(desc, c);
1446                                 if (err)
1447                                         goto out;
1448                                 c += desc->elem_size;
1449                                 avail_page -= desc->elem_size;
1450                         }
1451                         if (avail_page) {
1452                                 unsigned int l = min(avail_page,
1453                                             desc->elem_size - copied);
1454                                 if (!elem) {
1455                                         elem = kmalloc(desc->elem_size,
1456                                                        GFP_KERNEL);
1457                                         err = -ENOMEM;
1458                                         if (!elem)
1459                                                 goto out;
1460                                 }
1461                                 if (encode) {
1462                                         if (!copied) {
1463                                                 err = desc->xcode(desc, elem);
1464                                                 if (err)
1465                                                         goto out;
1466                                         }
1467                                         memcpy(c, elem + copied, l);
1468                                         copied += l;
1469                                         if (copied == desc->elem_size)
1470                                                 copied = 0;
1471                                 } else {
1472                                         memcpy(elem + copied, c, l);
1473                                         copied += l;
1474                                         if (copied == desc->elem_size) {
1475                                                 err = desc->xcode(desc, elem);
1476                                                 if (err)
1477                                                         goto out;
1478                                                 copied = 0;
1479                                         }
1480                                 }
1481                         }
1482                         if (avail_here) {
1483                                 kunmap(*ppages);
1484                                 ppages++;
1485                                 c = kmap(*ppages);
1486                         }
1487 
1488                         avail_page = min(avail_here,
1489                                  (unsigned int) PAGE_SIZE);
1490                 }
1491                 base = buf->page_len;  /* align to start of tail */
1492         }
1493 
1494         /* process tail */
1495         base -= buf->page_len;
1496         if (todo) {
1497                 c = buf->tail->iov_base + base;
1498                 if (copied) {
1499                         unsigned int l = desc->elem_size - copied;
1500 
1501                         if (encode)
1502                                 memcpy(c, elem + copied, l);
1503                         else {
1504                                 memcpy(elem + copied, c, l);
1505                                 err = desc->xcode(desc, elem);
1506                                 if (err)
1507                                         goto out;
1508                         }
1509                         todo -= l;
1510                         c += l;
1511                 }
1512                 while (todo) {
1513                         err = desc->xcode(desc, c);
1514                         if (err)
1515                                 goto out;
1516                         c += desc->elem_size;
1517                         todo -= desc->elem_size;
1518                 }
1519         }
1520         err = 0;
1521 
1522 out:
1523         kfree(elem);
1524         if (ppages)
1525                 kunmap(*ppages);
1526         return err;
1527 }
1528 
1529 int
1530 xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
1531                   struct xdr_array2_desc *desc)
1532 {
1533         if (base >= buf->len)
1534                 return -EINVAL;
1535 
1536         return xdr_xcode_array2(buf, base, desc, 0);
1537 }
1538 EXPORT_SYMBOL_GPL(xdr_decode_array2);
1539 
1540 int
1541 xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
1542                   struct xdr_array2_desc *desc)
1543 {
1544         if ((unsigned long) base + 4 + desc->array_len * desc->elem_size >
1545             buf->head->iov_len + buf->page_len + buf->tail->iov_len)
1546                 return -EINVAL;
1547 
1548         return xdr_xcode_array2(buf, base, desc, 1);
1549 }
1550 EXPORT_SYMBOL_GPL(xdr_encode_array2);
1551 
1552 int
1553 xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
1554                 int (*actor)(struct scatterlist *, void *), void *data)
1555 {
1556         int i, ret = 0;
1557         unsigned int page_len, thislen, page_offset;
1558         struct scatterlist      sg[1];
1559 
1560         sg_init_table(sg, 1);
1561 
1562         if (offset >= buf->head[0].iov_len) {
1563                 offset -= buf->head[0].iov_len;
1564         } else {
1565                 thislen = buf->head[0].iov_len - offset;
1566                 if (thislen > len)
1567                         thislen = len;
1568                 sg_set_buf(sg, buf->head[0].iov_base + offset, thislen);
1569                 ret = actor(sg, data);
1570                 if (ret)
1571                         goto out;
1572                 offset = 0;
1573                 len -= thislen;
1574         }
1575         if (len == 0)
1576                 goto out;
1577 
1578         if (offset >= buf->page_len) {
1579                 offset -= buf->page_len;
1580         } else {
1581                 page_len = buf->page_len - offset;
1582                 if (page_len > len)
1583                         page_len = len;
1584                 len -= page_len;
1585                 page_offset = (offset + buf->page_base) & (PAGE_SIZE - 1);
1586                 i = (offset + buf->page_base) >> PAGE_SHIFT;
1587                 thislen = PAGE_SIZE - page_offset;
1588                 do {
1589                         if (thislen > page_len)
1590                                 thislen = page_len;
1591                         sg_set_page(sg, buf->pages[i], thislen, page_offset);
1592                         ret = actor(sg, data);
1593                         if (ret)
1594                                 goto out;
1595                         page_len -= thislen;
1596                         i++;
1597                         page_offset = 0;
1598                         thislen = PAGE_SIZE;
1599                 } while (page_len != 0);
1600                 offset = 0;
1601         }
1602         if (len == 0)
1603                 goto out;
1604         if (offset < buf->tail[0].iov_len) {
1605                 thislen = buf->tail[0].iov_len - offset;
1606                 if (thislen > len)
1607                         thislen = len;
1608                 sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen);
1609                 ret = actor(sg, data);
1610                 len -= thislen;
1611         }
1612         if (len != 0)
1613                 ret = -EINVAL;
1614 out:
1615         return ret;
1616 }
1617 EXPORT_SYMBOL_GPL(xdr_process_buf);
1618 
1619 /**
1620  * xdr_stream_decode_opaque - Decode variable length opaque
1621  * @xdr: pointer to xdr_stream
1622  * @ptr: location to store opaque data
1623  * @size: size of storage buffer @ptr
1624  *
1625  * Return values:
1626  *   On success, returns size of object stored in *@ptr
1627  *   %-EBADMSG on XDR buffer overflow
1628  *   %-EMSGSIZE on overflow of storage buffer @ptr
1629  */
1630 ssize_t xdr_stream_decode_opaque(struct xdr_stream *xdr, void *ptr, size_t size)
1631 {
1632         ssize_t ret;
1633         void *p;
1634 
1635         ret = xdr_stream_decode_opaque_inline(xdr, &p, size);
1636         if (ret <= 0)
1637                 return ret;
1638         memcpy(ptr, p, ret);
1639         return ret;
1640 }
1641 EXPORT_SYMBOL_GPL(xdr_stream_decode_opaque);
1642 
1643 /**
1644  * xdr_stream_decode_opaque_dup - Decode and duplicate variable length opaque
1645  * @xdr: pointer to xdr_stream
1646  * @ptr: location to store pointer to opaque data
1647  * @maxlen: maximum acceptable object size
1648  * @gfp_flags: GFP mask to use
1649  *
1650  * Return values:
1651  *   On success, returns size of object stored in *@ptr
1652  *   %-EBADMSG on XDR buffer overflow
1653  *   %-EMSGSIZE if the size of the object would exceed @maxlen
1654  *   %-ENOMEM on memory allocation failure
1655  */
1656 ssize_t xdr_stream_decode_opaque_dup(struct xdr_stream *xdr, void **ptr,
1657                 size_t maxlen, gfp_t gfp_flags)
1658 {
1659         ssize_t ret;
1660         void *p;
1661 
1662         ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
1663         if (ret > 0) {
1664                 *ptr = kmemdup(p, ret, gfp_flags);
1665                 if (*ptr != NULL)
1666                         return ret;
1667                 ret = -ENOMEM;
1668         }
1669         *ptr = NULL;
1670         return ret;
1671 }
1672 EXPORT_SYMBOL_GPL(xdr_stream_decode_opaque_dup);
1673 
1674 /**
1675  * xdr_stream_decode_string - Decode variable length string
1676  * @xdr: pointer to xdr_stream
1677  * @str: location to store string
1678  * @size: size of storage buffer @str
1679  *
1680  * Return values:
1681  *   On success, returns length of NUL-terminated string stored in *@str
1682  *   %-EBADMSG on XDR buffer overflow
1683  *   %-EMSGSIZE on overflow of storage buffer @str
1684  */
1685 ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str, size_t size)
1686 {
1687         ssize_t ret;
1688         void *p;
1689 
1690         ret = xdr_stream_decode_opaque_inline(xdr, &p, size);
1691         if (ret > 0) {
1692                 memcpy(str, p, ret);
1693                 str[ret] = '\0';
1694                 return strlen(str);
1695         }
1696         *str = '\0';
1697         return ret;
1698 }
1699 EXPORT_SYMBOL_GPL(xdr_stream_decode_string);
1700 
1701 /**
1702  * xdr_stream_decode_string_dup - Decode and duplicate variable length string
1703  * @xdr: pointer to xdr_stream
1704  * @str: location to store pointer to string
1705  * @maxlen: maximum acceptable string length
1706  * @gfp_flags: GFP mask to use
1707  *
1708  * Return values:
1709  *   On success, returns length of NUL-terminated string stored in *@ptr
1710  *   %-EBADMSG on XDR buffer overflow
1711  *   %-EMSGSIZE if the size of the string would exceed @maxlen
1712  *   %-ENOMEM on memory allocation failure
1713  */
1714 ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
1715                 size_t maxlen, gfp_t gfp_flags)
1716 {
1717         void *p;
1718         ssize_t ret;
1719 
1720         ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
1721         if (ret > 0) {
1722                 char *s = kmalloc(ret + 1, gfp_flags);
1723                 if (s != NULL) {
1724                         memcpy(s, p, ret);
1725                         s[ret] = '\0';
1726                         *str = s;
1727                         return strlen(s);
1728                 }
1729                 ret = -ENOMEM;
1730         }
1731         *str = NULL;
1732         return ret;
1733 }
1734 EXPORT_SYMBOL_GPL(xdr_stream_decode_string_dup);

/* [<][>][^][v][top][bottom][index][help] */