linux/net/sunrpc/xdr.c
<<
>>
Prefs
   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
  22static void _copy_to_pages(struct page **, size_t, const char *, size_t);
  23
  24
  25/*
  26 * XDR functions for basic NFS types
  27 */
  28__be32 *
  29xdr_encode_netobj(__be32 *p, const struct xdr_netobj *obj)
  30{
  31        unsigned int    quadlen = XDR_QUADLEN(obj->len);
  32
  33        p[quadlen] = 0;         /* zero trailing bytes */
  34        *p++ = cpu_to_be32(obj->len);
  35        memcpy(p, obj->data, obj->len);
  36        return p + XDR_QUADLEN(obj->len);
  37}
  38EXPORT_SYMBOL_GPL(xdr_encode_netobj);
  39
  40__be32 *
  41xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj)
  42{
  43        unsigned int    len;
  44
  45        if ((len = be32_to_cpu(*p++)) > XDR_MAX_NETOBJ)
  46                return NULL;
  47        obj->len  = len;
  48        obj->data = (u8 *) p;
  49        return p + XDR_QUADLEN(len);
  50}
  51EXPORT_SYMBOL_GPL(xdr_decode_netobj);
  52
  53/**
  54 * xdr_encode_opaque_fixed - Encode fixed length opaque data
  55 * @p: pointer to current position in XDR buffer.
  56 * @ptr: pointer to data to encode (or NULL)
  57 * @nbytes: size of data.
  58 *
  59 * Copy the array of data of length nbytes at ptr to the XDR buffer
  60 * at position p, then align to the next 32-bit boundary by padding
  61 * with zero bytes (see RFC1832).
  62 * Note: if ptr is NULL, only the padding is performed.
  63 *
  64 * Returns the updated current XDR buffer position
  65 *
  66 */
  67__be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int nbytes)
  68{
  69        if (likely(nbytes != 0)) {
  70                unsigned int quadlen = XDR_QUADLEN(nbytes);
  71                unsigned int padding = (quadlen << 2) - nbytes;
  72
  73                if (ptr != NULL)
  74                        memcpy(p, ptr, nbytes);
  75                if (padding != 0)
  76                        memset((char *)p + nbytes, 0, padding);
  77                p += quadlen;
  78        }
  79        return p;
  80}
  81EXPORT_SYMBOL_GPL(xdr_encode_opaque_fixed);
  82
  83/**
  84 * xdr_encode_opaque - Encode variable length opaque data
  85 * @p: pointer to current position in XDR buffer.
  86 * @ptr: pointer to data to encode (or NULL)
  87 * @nbytes: size of data.
  88 *
  89 * Returns the updated current XDR buffer position
  90 */
  91__be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int nbytes)
  92{
  93        *p++ = cpu_to_be32(nbytes);
  94        return xdr_encode_opaque_fixed(p, ptr, nbytes);
  95}
  96EXPORT_SYMBOL_GPL(xdr_encode_opaque);
  97
  98__be32 *
  99xdr_encode_string(__be32 *p, const char *string)
 100{
 101        return xdr_encode_array(p, string, strlen(string));
 102}
 103EXPORT_SYMBOL_GPL(xdr_encode_string);
 104
 105__be32 *
 106xdr_decode_string_inplace(__be32 *p, char **sp,
 107                          unsigned int *lenp, unsigned int maxlen)
 108{
 109        u32 len;
 110
 111        len = be32_to_cpu(*p++);
 112        if (len > maxlen)
 113                return NULL;
 114        *lenp = len;
 115        *sp = (char *) p;
 116        return p + XDR_QUADLEN(len);
 117}
 118EXPORT_SYMBOL_GPL(xdr_decode_string_inplace);
 119
 120/**
 121 * xdr_terminate_string - '\0'-terminate a string residing in an xdr_buf
 122 * @buf: XDR buffer where string resides
 123 * @len: length of string, in bytes
 124 *
 125 */
 126void xdr_terminate_string(const struct xdr_buf *buf, const u32 len)
 127{
 128        char *kaddr;
 129
 130        kaddr = kmap_atomic(buf->pages[0]);
 131        kaddr[buf->page_base + len] = '\0';
 132        kunmap_atomic(kaddr);
 133}
 134EXPORT_SYMBOL_GPL(xdr_terminate_string);
 135
 136size_t xdr_buf_pagecount(const struct xdr_buf *buf)
 137{
 138        if (!buf->page_len)
 139                return 0;
 140        return (buf->page_base + buf->page_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
 141}
 142
 143int
 144xdr_alloc_bvec(struct xdr_buf *buf, gfp_t gfp)
 145{
 146        size_t i, n = xdr_buf_pagecount(buf);
 147
 148        if (n != 0 && buf->bvec == NULL) {
 149                buf->bvec = kmalloc_array(n, sizeof(buf->bvec[0]), gfp);
 150                if (!buf->bvec)
 151                        return -ENOMEM;
 152                for (i = 0; i < n; i++) {
 153                        buf->bvec[i].bv_page = buf->pages[i];
 154                        buf->bvec[i].bv_len = PAGE_SIZE;
 155                        buf->bvec[i].bv_offset = 0;
 156                }
 157        }
 158        return 0;
 159}
 160
 161void
 162xdr_free_bvec(struct xdr_buf *buf)
 163{
 164        kfree(buf->bvec);
 165        buf->bvec = NULL;
 166}
 167
 168/**
 169 * xdr_inline_pages - Prepare receive buffer for a large reply
 170 * @xdr: xdr_buf into which reply will be placed
 171 * @offset: expected offset where data payload will start, in bytes
 172 * @pages: vector of struct page pointers
 173 * @base: offset in first page where receive should start, in bytes
 174 * @len: expected size of the upper layer data payload, in bytes
 175 *
 176 */
 177void
 178xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
 179                 struct page **pages, unsigned int base, unsigned int len)
 180{
 181        struct kvec *head = xdr->head;
 182        struct kvec *tail = xdr->tail;
 183        char *buf = (char *)head->iov_base;
 184        unsigned int buflen = head->iov_len;
 185
 186        head->iov_len  = offset;
 187
 188        xdr->pages = pages;
 189        xdr->page_base = base;
 190        xdr->page_len = len;
 191
 192        tail->iov_base = buf + offset;
 193        tail->iov_len = buflen - offset;
 194        xdr->buflen += len;
 195}
 196EXPORT_SYMBOL_GPL(xdr_inline_pages);
 197
 198/*
 199 * Helper routines for doing 'memmove' like operations on a struct xdr_buf
 200 */
 201
 202/**
 203 * _shift_data_left_pages
 204 * @pages: vector of pages containing both the source and dest memory area.
 205 * @pgto_base: page vector address of destination
 206 * @pgfrom_base: page vector address of source
 207 * @len: number of bytes to copy
 208 *
 209 * Note: the addresses pgto_base and pgfrom_base are both calculated in
 210 *       the same way:
 211 *            if a memory area starts at byte 'base' in page 'pages[i]',
 212 *            then its address is given as (i << PAGE_CACHE_SHIFT) + base
 213 * Alse note: pgto_base must be < pgfrom_base, but the memory areas
 214 *      they point to may overlap.
 215 */
 216static void
 217_shift_data_left_pages(struct page **pages, size_t pgto_base,
 218                        size_t pgfrom_base, size_t len)
 219{
 220        struct page **pgfrom, **pgto;
 221        char *vfrom, *vto;
 222        size_t copy;
 223
 224        BUG_ON(pgfrom_base <= pgto_base);
 225
 226        if (!len)
 227                return;
 228
 229        pgto = pages + (pgto_base >> PAGE_SHIFT);
 230        pgfrom = pages + (pgfrom_base >> PAGE_SHIFT);
 231
 232        pgto_base &= ~PAGE_MASK;
 233        pgfrom_base &= ~PAGE_MASK;
 234
 235        do {
 236                if (pgto_base >= PAGE_SIZE) {
 237                        pgto_base = 0;
 238                        pgto++;
 239                }
 240                if (pgfrom_base >= PAGE_SIZE){
 241                        pgfrom_base = 0;
 242                        pgfrom++;
 243                }
 244
 245                copy = len;
 246                if (copy > (PAGE_SIZE - pgto_base))
 247                        copy = PAGE_SIZE - pgto_base;
 248                if (copy > (PAGE_SIZE - pgfrom_base))
 249                        copy = PAGE_SIZE - pgfrom_base;
 250
 251                vto = kmap_atomic(*pgto);
 252                if (*pgto != *pgfrom) {
 253                        vfrom = kmap_atomic(*pgfrom);
 254                        memcpy(vto + pgto_base, vfrom + pgfrom_base, copy);
 255                        kunmap_atomic(vfrom);
 256                } else
 257                        memmove(vto + pgto_base, vto + pgfrom_base, copy);
 258                flush_dcache_page(*pgto);
 259                kunmap_atomic(vto);
 260
 261                pgto_base += copy;
 262                pgfrom_base += copy;
 263
 264        } while ((len -= copy) != 0);
 265}
 266
 267/**
 268 * _shift_data_right_pages
 269 * @pages: vector of pages containing both the source and dest memory area.
 270 * @pgto_base: page vector address of destination
 271 * @pgfrom_base: page vector address of source
 272 * @len: number of bytes to copy
 273 *
 274 * Note: the addresses pgto_base and pgfrom_base are both calculated in
 275 *       the same way:
 276 *            if a memory area starts at byte 'base' in page 'pages[i]',
 277 *            then its address is given as (i << PAGE_SHIFT) + base
 278 * Also note: pgfrom_base must be < pgto_base, but the memory areas
 279 *      they point to may overlap.
 280 */
 281static void
 282_shift_data_right_pages(struct page **pages, size_t pgto_base,
 283                size_t pgfrom_base, size_t len)
 284{
 285        struct page **pgfrom, **pgto;
 286        char *vfrom, *vto;
 287        size_t copy;
 288
 289        BUG_ON(pgto_base <= pgfrom_base);
 290
 291        if (!len)
 292                return;
 293
 294        pgto_base += len;
 295        pgfrom_base += len;
 296
 297        pgto = pages + (pgto_base >> PAGE_SHIFT);
 298        pgfrom = pages + (pgfrom_base >> PAGE_SHIFT);
 299
 300        pgto_base &= ~PAGE_MASK;
 301        pgfrom_base &= ~PAGE_MASK;
 302
 303        do {
 304                /* Are any pointers crossing a page boundary? */
 305                if (pgto_base == 0) {
 306                        pgto_base = PAGE_SIZE;
 307                        pgto--;
 308                }
 309                if (pgfrom_base == 0) {
 310                        pgfrom_base = PAGE_SIZE;
 311                        pgfrom--;
 312                }
 313
 314                copy = len;
 315                if (copy > pgto_base)
 316                        copy = pgto_base;
 317                if (copy > pgfrom_base)
 318                        copy = pgfrom_base;
 319                pgto_base -= copy;
 320                pgfrom_base -= copy;
 321
 322                vto = kmap_atomic(*pgto);
 323                if (*pgto != *pgfrom) {
 324                        vfrom = kmap_atomic(*pgfrom);
 325                        memcpy(vto + pgto_base, vfrom + pgfrom_base, copy);
 326                        kunmap_atomic(vfrom);
 327                } else
 328                        memmove(vto + pgto_base, vto + pgfrom_base, copy);
 329                flush_dcache_page(*pgto);
 330                kunmap_atomic(vto);
 331
 332        } while ((len -= copy) != 0);
 333}
 334
 335/**
 336 * _copy_to_pages
 337 * @pages: array of pages
 338 * @pgbase: page vector address of destination
 339 * @p: pointer to source data
 340 * @len: length
 341 *
 342 * Copies data from an arbitrary memory location into an array of pages
 343 * The copy is assumed to be non-overlapping.
 344 */
 345static void
 346_copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
 347{
 348        struct page **pgto;
 349        char *vto;
 350        size_t copy;
 351
 352        if (!len)
 353                return;
 354
 355        pgto = pages + (pgbase >> PAGE_SHIFT);
 356        pgbase &= ~PAGE_MASK;
 357
 358        for (;;) {
 359                copy = PAGE_SIZE - pgbase;
 360                if (copy > len)
 361                        copy = len;
 362
 363                vto = kmap_atomic(*pgto);
 364                memcpy(vto + pgbase, p, copy);
 365                kunmap_atomic(vto);
 366
 367                len -= copy;
 368                if (len == 0)
 369                        break;
 370
 371                pgbase += copy;
 372                if (pgbase == PAGE_SIZE) {
 373                        flush_dcache_page(*pgto);
 374                        pgbase = 0;
 375                        pgto++;
 376                }
 377                p += copy;
 378        }
 379        flush_dcache_page(*pgto);
 380}
 381
 382/**
 383 * _copy_from_pages
 384 * @p: pointer to destination
 385 * @pages: array of pages
 386 * @pgbase: offset of source data
 387 * @len: length
 388 *
 389 * Copies data into an arbitrary memory location from an array of pages
 390 * The copy is assumed to be non-overlapping.
 391 */
 392void
 393_copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
 394{
 395        struct page **pgfrom;
 396        char *vfrom;
 397        size_t copy;
 398
 399        if (!len)
 400                return;
 401
 402        pgfrom = pages + (pgbase >> PAGE_SHIFT);
 403        pgbase &= ~PAGE_MASK;
 404
 405        do {
 406                copy = PAGE_SIZE - pgbase;
 407                if (copy > len)
 408                        copy = len;
 409
 410                vfrom = kmap_atomic(*pgfrom);
 411                memcpy(p, vfrom + pgbase, copy);
 412                kunmap_atomic(vfrom);
 413
 414                pgbase += copy;
 415                if (pgbase == PAGE_SIZE) {
 416                        pgbase = 0;
 417                        pgfrom++;
 418                }
 419                p += copy;
 420
 421        } while ((len -= copy) != 0);
 422}
 423EXPORT_SYMBOL_GPL(_copy_from_pages);
 424
 425static void xdr_buf_iov_zero(const struct kvec *iov, unsigned int base,
 426                             unsigned int len)
 427{
 428        if (base >= iov->iov_len)
 429                return;
 430        if (len > iov->iov_len - base)
 431                len = iov->iov_len - base;
 432        memset(iov->iov_base + base, 0, len);
 433}
 434
 435/**
 436 * xdr_buf_pages_zero
 437 * @buf: xdr_buf
 438 * @pgbase: beginning offset
 439 * @len: length
 440 */
 441static void xdr_buf_pages_zero(const struct xdr_buf *buf, unsigned int pgbase,
 442                               unsigned int len)
 443{
 444        struct page **pages = buf->pages;
 445        struct page **page;
 446        char *vpage;
 447        unsigned int zero;
 448
 449        if (!len)
 450                return;
 451        if (pgbase >= buf->page_len) {
 452                xdr_buf_iov_zero(buf->tail, pgbase - buf->page_len, len);
 453                return;
 454        }
 455        if (pgbase + len > buf->page_len) {
 456                xdr_buf_iov_zero(buf->tail, 0, pgbase + len - buf->page_len);
 457                len = buf->page_len - pgbase;
 458        }
 459
 460        pgbase += buf->page_base;
 461
 462        page = pages + (pgbase >> PAGE_SHIFT);
 463        pgbase &= ~PAGE_MASK;
 464
 465        do {
 466                zero = PAGE_SIZE - pgbase;
 467                if (zero > len)
 468                        zero = len;
 469
 470                vpage = kmap_atomic(*page);
 471                memset(vpage + pgbase, 0, zero);
 472                kunmap_atomic(vpage);
 473
 474                flush_dcache_page(*page);
 475                pgbase = 0;
 476                page++;
 477
 478        } while ((len -= zero) != 0);
 479}
 480
 481static unsigned int xdr_buf_pages_fill_sparse(const struct xdr_buf *buf,
 482                                              unsigned int buflen, gfp_t gfp)
 483{
 484        unsigned int i, npages, pagelen;
 485
 486        if (!(buf->flags & XDRBUF_SPARSE_PAGES))
 487                return buflen;
 488        if (buflen <= buf->head->iov_len)
 489                return buflen;
 490        pagelen = buflen - buf->head->iov_len;
 491        if (pagelen > buf->page_len)
 492                pagelen = buf->page_len;
 493        npages = (pagelen + buf->page_base + PAGE_SIZE - 1) >> PAGE_SHIFT;
 494        for (i = 0; i < npages; i++) {
 495                if (!buf->pages[i])
 496                        continue;
 497                buf->pages[i] = alloc_page(gfp);
 498                if (likely(buf->pages[i]))
 499                        continue;
 500                buflen -= pagelen;
 501                pagelen = i << PAGE_SHIFT;
 502                if (pagelen > buf->page_base)
 503                        buflen += pagelen - buf->page_base;
 504                break;
 505        }
 506        return buflen;
 507}
 508
 509static void xdr_buf_try_expand(struct xdr_buf *buf, unsigned int len)
 510{
 511        struct kvec *head = buf->head;
 512        struct kvec *tail = buf->tail;
 513        unsigned int sum = head->iov_len + buf->page_len + tail->iov_len;
 514        unsigned int free_space, newlen;
 515
 516        if (sum > buf->len) {
 517                free_space = min_t(unsigned int, sum - buf->len, len);
 518                newlen = xdr_buf_pages_fill_sparse(buf, buf->len + free_space,
 519                                                   GFP_KERNEL);
 520                free_space = newlen - buf->len;
 521                buf->len = newlen;
 522                len -= free_space;
 523                if (!len)
 524                        return;
 525        }
 526
 527        if (buf->buflen > sum) {
 528                /* Expand the tail buffer */
 529                free_space = min_t(unsigned int, buf->buflen - sum, len);
 530                tail->iov_len += free_space;
 531                buf->len += free_space;
 532        }
 533}
 534
 535static void xdr_buf_tail_copy_right(const struct xdr_buf *buf,
 536                                    unsigned int base, unsigned int len,
 537                                    unsigned int shift)
 538{
 539        const struct kvec *tail = buf->tail;
 540        unsigned int to = base + shift;
 541
 542        if (to >= tail->iov_len)
 543                return;
 544        if (len + to > tail->iov_len)
 545                len = tail->iov_len - to;
 546        memmove(tail->iov_base + to, tail->iov_base + base, len);
 547}
 548
 549static void xdr_buf_pages_copy_right(const struct xdr_buf *buf,
 550                                     unsigned int base, unsigned int len,
 551                                     unsigned int shift)
 552{
 553        const struct kvec *tail = buf->tail;
 554        unsigned int to = base + shift;
 555        unsigned int pglen = 0;
 556        unsigned int talen = 0, tato = 0;
 557
 558        if (base >= buf->page_len)
 559                return;
 560        if (len > buf->page_len - base)
 561                len = buf->page_len - base;
 562        if (to >= buf->page_len) {
 563                tato = to - buf->page_len;
 564                if (tail->iov_len >= len + tato)
 565                        talen = len;
 566                else if (tail->iov_len > tato)
 567                        talen = tail->iov_len - tato;
 568        } else if (len + to >= buf->page_len) {
 569                pglen = buf->page_len - to;
 570                talen = len - pglen;
 571                if (talen > tail->iov_len)
 572                        talen = tail->iov_len;
 573        } else
 574                pglen = len;
 575
 576        _copy_from_pages(tail->iov_base + tato, buf->pages,
 577                         buf->page_base + base + pglen, talen);
 578        _shift_data_right_pages(buf->pages, buf->page_base + to,
 579                                buf->page_base + base, pglen);
 580}
 581
 582static void xdr_buf_head_copy_right(const struct xdr_buf *buf,
 583                                    unsigned int base, unsigned int len,
 584                                    unsigned int shift)
 585{
 586        const struct kvec *head = buf->head;
 587        const struct kvec *tail = buf->tail;
 588        unsigned int to = base + shift;
 589        unsigned int pglen = 0, pgto = 0;
 590        unsigned int talen = 0, tato = 0;
 591
 592        if (base >= head->iov_len)
 593                return;
 594        if (len > head->iov_len - base)
 595                len = head->iov_len - base;
 596        if (to >= buf->page_len + head->iov_len) {
 597                tato = to - buf->page_len - head->iov_len;
 598                talen = len;
 599        } else if (to >= head->iov_len) {
 600                pgto = to - head->iov_len;
 601                pglen = len;
 602                if (pgto + pglen > buf->page_len) {
 603                        talen = pgto + pglen - buf->page_len;
 604                        pglen -= talen;
 605                }
 606        } else {
 607                pglen = len - to;
 608                if (pglen > buf->page_len) {
 609                        talen = pglen - buf->page_len;
 610                        pglen = buf->page_len;
 611                }
 612        }
 613
 614        len -= talen;
 615        base += len;
 616        if (talen + tato > tail->iov_len)
 617                talen = tail->iov_len > tato ? tail->iov_len - tato : 0;
 618        memcpy(tail->iov_base + tato, head->iov_base + base, talen);
 619
 620        len -= pglen;
 621        base -= pglen;
 622        _copy_to_pages(buf->pages, buf->page_base + pgto, head->iov_base + base,
 623                       pglen);
 624
 625        base -= len;
 626        memmove(head->iov_base + to, head->iov_base + base, len);
 627}
 628
 629static void xdr_buf_tail_shift_right(const struct xdr_buf *buf,
 630                                     unsigned int base, unsigned int len,
 631                                     unsigned int shift)
 632{
 633        const struct kvec *tail = buf->tail;
 634
 635        if (base >= tail->iov_len || !shift || !len)
 636                return;
 637        xdr_buf_tail_copy_right(buf, base, len, shift);
 638}
 639
 640static void xdr_buf_pages_shift_right(const struct xdr_buf *buf,
 641                                      unsigned int base, unsigned int len,
 642                                      unsigned int shift)
 643{
 644        if (!shift || !len)
 645                return;
 646        if (base >= buf->page_len) {
 647                xdr_buf_tail_shift_right(buf, base - buf->page_len, len, shift);
 648                return;
 649        }
 650        if (base + len > buf->page_len)
 651                xdr_buf_tail_shift_right(buf, 0, base + len - buf->page_len,
 652                                         shift);
 653        xdr_buf_pages_copy_right(buf, base, len, shift);
 654}
 655
 656static void xdr_buf_head_shift_right(const struct xdr_buf *buf,
 657                                     unsigned int base, unsigned int len,
 658                                     unsigned int shift)
 659{
 660        const struct kvec *head = buf->head;
 661
 662        if (!shift)
 663                return;
 664        if (base >= head->iov_len) {
 665                xdr_buf_pages_shift_right(buf, head->iov_len - base, len,
 666                                          shift);
 667                return;
 668        }
 669        if (base + len > head->iov_len)
 670                xdr_buf_pages_shift_right(buf, 0, base + len - head->iov_len,
 671                                          shift);
 672        xdr_buf_head_copy_right(buf, base, len, shift);
 673}
 674
 675static void xdr_buf_tail_copy_left(const struct xdr_buf *buf, unsigned int base,
 676                                   unsigned int len, unsigned int shift)
 677{
 678        const struct kvec *tail = buf->tail;
 679
 680        if (base >= tail->iov_len)
 681                return;
 682        if (len > tail->iov_len - base)
 683                len = tail->iov_len - base;
 684        /* Shift data into head */
 685        if (shift > buf->page_len + base) {
 686                const struct kvec *head = buf->head;
 687                unsigned int hdto =
 688                        head->iov_len + buf->page_len + base - shift;
 689                unsigned int hdlen = len;
 690
 691                if (WARN_ONCE(shift > head->iov_len + buf->page_len + base,
 692                              "SUNRPC: Misaligned data.\n"))
 693                        return;
 694                if (hdto + hdlen > head->iov_len)
 695                        hdlen = head->iov_len - hdto;
 696                memcpy(head->iov_base + hdto, tail->iov_base + base, hdlen);
 697                base += hdlen;
 698                len -= hdlen;
 699                if (!len)
 700                        return;
 701        }
 702        /* Shift data into pages */
 703        if (shift > base) {
 704                unsigned int pgto = buf->page_len + base - shift;
 705                unsigned int pglen = len;
 706
 707                if (pgto + pglen > buf->page_len)
 708                        pglen = buf->page_len - pgto;
 709                _copy_to_pages(buf->pages, buf->page_base + pgto,
 710                               tail->iov_base + base, pglen);
 711                base += pglen;
 712                len -= pglen;
 713                if (!len)
 714                        return;
 715        }
 716        memmove(tail->iov_base + base - shift, tail->iov_base + base, len);
 717}
 718
 719static void xdr_buf_pages_copy_left(const struct xdr_buf *buf,
 720                                    unsigned int base, unsigned int len,
 721                                    unsigned int shift)
 722{
 723        unsigned int pgto;
 724
 725        if (base >= buf->page_len)
 726                return;
 727        if (len > buf->page_len - base)
 728                len = buf->page_len - base;
 729        /* Shift data into head */
 730        if (shift > base) {
 731                const struct kvec *head = buf->head;
 732                unsigned int hdto = head->iov_len + base - shift;
 733                unsigned int hdlen = len;
 734
 735                if (WARN_ONCE(shift > head->iov_len + base,
 736                              "SUNRPC: Misaligned data.\n"))
 737                        return;
 738                if (hdto + hdlen > head->iov_len)
 739                        hdlen = head->iov_len - hdto;
 740                _copy_from_pages(head->iov_base + hdto, buf->pages,
 741                                 buf->page_base + base, hdlen);
 742                base += hdlen;
 743                len -= hdlen;
 744                if (!len)
 745                        return;
 746        }
 747        pgto = base - shift;
 748        _shift_data_left_pages(buf->pages, buf->page_base + pgto,
 749                               buf->page_base + base, len);
 750}
 751
 752static void xdr_buf_tail_shift_left(const struct xdr_buf *buf,
 753                                    unsigned int base, unsigned int len,
 754                                    unsigned int shift)
 755{
 756        if (!shift || !len)
 757                return;
 758        xdr_buf_tail_copy_left(buf, base, len, shift);
 759}
 760
 761static void xdr_buf_pages_shift_left(const struct xdr_buf *buf,
 762                                     unsigned int base, unsigned int len,
 763                                     unsigned int shift)
 764{
 765        if (!shift || !len)
 766                return;
 767        if (base >= buf->page_len) {
 768                xdr_buf_tail_shift_left(buf, base - buf->page_len, len, shift);
 769                return;
 770        }
 771        xdr_buf_pages_copy_left(buf, base, len, shift);
 772        len += base;
 773        if (len <= buf->page_len)
 774                return;
 775        xdr_buf_tail_copy_left(buf, 0, len - buf->page_len, shift);
 776}
 777
 778/**
 779 * xdr_shrink_bufhead
 780 * @buf: xdr_buf
 781 * @len: new length of buf->head[0]
 782 *
 783 * Shrinks XDR buffer's header kvec buf->head[0], setting it to
 784 * 'len' bytes. The extra data is not lost, but is instead
 785 * moved into the inlined pages and/or the tail.
 786 */
 787static unsigned int xdr_shrink_bufhead(struct xdr_buf *buf, unsigned int len)
 788{
 789        struct kvec *head = buf->head;
 790        unsigned int shift, buflen = max(buf->len, len);
 791
 792        WARN_ON_ONCE(len > head->iov_len);
 793        if (head->iov_len > buflen) {
 794                buf->buflen -= head->iov_len - buflen;
 795                head->iov_len = buflen;
 796        }
 797        if (len >= head->iov_len)
 798                return 0;
 799        shift = head->iov_len - len;
 800        xdr_buf_try_expand(buf, shift);
 801        xdr_buf_head_shift_right(buf, len, buflen - len, shift);
 802        head->iov_len = len;
 803        buf->buflen -= shift;
 804        buf->len -= shift;
 805        return shift;
 806}
 807
 808/**
 809 * xdr_shrink_pagelen - shrinks buf->pages to @len bytes
 810 * @buf: xdr_buf
 811 * @len: new page buffer length
 812 *
 813 * The extra data is not lost, but is instead moved into buf->tail.
 814 * Returns the actual number of bytes moved.
 815 */
 816static unsigned int xdr_shrink_pagelen(struct xdr_buf *buf, unsigned int len)
 817{
 818        unsigned int shift, buflen = buf->len - buf->head->iov_len;
 819
 820        WARN_ON_ONCE(len > buf->page_len);
 821        if (buf->head->iov_len >= buf->len || len > buflen)
 822                buflen = len;
 823        if (buf->page_len > buflen) {
 824                buf->buflen -= buf->page_len - buflen;
 825                buf->page_len = buflen;
 826        }
 827        if (len >= buf->page_len)
 828                return 0;
 829        shift = buf->page_len - len;
 830        xdr_buf_try_expand(buf, shift);
 831        xdr_buf_pages_shift_right(buf, len, buflen - len, shift);
 832        buf->page_len = len;
 833        buf->len -= shift;
 834        buf->buflen -= shift;
 835        return shift;
 836}
 837
 838void
 839xdr_shift_buf(struct xdr_buf *buf, size_t len)
 840{
 841        xdr_shrink_bufhead(buf, buf->head->iov_len - len);
 842}
 843EXPORT_SYMBOL_GPL(xdr_shift_buf);
 844
 845/**
 846 * xdr_stream_pos - Return the current offset from the start of the xdr_stream
 847 * @xdr: pointer to struct xdr_stream
 848 */
 849unsigned int xdr_stream_pos(const struct xdr_stream *xdr)
 850{
 851        return (unsigned int)(XDR_QUADLEN(xdr->buf->len) - xdr->nwords) << 2;
 852}
 853EXPORT_SYMBOL_GPL(xdr_stream_pos);
 854
 855static void xdr_stream_set_pos(struct xdr_stream *xdr, unsigned int pos)
 856{
 857        unsigned int blen = xdr->buf->len;
 858
 859        xdr->nwords = blen > pos ? XDR_QUADLEN(blen) - XDR_QUADLEN(pos) : 0;
 860}
 861
 862static void xdr_stream_page_set_pos(struct xdr_stream *xdr, unsigned int pos)
 863{
 864        xdr_stream_set_pos(xdr, pos + xdr->buf->head[0].iov_len);
 865}
 866
 867/**
 868 * xdr_page_pos - Return the current offset from the start of the xdr pages
 869 * @xdr: pointer to struct xdr_stream
 870 */
 871unsigned int xdr_page_pos(const struct xdr_stream *xdr)
 872{
 873        unsigned int pos = xdr_stream_pos(xdr);
 874
 875        WARN_ON(pos < xdr->buf->head[0].iov_len);
 876        return pos - xdr->buf->head[0].iov_len;
 877}
 878EXPORT_SYMBOL_GPL(xdr_page_pos);
 879
 880/**
 881 * xdr_init_encode - Initialize a struct xdr_stream for sending data.
 882 * @xdr: pointer to xdr_stream struct
 883 * @buf: pointer to XDR buffer in which to encode data
 884 * @p: current pointer inside XDR buffer
 885 * @rqst: pointer to controlling rpc_rqst, for debugging
 886 *
 887 * Note: at the moment the RPC client only passes the length of our
 888 *       scratch buffer in the xdr_buf's header kvec. Previously this
 889 *       meant we needed to call xdr_adjust_iovec() after encoding the
 890 *       data. With the new scheme, the xdr_stream manages the details
 891 *       of the buffer length, and takes care of adjusting the kvec
 892 *       length for us.
 893 */
 894void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
 895                     struct rpc_rqst *rqst)
 896{
 897        struct kvec *iov = buf->head;
 898        int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
 899
 900        xdr_reset_scratch_buffer(xdr);
 901        BUG_ON(scratch_len < 0);
 902        xdr->buf = buf;
 903        xdr->iov = iov;
 904        xdr->p = (__be32 *)((char *)iov->iov_base + iov->iov_len);
 905        xdr->end = (__be32 *)((char *)iov->iov_base + scratch_len);
 906        BUG_ON(iov->iov_len > scratch_len);
 907
 908        if (p != xdr->p && p != NULL) {
 909                size_t len;
 910
 911                BUG_ON(p < xdr->p || p > xdr->end);
 912                len = (char *)p - (char *)xdr->p;
 913                xdr->p = p;
 914                buf->len += len;
 915                iov->iov_len += len;
 916        }
 917        xdr->rqst = rqst;
 918}
 919EXPORT_SYMBOL_GPL(xdr_init_encode);
 920
 921/**
 922 * xdr_commit_encode - Ensure all data is written to buffer
 923 * @xdr: pointer to xdr_stream
 924 *
 925 * We handle encoding across page boundaries by giving the caller a
 926 * temporary location to write to, then later copying the data into
 927 * place; xdr_commit_encode does that copying.
 928 *
 929 * Normally the caller doesn't need to call this directly, as the
 930 * following xdr_reserve_space will do it.  But an explicit call may be
 931 * required at the end of encoding, or any other time when the xdr_buf
 932 * data might be read.
 933 */
 934inline void xdr_commit_encode(struct xdr_stream *xdr)
 935{
 936        int shift = xdr->scratch.iov_len;
 937        void *page;
 938
 939        if (shift == 0)
 940                return;
 941        page = page_address(*xdr->page_ptr);
 942        memcpy(xdr->scratch.iov_base, page, shift);
 943        memmove(page, page + shift, (void *)xdr->p - page);
 944        xdr_reset_scratch_buffer(xdr);
 945}
 946EXPORT_SYMBOL_GPL(xdr_commit_encode);
 947
 948static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
 949                size_t nbytes)
 950{
 951        __be32 *p;
 952        int space_left;
 953        int frag1bytes, frag2bytes;
 954
 955        if (nbytes > PAGE_SIZE)
 956                goto out_overflow; /* Bigger buffers require special handling */
 957        if (xdr->buf->len + nbytes > xdr->buf->buflen)
 958                goto out_overflow; /* Sorry, we're totally out of space */
 959        frag1bytes = (xdr->end - xdr->p) << 2;
 960        frag2bytes = nbytes - frag1bytes;
 961        if (xdr->iov)
 962                xdr->iov->iov_len += frag1bytes;
 963        else
 964                xdr->buf->page_len += frag1bytes;
 965        xdr->page_ptr++;
 966        xdr->iov = NULL;
 967        /*
 968         * If the last encode didn't end exactly on a page boundary, the
 969         * next one will straddle boundaries.  Encode into the next
 970         * page, then copy it back later in xdr_commit_encode.  We use
 971         * the "scratch" iov to track any temporarily unused fragment of
 972         * space at the end of the previous buffer:
 973         */
 974        xdr_set_scratch_buffer(xdr, xdr->p, frag1bytes);
 975        p = page_address(*xdr->page_ptr);
 976        /*
 977         * Note this is where the next encode will start after we've
 978         * shifted this one back:
 979         */
 980        xdr->p = (void *)p + frag2bytes;
 981        space_left = xdr->buf->buflen - xdr->buf->len;
 982        xdr->end = (void *)p + min_t(int, space_left, PAGE_SIZE);
 983        xdr->buf->page_len += frag2bytes;
 984        xdr->buf->len += nbytes;
 985        return p;
 986out_overflow:
 987        trace_rpc_xdr_overflow(xdr, nbytes);
 988        return NULL;
 989}
 990
 991/**
 992 * xdr_reserve_space - Reserve buffer space for sending
 993 * @xdr: pointer to xdr_stream
 994 * @nbytes: number of bytes to reserve
 995 *
 996 * Checks that we have enough buffer space to encode 'nbytes' more
 997 * bytes of data. If so, update the total xdr_buf length, and
 998 * adjust the length of the current kvec.
 999 */
1000__be32 * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
1001{
1002        __be32 *p = xdr->p;
1003        __be32 *q;
1004
1005        xdr_commit_encode(xdr);
1006        /* align nbytes on the next 32-bit boundary */
1007        nbytes += 3;
1008        nbytes &= ~3;
1009        q = p + (nbytes >> 2);
1010        if (unlikely(q > xdr->end || q < p))
1011                return xdr_get_next_encode_buffer(xdr, nbytes);
1012        xdr->p = q;
1013        if (xdr->iov)
1014                xdr->iov->iov_len += nbytes;
1015        else
1016                xdr->buf->page_len += nbytes;
1017        xdr->buf->len += nbytes;
1018        return p;
1019}
1020EXPORT_SYMBOL_GPL(xdr_reserve_space);
1021
1022
1023/**
1024 * xdr_reserve_space_vec - Reserves a large amount of buffer space for sending
1025 * @xdr: pointer to xdr_stream
1026 * @vec: pointer to a kvec array
1027 * @nbytes: number of bytes to reserve
1028 *
1029 * Reserves enough buffer space to encode 'nbytes' of data and stores the
1030 * pointers in 'vec'. The size argument passed to xdr_reserve_space() is
1031 * determined based on the number of bytes remaining in the current page to
1032 * avoid invalidating iov_base pointers when xdr_commit_encode() is called.
1033 */
1034int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec, size_t nbytes)
1035{
1036        int thislen;
1037        int v = 0;
1038        __be32 *p;
1039
1040        /*
1041         * svcrdma requires every READ payload to start somewhere
1042         * in xdr->pages.
1043         */
1044        if (xdr->iov == xdr->buf->head) {
1045                xdr->iov = NULL;
1046                xdr->end = xdr->p;
1047        }
1048
1049        while (nbytes) {
1050                thislen = xdr->buf->page_len % PAGE_SIZE;
1051                thislen = min_t(size_t, nbytes, PAGE_SIZE - thislen);
1052
1053                p = xdr_reserve_space(xdr, thislen);
1054                if (!p)
1055                        return -EIO;
1056
1057                vec[v].iov_base = p;
1058                vec[v].iov_len = thislen;
1059                v++;
1060                nbytes -= thislen;
1061        }
1062
1063        return v;
1064}
1065EXPORT_SYMBOL_GPL(xdr_reserve_space_vec);
1066
1067/**
1068 * xdr_truncate_encode - truncate an encode buffer
1069 * @xdr: pointer to xdr_stream
1070 * @len: new length of buffer
1071 *
1072 * Truncates the xdr stream, so that xdr->buf->len == len,
1073 * and xdr->p points at offset len from the start of the buffer, and
1074 * head, tail, and page lengths are adjusted to correspond.
1075 *
1076 * If this means moving xdr->p to a different buffer, we assume that
1077 * the end pointer should be set to the end of the current page,
1078 * except in the case of the head buffer when we assume the head
1079 * buffer's current length represents the end of the available buffer.
1080 *
1081 * This is *not* safe to use on a buffer that already has inlined page
1082 * cache pages (as in a zero-copy server read reply), except for the
1083 * simple case of truncating from one position in the tail to another.
1084 *
1085 */
1086void xdr_truncate_encode(struct xdr_stream *xdr, size_t len)
1087{
1088        struct xdr_buf *buf = xdr->buf;
1089        struct kvec *head = buf->head;
1090        struct kvec *tail = buf->tail;
1091        int fraglen;
1092        int new;
1093
1094        if (len > buf->len) {
1095                WARN_ON_ONCE(1);
1096                return;
1097        }
1098        xdr_commit_encode(xdr);
1099
1100        fraglen = min_t(int, buf->len - len, tail->iov_len);
1101        tail->iov_len -= fraglen;
1102        buf->len -= fraglen;
1103        if (tail->iov_len) {
1104                xdr->p = tail->iov_base + tail->iov_len;
1105                WARN_ON_ONCE(!xdr->end);
1106                WARN_ON_ONCE(!xdr->iov);
1107                return;
1108        }
1109        WARN_ON_ONCE(fraglen);
1110        fraglen = min_t(int, buf->len - len, buf->page_len);
1111        buf->page_len -= fraglen;
1112        buf->len -= fraglen;
1113
1114        new = buf->page_base + buf->page_len;
1115
1116        xdr->page_ptr = buf->pages + (new >> PAGE_SHIFT);
1117
1118        if (buf->page_len) {
1119                xdr->p = page_address(*xdr->page_ptr);
1120                xdr->end = (void *)xdr->p + PAGE_SIZE;
1121                xdr->p = (void *)xdr->p + (new % PAGE_SIZE);
1122                WARN_ON_ONCE(xdr->iov);
1123                return;
1124        }
1125        if (fraglen)
1126                xdr->end = head->iov_base + head->iov_len;
1127        /* (otherwise assume xdr->end is already set) */
1128        xdr->page_ptr--;
1129        head->iov_len = len;
1130        buf->len = len;
1131        xdr->p = head->iov_base + head->iov_len;
1132        xdr->iov = buf->head;
1133}
1134EXPORT_SYMBOL(xdr_truncate_encode);
1135
1136/**
1137 * xdr_restrict_buflen - decrease available buffer space
1138 * @xdr: pointer to xdr_stream
1139 * @newbuflen: new maximum number of bytes available
1140 *
1141 * Adjust our idea of how much space is available in the buffer.
1142 * If we've already used too much space in the buffer, returns -1.
1143 * If the available space is already smaller than newbuflen, returns 0
1144 * and does nothing.  Otherwise, adjusts xdr->buf->buflen to newbuflen
1145 * and ensures xdr->end is set at most offset newbuflen from the start
1146 * of the buffer.
1147 */
1148int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen)
1149{
1150        struct xdr_buf *buf = xdr->buf;
1151        int left_in_this_buf = (void *)xdr->end - (void *)xdr->p;
1152        int end_offset = buf->len + left_in_this_buf;
1153
1154        if (newbuflen < 0 || newbuflen < buf->len)
1155                return -1;
1156        if (newbuflen > buf->buflen)
1157                return 0;
1158        if (newbuflen < end_offset)
1159                xdr->end = (void *)xdr->end + newbuflen - end_offset;
1160        buf->buflen = newbuflen;
1161        return 0;
1162}
1163EXPORT_SYMBOL(xdr_restrict_buflen);
1164
1165/**
1166 * xdr_write_pages - Insert a list of pages into an XDR buffer for sending
1167 * @xdr: pointer to xdr_stream
1168 * @pages: list of pages
1169 * @base: offset of first byte
1170 * @len: length of data in bytes
1171 *
1172 */
1173void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int base,
1174                 unsigned int len)
1175{
1176        struct xdr_buf *buf = xdr->buf;
1177        struct kvec *iov = buf->tail;
1178        buf->pages = pages;
1179        buf->page_base = base;
1180        buf->page_len = len;
1181
1182        iov->iov_base = (char *)xdr->p;
1183        iov->iov_len  = 0;
1184        xdr->iov = iov;
1185
1186        if (len & 3) {
1187                unsigned int pad = 4 - (len & 3);
1188
1189                BUG_ON(xdr->p >= xdr->end);
1190                iov->iov_base = (char *)xdr->p + (len & 3);
1191                iov->iov_len  += pad;
1192                len += pad;
1193                *xdr->p++ = 0;
1194        }
1195        buf->buflen += len;
1196        buf->len += len;
1197}
1198EXPORT_SYMBOL_GPL(xdr_write_pages);
1199
1200static unsigned int xdr_set_iov(struct xdr_stream *xdr, struct kvec *iov,
1201                                unsigned int base, unsigned int len)
1202{
1203        if (len > iov->iov_len)
1204                len = iov->iov_len;
1205        if (unlikely(base > len))
1206                base = len;
1207        xdr->p = (__be32*)(iov->iov_base + base);
1208        xdr->end = (__be32*)(iov->iov_base + len);
1209        xdr->iov = iov;
1210        xdr->page_ptr = NULL;
1211        return len - base;
1212}
1213
1214static unsigned int xdr_set_tail_base(struct xdr_stream *xdr,
1215                                      unsigned int base, unsigned int len)
1216{
1217        struct xdr_buf *buf = xdr->buf;
1218
1219        xdr_stream_set_pos(xdr, base + buf->page_len + buf->head->iov_len);
1220        return xdr_set_iov(xdr, buf->tail, base, len);
1221}
1222
1223static unsigned int xdr_set_page_base(struct xdr_stream *xdr,
1224                                      unsigned int base, unsigned int len)
1225{
1226        unsigned int pgnr;
1227        unsigned int maxlen;
1228        unsigned int pgoff;
1229        unsigned int pgend;
1230        void *kaddr;
1231
1232        maxlen = xdr->buf->page_len;
1233        if (base >= maxlen)
1234                return 0;
1235        else
1236                maxlen -= base;
1237        if (len > maxlen)
1238                len = maxlen;
1239
1240        xdr_stream_page_set_pos(xdr, base);
1241        base += xdr->buf->page_base;
1242
1243        pgnr = base >> PAGE_SHIFT;
1244        xdr->page_ptr = &xdr->buf->pages[pgnr];
1245        kaddr = page_address(*xdr->page_ptr);
1246
1247        pgoff = base & ~PAGE_MASK;
1248        xdr->p = (__be32*)(kaddr + pgoff);
1249
1250        pgend = pgoff + len;
1251        if (pgend > PAGE_SIZE)
1252                pgend = PAGE_SIZE;
1253        xdr->end = (__be32*)(kaddr + pgend);
1254        xdr->iov = NULL;
1255        return len;
1256}
1257
1258static void xdr_set_page(struct xdr_stream *xdr, unsigned int base,
1259                         unsigned int len)
1260{
1261        if (xdr_set_page_base(xdr, base, len) == 0) {
1262                base -= xdr->buf->page_len;
1263                xdr_set_tail_base(xdr, base, len);
1264        }
1265}
1266
1267static void xdr_set_next_page(struct xdr_stream *xdr)
1268{
1269        unsigned int newbase;
1270
1271        newbase = (1 + xdr->page_ptr - xdr->buf->pages) << PAGE_SHIFT;
1272        newbase -= xdr->buf->page_base;
1273        if (newbase < xdr->buf->page_len)
1274                xdr_set_page_base(xdr, newbase, xdr_stream_remaining(xdr));
1275        else
1276                xdr_set_tail_base(xdr, 0, xdr_stream_remaining(xdr));
1277}
1278
1279static bool xdr_set_next_buffer(struct xdr_stream *xdr)
1280{
1281        if (xdr->page_ptr != NULL)
1282                xdr_set_next_page(xdr);
1283        else if (xdr->iov == xdr->buf->head)
1284                xdr_set_page(xdr, 0, xdr_stream_remaining(xdr));
1285        return xdr->p != xdr->end;
1286}
1287
1288/**
1289 * xdr_init_decode - Initialize an xdr_stream for decoding data.
1290 * @xdr: pointer to xdr_stream struct
1291 * @buf: pointer to XDR buffer from which to decode data
1292 * @p: current pointer inside XDR buffer
1293 * @rqst: pointer to controlling rpc_rqst, for debugging
1294 */
1295void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
1296                     struct rpc_rqst *rqst)
1297{
1298        xdr->buf = buf;
1299        xdr_reset_scratch_buffer(xdr);
1300        xdr->nwords = XDR_QUADLEN(buf->len);
1301        if (xdr_set_iov(xdr, buf->head, 0, buf->len) == 0 &&
1302            xdr_set_page_base(xdr, 0, buf->len) == 0)
1303                xdr_set_iov(xdr, buf->tail, 0, buf->len);
1304        if (p != NULL && p > xdr->p && xdr->end >= p) {
1305                xdr->nwords -= p - xdr->p;
1306                xdr->p = p;
1307        }
1308        xdr->rqst = rqst;
1309}
1310EXPORT_SYMBOL_GPL(xdr_init_decode);
1311
1312/**
1313 * xdr_init_decode_pages - Initialize an xdr_stream for decoding into pages
1314 * @xdr: pointer to xdr_stream struct
1315 * @buf: pointer to XDR buffer from which to decode data
1316 * @pages: list of pages to decode into
1317 * @len: length in bytes of buffer in pages
1318 */
1319void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf,
1320                           struct page **pages, unsigned int len)
1321{
1322        memset(buf, 0, sizeof(*buf));
1323        buf->pages =  pages;
1324        buf->page_len =  len;
1325        buf->buflen =  len;
1326        buf->len = len;
1327        xdr_init_decode(xdr, buf, NULL, NULL);
1328}
1329EXPORT_SYMBOL_GPL(xdr_init_decode_pages);
1330
1331static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
1332{
1333        unsigned int nwords = XDR_QUADLEN(nbytes);
1334        __be32 *p = xdr->p;
1335        __be32 *q = p + nwords;
1336
1337        if (unlikely(nwords > xdr->nwords || q > xdr->end || q < p))
1338                return NULL;
1339        xdr->p = q;
1340        xdr->nwords -= nwords;
1341        return p;
1342}
1343
1344static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes)
1345{
1346        __be32 *p;
1347        char *cpdest = xdr->scratch.iov_base;
1348        size_t cplen = (char *)xdr->end - (char *)xdr->p;
1349
1350        if (nbytes > xdr->scratch.iov_len)
1351                goto out_overflow;
1352        p = __xdr_inline_decode(xdr, cplen);
1353        if (p == NULL)
1354                return NULL;
1355        memcpy(cpdest, p, cplen);
1356        if (!xdr_set_next_buffer(xdr))
1357                goto out_overflow;
1358        cpdest += cplen;
1359        nbytes -= cplen;
1360        p = __xdr_inline_decode(xdr, nbytes);
1361        if (p == NULL)
1362                return NULL;
1363        memcpy(cpdest, p, nbytes);
1364        return xdr->scratch.iov_base;
1365out_overflow:
1366        trace_rpc_xdr_overflow(xdr, nbytes);
1367        return NULL;
1368}
1369
1370/**
1371 * xdr_inline_decode - Retrieve XDR data to decode
1372 * @xdr: pointer to xdr_stream struct
1373 * @nbytes: number of bytes of data to decode
1374 *
1375 * Check if the input buffer is long enough to enable us to decode
1376 * 'nbytes' more bytes of data starting at the current position.
1377 * If so return the current pointer, then update the current
1378 * pointer position.
1379 */
1380__be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
1381{
1382        __be32 *p;
1383
1384        if (unlikely(nbytes == 0))
1385                return xdr->p;
1386        if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr))
1387                goto out_overflow;
1388        p = __xdr_inline_decode(xdr, nbytes);
1389        if (p != NULL)
1390                return p;
1391        return xdr_copy_to_scratch(xdr, nbytes);
1392out_overflow:
1393        trace_rpc_xdr_overflow(xdr, nbytes);
1394        return NULL;
1395}
1396EXPORT_SYMBOL_GPL(xdr_inline_decode);
1397
1398static void xdr_realign_pages(struct xdr_stream *xdr)
1399{
1400        struct xdr_buf *buf = xdr->buf;
1401        struct kvec *iov = buf->head;
1402        unsigned int cur = xdr_stream_pos(xdr);
1403        unsigned int copied;
1404
1405        /* Realign pages to current pointer position */
1406        if (iov->iov_len > cur) {
1407                copied = xdr_shrink_bufhead(buf, cur);
1408                trace_rpc_xdr_alignment(xdr, cur, copied);
1409                xdr_set_page(xdr, 0, buf->page_len);
1410        }
1411}
1412
1413static unsigned int xdr_align_pages(struct xdr_stream *xdr, unsigned int len)
1414{
1415        struct xdr_buf *buf = xdr->buf;
1416        unsigned int nwords = XDR_QUADLEN(len);
1417        unsigned int copied;
1418
1419        if (xdr->nwords == 0)
1420                return 0;
1421
1422        xdr_realign_pages(xdr);
1423        if (nwords > xdr->nwords) {
1424                nwords = xdr->nwords;
1425                len = nwords << 2;
1426        }
1427        if (buf->page_len <= len)
1428                len = buf->page_len;
1429        else if (nwords < xdr->nwords) {
1430                /* Truncate page data and move it into the tail */
1431                copied = xdr_shrink_pagelen(buf, len);
1432                trace_rpc_xdr_alignment(xdr, len, copied);
1433        }
1434        return len;
1435}
1436
1437/**
1438 * xdr_read_pages - align page-based XDR data to current pointer position
1439 * @xdr: pointer to xdr_stream struct
1440 * @len: number of bytes of page data
1441 *
1442 * Moves data beyond the current pointer position from the XDR head[] buffer
1443 * into the page list. Any data that lies beyond current position + @len
1444 * bytes is moved into the XDR tail[]. The xdr_stream current position is
1445 * then advanced past that data to align to the next XDR object in the tail.
1446 *
1447 * Returns the number of XDR encoded bytes now contained in the pages
1448 */
1449unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
1450{
1451        unsigned int nwords = XDR_QUADLEN(len);
1452        unsigned int base, end, pglen;
1453
1454        pglen = xdr_align_pages(xdr, nwords << 2);
1455        if (pglen == 0)
1456                return 0;
1457
1458        base = (nwords << 2) - pglen;
1459        end = xdr_stream_remaining(xdr) - pglen;
1460
1461        xdr_set_tail_base(xdr, base, end);
1462        return len <= pglen ? len : pglen;
1463}
1464EXPORT_SYMBOL_GPL(xdr_read_pages);
1465
1466unsigned int xdr_align_data(struct xdr_stream *xdr, unsigned int offset,
1467                            unsigned int length)
1468{
1469        struct xdr_buf *buf = xdr->buf;
1470        unsigned int from, bytes, len;
1471        unsigned int shift;
1472
1473        xdr_realign_pages(xdr);
1474        from = xdr_page_pos(xdr);
1475
1476        if (from >= buf->page_len + buf->tail->iov_len)
1477                return 0;
1478        if (from + buf->head->iov_len >= buf->len)
1479                return 0;
1480
1481        len = buf->len - buf->head->iov_len;
1482
1483        /* We only shift data left! */
1484        if (WARN_ONCE(from < offset, "SUNRPC: misaligned data src=%u dst=%u\n",
1485                      from, offset))
1486                return 0;
1487        if (WARN_ONCE(offset > buf->page_len,
1488                      "SUNRPC: buffer overflow. offset=%u, page_len=%u\n",
1489                      offset, buf->page_len))
1490                return 0;
1491
1492        /* Move page data to the left */
1493        shift = from - offset;
1494        xdr_buf_pages_shift_left(buf, from, len, shift);
1495
1496        bytes = xdr_stream_remaining(xdr);
1497        if (length > bytes)
1498                length = bytes;
1499        bytes -= length;
1500
1501        xdr->buf->len -= shift;
1502        xdr_set_page(xdr, offset + length, bytes);
1503        return length;
1504}
1505EXPORT_SYMBOL_GPL(xdr_align_data);
1506
1507unsigned int xdr_expand_hole(struct xdr_stream *xdr, unsigned int offset,
1508                             unsigned int length)
1509{
1510        struct xdr_buf *buf = xdr->buf;
1511        unsigned int from, to, shift;
1512
1513        xdr_realign_pages(xdr);
1514        from = xdr_page_pos(xdr);
1515        to = xdr_align_size(offset + length);
1516
1517        /* Could the hole be behind us? */
1518        if (to > from) {
1519                unsigned int buflen = buf->len - buf->head->iov_len;
1520                shift = to - from;
1521                xdr_buf_try_expand(buf, shift);
1522                xdr_buf_pages_shift_right(buf, from, buflen, shift);
1523                xdr_set_page(xdr, to, xdr_stream_remaining(xdr));
1524        } else if (to != from)
1525                xdr_align_data(xdr, to, 0);
1526        xdr_buf_pages_zero(buf, offset, length);
1527
1528        return length;
1529}
1530EXPORT_SYMBOL_GPL(xdr_expand_hole);
1531
1532/**
1533 * xdr_enter_page - decode data from the XDR page
1534 * @xdr: pointer to xdr_stream struct
1535 * @len: number of bytes of page data
1536 *
1537 * Moves data beyond the current pointer position from the XDR head[] buffer
1538 * into the page list. Any data that lies beyond current position + "len"
1539 * bytes is moved into the XDR tail[]. The current pointer is then
1540 * repositioned at the beginning of the first XDR page.
1541 */
1542void xdr_enter_page(struct xdr_stream *xdr, unsigned int len)
1543{
1544        len = xdr_align_pages(xdr, len);
1545        /*
1546         * Position current pointer at beginning of tail, and
1547         * set remaining message length.
1548         */
1549        if (len != 0)
1550                xdr_set_page_base(xdr, 0, len);
1551}
1552EXPORT_SYMBOL_GPL(xdr_enter_page);
1553
1554static const struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0};
1555
1556void xdr_buf_from_iov(const struct kvec *iov, struct xdr_buf *buf)
1557{
1558        buf->head[0] = *iov;
1559        buf->tail[0] = empty_iov;
1560        buf->page_len = 0;
1561        buf->buflen = buf->len = iov->iov_len;
1562}
1563EXPORT_SYMBOL_GPL(xdr_buf_from_iov);
1564
1565/**
1566 * xdr_buf_subsegment - set subbuf to a portion of buf
1567 * @buf: an xdr buffer
1568 * @subbuf: the result buffer
1569 * @base: beginning of range in bytes
1570 * @len: length of range in bytes
1571 *
1572 * sets @subbuf to an xdr buffer representing the portion of @buf of
1573 * length @len starting at offset @base.
1574 *
1575 * @buf and @subbuf may be pointers to the same struct xdr_buf.
1576 *
1577 * Returns -1 if base of length are out of bounds.
1578 */
1579int xdr_buf_subsegment(const struct xdr_buf *buf, struct xdr_buf *subbuf,
1580                       unsigned int base, unsigned int len)
1581{
1582        subbuf->buflen = subbuf->len = len;
1583        if (base < buf->head[0].iov_len) {
1584                subbuf->head[0].iov_base = buf->head[0].iov_base + base;
1585                subbuf->head[0].iov_len = min_t(unsigned int, len,
1586                                                buf->head[0].iov_len - base);
1587                len -= subbuf->head[0].iov_len;
1588                base = 0;
1589        } else {
1590                base -= buf->head[0].iov_len;
1591                subbuf->head[0].iov_base = buf->head[0].iov_base;
1592                subbuf->head[0].iov_len = 0;
1593        }
1594
1595        if (base < buf->page_len) {
1596                subbuf->page_len = min(buf->page_len - base, len);
1597                base += buf->page_base;
1598                subbuf->page_base = base & ~PAGE_MASK;
1599                subbuf->pages = &buf->pages[base >> PAGE_SHIFT];
1600                len -= subbuf->page_len;
1601                base = 0;
1602        } else {
1603                base -= buf->page_len;
1604                subbuf->pages = buf->pages;
1605                subbuf->page_base = 0;
1606                subbuf->page_len = 0;
1607        }
1608
1609        if (base < buf->tail[0].iov_len) {
1610                subbuf->tail[0].iov_base = buf->tail[0].iov_base + base;
1611                subbuf->tail[0].iov_len = min_t(unsigned int, len,
1612                                                buf->tail[0].iov_len - base);
1613                len -= subbuf->tail[0].iov_len;
1614                base = 0;
1615        } else {
1616                base -= buf->tail[0].iov_len;
1617                subbuf->tail[0].iov_base = buf->tail[0].iov_base;
1618                subbuf->tail[0].iov_len = 0;
1619        }
1620
1621        if (base || len)
1622                return -1;
1623        return 0;
1624}
1625EXPORT_SYMBOL_GPL(xdr_buf_subsegment);
1626
1627/**
1628 * xdr_stream_subsegment - set @subbuf to a portion of @xdr
1629 * @xdr: an xdr_stream set up for decoding
1630 * @subbuf: the result buffer
1631 * @nbytes: length of @xdr to extract, in bytes
1632 *
1633 * Sets up @subbuf to represent a portion of @xdr. The portion
1634 * starts at the current offset in @xdr, and extends for a length
1635 * of @nbytes. If this is successful, @xdr is advanced to the next
1636 * position following that portion.
1637 *
1638 * Return values:
1639 *   %true: @subbuf has been initialized, and @xdr has been advanced.
1640 *   %false: a bounds error has occurred
1641 */
1642bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf,
1643                           unsigned int nbytes)
1644{
1645        unsigned int remaining, offset, len;
1646
1647        if (xdr_buf_subsegment(xdr->buf, subbuf, xdr_stream_pos(xdr), nbytes))
1648                return false;
1649
1650        if (subbuf->head[0].iov_len)
1651                if (!__xdr_inline_decode(xdr, subbuf->head[0].iov_len))
1652                        return false;
1653
1654        remaining = subbuf->page_len;
1655        offset = subbuf->page_base;
1656        while (remaining) {
1657                len = min_t(unsigned int, remaining, PAGE_SIZE) - offset;
1658
1659                if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr))
1660                        return false;
1661                if (!__xdr_inline_decode(xdr, len))
1662                        return false;
1663
1664                remaining -= len;
1665                offset = 0;
1666        }
1667
1668        return true;
1669}
1670EXPORT_SYMBOL_GPL(xdr_stream_subsegment);
1671
1672/**
1673 * xdr_buf_trim - lop at most "len" bytes off the end of "buf"
1674 * @buf: buf to be trimmed
1675 * @len: number of bytes to reduce "buf" by
1676 *
1677 * Trim an xdr_buf by the given number of bytes by fixing up the lengths. Note
1678 * that it's possible that we'll trim less than that amount if the xdr_buf is
1679 * too small, or if (for instance) it's all in the head and the parser has
1680 * already read too far into it.
1681 */
1682void xdr_buf_trim(struct xdr_buf *buf, unsigned int len)
1683{
1684        size_t cur;
1685        unsigned int trim = len;
1686
1687        if (buf->tail[0].iov_len) {
1688                cur = min_t(size_t, buf->tail[0].iov_len, trim);
1689                buf->tail[0].iov_len -= cur;
1690                trim -= cur;
1691                if (!trim)
1692                        goto fix_len;
1693        }
1694
1695        if (buf->page_len) {
1696                cur = min_t(unsigned int, buf->page_len, trim);
1697                buf->page_len -= cur;
1698                trim -= cur;
1699                if (!trim)
1700                        goto fix_len;
1701        }
1702
1703        if (buf->head[0].iov_len) {
1704                cur = min_t(size_t, buf->head[0].iov_len, trim);
1705                buf->head[0].iov_len -= cur;
1706                trim -= cur;
1707        }
1708fix_len:
1709        buf->len -= (len - trim);
1710}
1711EXPORT_SYMBOL_GPL(xdr_buf_trim);
1712
1713static void __read_bytes_from_xdr_buf(const struct xdr_buf *subbuf,
1714                                      void *obj, unsigned int len)
1715{
1716        unsigned int this_len;
1717
1718        this_len = min_t(unsigned int, len, subbuf->head[0].iov_len);
1719        memcpy(obj, subbuf->head[0].iov_base, this_len);
1720        len -= this_len;
1721        obj += this_len;
1722        this_len = min_t(unsigned int, len, subbuf->page_len);
1723        _copy_from_pages(obj, subbuf->pages, subbuf->page_base, this_len);
1724        len -= this_len;
1725        obj += this_len;
1726        this_len = min_t(unsigned int, len, subbuf->tail[0].iov_len);
1727        memcpy(obj, subbuf->tail[0].iov_base, this_len);
1728}
1729
1730/* obj is assumed to point to allocated memory of size at least len: */
1731int read_bytes_from_xdr_buf(const struct xdr_buf *buf, unsigned int base,
1732                            void *obj, unsigned int len)
1733{
1734        struct xdr_buf subbuf;
1735        int status;
1736
1737        status = xdr_buf_subsegment(buf, &subbuf, base, len);
1738        if (status != 0)
1739                return status;
1740        __read_bytes_from_xdr_buf(&subbuf, obj, len);
1741        return 0;
1742}
1743EXPORT_SYMBOL_GPL(read_bytes_from_xdr_buf);
1744
1745static void __write_bytes_to_xdr_buf(const struct xdr_buf *subbuf,
1746                                     void *obj, unsigned int len)
1747{
1748        unsigned int this_len;
1749
1750        this_len = min_t(unsigned int, len, subbuf->head[0].iov_len);
1751        memcpy(subbuf->head[0].iov_base, obj, this_len);
1752        len -= this_len;
1753        obj += this_len;
1754        this_len = min_t(unsigned int, len, subbuf->page_len);
1755        _copy_to_pages(subbuf->pages, subbuf->page_base, obj, this_len);
1756        len -= this_len;
1757        obj += this_len;
1758        this_len = min_t(unsigned int, len, subbuf->tail[0].iov_len);
1759        memcpy(subbuf->tail[0].iov_base, obj, this_len);
1760}
1761
1762/* obj is assumed to point to allocated memory of size at least len: */
1763int write_bytes_to_xdr_buf(const struct xdr_buf *buf, unsigned int base,
1764                           void *obj, unsigned int len)
1765{
1766        struct xdr_buf subbuf;
1767        int status;
1768
1769        status = xdr_buf_subsegment(buf, &subbuf, base, len);
1770        if (status != 0)
1771                return status;
1772        __write_bytes_to_xdr_buf(&subbuf, obj, len);
1773        return 0;
1774}
1775EXPORT_SYMBOL_GPL(write_bytes_to_xdr_buf);
1776
1777int xdr_decode_word(const struct xdr_buf *buf, unsigned int base, u32 *obj)
1778{
1779        __be32  raw;
1780        int     status;
1781
1782        status = read_bytes_from_xdr_buf(buf, base, &raw, sizeof(*obj));
1783        if (status)
1784                return status;
1785        *obj = be32_to_cpu(raw);
1786        return 0;
1787}
1788EXPORT_SYMBOL_GPL(xdr_decode_word);
1789
1790int xdr_encode_word(const struct xdr_buf *buf, unsigned int base, u32 obj)
1791{
1792        __be32  raw = cpu_to_be32(obj);
1793
1794        return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj));
1795}
1796EXPORT_SYMBOL_GPL(xdr_encode_word);
1797
1798/* Returns 0 on success, or else a negative error code. */
1799static int xdr_xcode_array2(const struct xdr_buf *buf, unsigned int base,
1800                            struct xdr_array2_desc *desc, int encode)
1801{
1802        char *elem = NULL, *c;
1803        unsigned int copied = 0, todo, avail_here;
1804        struct page **ppages = NULL;
1805        int err;
1806
1807        if (encode) {
1808                if (xdr_encode_word(buf, base, desc->array_len) != 0)
1809                        return -EINVAL;
1810        } else {
1811                if (xdr_decode_word(buf, base, &desc->array_len) != 0 ||
1812                    desc->array_len > desc->array_maxlen ||
1813                    (unsigned long) base + 4 + desc->array_len *
1814                                    desc->elem_size > buf->len)
1815                        return -EINVAL;
1816        }
1817        base += 4;
1818
1819        if (!desc->xcode)
1820                return 0;
1821
1822        todo = desc->array_len * desc->elem_size;
1823
1824        /* process head */
1825        if (todo && base < buf->head->iov_len) {
1826                c = buf->head->iov_base + base;
1827                avail_here = min_t(unsigned int, todo,
1828                                   buf->head->iov_len - base);
1829                todo -= avail_here;
1830
1831                while (avail_here >= desc->elem_size) {
1832                        err = desc->xcode(desc, c);
1833                        if (err)
1834                                goto out;
1835                        c += desc->elem_size;
1836                        avail_here -= desc->elem_size;
1837                }
1838                if (avail_here) {
1839                        if (!elem) {
1840                                elem = kmalloc(desc->elem_size, GFP_KERNEL);
1841                                err = -ENOMEM;
1842                                if (!elem)
1843                                        goto out;
1844                        }
1845                        if (encode) {
1846                                err = desc->xcode(desc, elem);
1847                                if (err)
1848                                        goto out;
1849                                memcpy(c, elem, avail_here);
1850                        } else
1851                                memcpy(elem, c, avail_here);
1852                        copied = avail_here;
1853                }
1854                base = buf->head->iov_len;  /* align to start of pages */
1855        }
1856
1857        /* process pages array */
1858        base -= buf->head->iov_len;
1859        if (todo && base < buf->page_len) {
1860                unsigned int avail_page;
1861
1862                avail_here = min(todo, buf->page_len - base);
1863                todo -= avail_here;
1864
1865                base += buf->page_base;
1866                ppages = buf->pages + (base >> PAGE_SHIFT);
1867                base &= ~PAGE_MASK;
1868                avail_page = min_t(unsigned int, PAGE_SIZE - base,
1869                                        avail_here);
1870                c = kmap(*ppages) + base;
1871
1872                while (avail_here) {
1873                        avail_here -= avail_page;
1874                        if (copied || avail_page < desc->elem_size) {
1875                                unsigned int l = min(avail_page,
1876                                        desc->elem_size - copied);
1877                                if (!elem) {
1878                                        elem = kmalloc(desc->elem_size,
1879                                                       GFP_KERNEL);
1880                                        err = -ENOMEM;
1881                                        if (!elem)
1882                                                goto out;
1883                                }
1884                                if (encode) {
1885                                        if (!copied) {
1886                                                err = desc->xcode(desc, elem);
1887                                                if (err)
1888                                                        goto out;
1889                                        }
1890                                        memcpy(c, elem + copied, l);
1891                                        copied += l;
1892                                        if (copied == desc->elem_size)
1893                                                copied = 0;
1894                                } else {
1895                                        memcpy(elem + copied, c, l);
1896                                        copied += l;
1897                                        if (copied == desc->elem_size) {
1898                                                err = desc->xcode(desc, elem);
1899                                                if (err)
1900                                                        goto out;
1901                                                copied = 0;
1902                                        }
1903                                }
1904                                avail_page -= l;
1905                                c += l;
1906                        }
1907                        while (avail_page >= desc->elem_size) {
1908                                err = desc->xcode(desc, c);
1909                                if (err)
1910                                        goto out;
1911                                c += desc->elem_size;
1912                                avail_page -= desc->elem_size;
1913                        }
1914                        if (avail_page) {
1915                                unsigned int l = min(avail_page,
1916                                            desc->elem_size - copied);
1917                                if (!elem) {
1918                                        elem = kmalloc(desc->elem_size,
1919                                                       GFP_KERNEL);
1920                                        err = -ENOMEM;
1921                                        if (!elem)
1922                                                goto out;
1923                                }
1924                                if (encode) {
1925                                        if (!copied) {
1926                                                err = desc->xcode(desc, elem);
1927                                                if (err)
1928                                                        goto out;
1929                                        }
1930                                        memcpy(c, elem + copied, l);
1931                                        copied += l;
1932                                        if (copied == desc->elem_size)
1933                                                copied = 0;
1934                                } else {
1935                                        memcpy(elem + copied, c, l);
1936                                        copied += l;
1937                                        if (copied == desc->elem_size) {
1938                                                err = desc->xcode(desc, elem);
1939                                                if (err)
1940                                                        goto out;
1941                                                copied = 0;
1942                                        }
1943                                }
1944                        }
1945                        if (avail_here) {
1946                                kunmap(*ppages);
1947                                ppages++;
1948                                c = kmap(*ppages);
1949                        }
1950
1951                        avail_page = min(avail_here,
1952                                 (unsigned int) PAGE_SIZE);
1953                }
1954                base = buf->page_len;  /* align to start of tail */
1955        }
1956
1957        /* process tail */
1958        base -= buf->page_len;
1959        if (todo) {
1960                c = buf->tail->iov_base + base;
1961                if (copied) {
1962                        unsigned int l = desc->elem_size - copied;
1963
1964                        if (encode)
1965                                memcpy(c, elem + copied, l);
1966                        else {
1967                                memcpy(elem + copied, c, l);
1968                                err = desc->xcode(desc, elem);
1969                                if (err)
1970                                        goto out;
1971                        }
1972                        todo -= l;
1973                        c += l;
1974                }
1975                while (todo) {
1976                        err = desc->xcode(desc, c);
1977                        if (err)
1978                                goto out;
1979                        c += desc->elem_size;
1980                        todo -= desc->elem_size;
1981                }
1982        }
1983        err = 0;
1984
1985out:
1986        kfree(elem);
1987        if (ppages)
1988                kunmap(*ppages);
1989        return err;
1990}
1991
1992int xdr_decode_array2(const struct xdr_buf *buf, unsigned int base,
1993                      struct xdr_array2_desc *desc)
1994{
1995        if (base >= buf->len)
1996                return -EINVAL;
1997
1998        return xdr_xcode_array2(buf, base, desc, 0);
1999}
2000EXPORT_SYMBOL_GPL(xdr_decode_array2);
2001
2002int xdr_encode_array2(const struct xdr_buf *buf, unsigned int base,
2003                      struct xdr_array2_desc *desc)
2004{
2005        if ((unsigned long) base + 4 + desc->array_len * desc->elem_size >
2006            buf->head->iov_len + buf->page_len + buf->tail->iov_len)
2007                return -EINVAL;
2008
2009        return xdr_xcode_array2(buf, base, desc, 1);
2010}
2011EXPORT_SYMBOL_GPL(xdr_encode_array2);
2012
2013int xdr_process_buf(const struct xdr_buf *buf, unsigned int offset,
2014                    unsigned int len,
2015                    int (*actor)(struct scatterlist *, void *), void *data)
2016{
2017        int i, ret = 0;
2018        unsigned int page_len, thislen, page_offset;
2019        struct scatterlist      sg[1];
2020
2021        sg_init_table(sg, 1);
2022
2023        if (offset >= buf->head[0].iov_len) {
2024                offset -= buf->head[0].iov_len;
2025        } else {
2026                thislen = buf->head[0].iov_len - offset;
2027                if (thislen > len)
2028                        thislen = len;
2029                sg_set_buf(sg, buf->head[0].iov_base + offset, thislen);
2030                ret = actor(sg, data);
2031                if (ret)
2032                        goto out;
2033                offset = 0;
2034                len -= thislen;
2035        }
2036        if (len == 0)
2037                goto out;
2038
2039        if (offset >= buf->page_len) {
2040                offset -= buf->page_len;
2041        } else {
2042                page_len = buf->page_len - offset;
2043                if (page_len > len)
2044                        page_len = len;
2045                len -= page_len;
2046                page_offset = (offset + buf->page_base) & (PAGE_SIZE - 1);
2047                i = (offset + buf->page_base) >> PAGE_SHIFT;
2048                thislen = PAGE_SIZE - page_offset;
2049                do {
2050                        if (thislen > page_len)
2051                                thislen = page_len;
2052                        sg_set_page(sg, buf->pages[i], thislen, page_offset);
2053                        ret = actor(sg, data);
2054                        if (ret)
2055                                goto out;
2056                        page_len -= thislen;
2057                        i++;
2058                        page_offset = 0;
2059                        thislen = PAGE_SIZE;
2060                } while (page_len != 0);
2061                offset = 0;
2062        }
2063        if (len == 0)
2064                goto out;
2065        if (offset < buf->tail[0].iov_len) {
2066                thislen = buf->tail[0].iov_len - offset;
2067                if (thislen > len)
2068                        thislen = len;
2069                sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen);
2070                ret = actor(sg, data);
2071                len -= thislen;
2072        }
2073        if (len != 0)
2074                ret = -EINVAL;
2075out:
2076        return ret;
2077}
2078EXPORT_SYMBOL_GPL(xdr_process_buf);
2079
2080/**
2081 * xdr_stream_decode_opaque - Decode variable length opaque
2082 * @xdr: pointer to xdr_stream
2083 * @ptr: location to store opaque data
2084 * @size: size of storage buffer @ptr
2085 *
2086 * Return values:
2087 *   On success, returns size of object stored in *@ptr
2088 *   %-EBADMSG on XDR buffer overflow
2089 *   %-EMSGSIZE on overflow of storage buffer @ptr
2090 */
2091ssize_t xdr_stream_decode_opaque(struct xdr_stream *xdr, void *ptr, size_t size)
2092{
2093        ssize_t ret;
2094        void *p;
2095
2096        ret = xdr_stream_decode_opaque_inline(xdr, &p, size);
2097        if (ret <= 0)
2098                return ret;
2099        memcpy(ptr, p, ret);
2100        return ret;
2101}
2102EXPORT_SYMBOL_GPL(xdr_stream_decode_opaque);
2103
2104/**
2105 * xdr_stream_decode_opaque_dup - Decode and duplicate variable length opaque
2106 * @xdr: pointer to xdr_stream
2107 * @ptr: location to store pointer to opaque data
2108 * @maxlen: maximum acceptable object size
2109 * @gfp_flags: GFP mask to use
2110 *
2111 * Return values:
2112 *   On success, returns size of object stored in *@ptr
2113 *   %-EBADMSG on XDR buffer overflow
2114 *   %-EMSGSIZE if the size of the object would exceed @maxlen
2115 *   %-ENOMEM on memory allocation failure
2116 */
2117ssize_t xdr_stream_decode_opaque_dup(struct xdr_stream *xdr, void **ptr,
2118                size_t maxlen, gfp_t gfp_flags)
2119{
2120        ssize_t ret;
2121        void *p;
2122
2123        ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
2124        if (ret > 0) {
2125                *ptr = kmemdup(p, ret, gfp_flags);
2126                if (*ptr != NULL)
2127                        return ret;
2128                ret = -ENOMEM;
2129        }
2130        *ptr = NULL;
2131        return ret;
2132}
2133EXPORT_SYMBOL_GPL(xdr_stream_decode_opaque_dup);
2134
2135/**
2136 * xdr_stream_decode_string - Decode variable length string
2137 * @xdr: pointer to xdr_stream
2138 * @str: location to store string
2139 * @size: size of storage buffer @str
2140 *
2141 * Return values:
2142 *   On success, returns length of NUL-terminated string stored in *@str
2143 *   %-EBADMSG on XDR buffer overflow
2144 *   %-EMSGSIZE on overflow of storage buffer @str
2145 */
2146ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str, size_t size)
2147{
2148        ssize_t ret;
2149        void *p;
2150
2151        ret = xdr_stream_decode_opaque_inline(xdr, &p, size);
2152        if (ret > 0) {
2153                memcpy(str, p, ret);
2154                str[ret] = '\0';
2155                return strlen(str);
2156        }
2157        *str = '\0';
2158        return ret;
2159}
2160EXPORT_SYMBOL_GPL(xdr_stream_decode_string);
2161
2162/**
2163 * xdr_stream_decode_string_dup - Decode and duplicate variable length string
2164 * @xdr: pointer to xdr_stream
2165 * @str: location to store pointer to string
2166 * @maxlen: maximum acceptable string length
2167 * @gfp_flags: GFP mask to use
2168 *
2169 * Return values:
2170 *   On success, returns length of NUL-terminated string stored in *@ptr
2171 *   %-EBADMSG on XDR buffer overflow
2172 *   %-EMSGSIZE if the size of the string would exceed @maxlen
2173 *   %-ENOMEM on memory allocation failure
2174 */
2175ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
2176                size_t maxlen, gfp_t gfp_flags)
2177{
2178        void *p;
2179        ssize_t ret;
2180
2181        ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
2182        if (ret > 0) {
2183                char *s = kmemdup_nul(p, ret, gfp_flags);
2184                if (s != NULL) {
2185                        *str = s;
2186                        return strlen(s);
2187                }
2188                ret = -ENOMEM;
2189        }
2190        *str = NULL;
2191        return ret;
2192}
2193EXPORT_SYMBOL_GPL(xdr_stream_decode_string_dup);
2194