Lines Matching +full:data +full:- +full:shift
1 // SPDX-License-Identifier: GPL-2.0-only
31 unsigned int quadlen = XDR_QUADLEN(obj->len); in xdr_encode_netobj()
34 *p++ = cpu_to_be32(obj->len); in xdr_encode_netobj()
35 memcpy(p, obj->data, obj->len); in xdr_encode_netobj()
36 return p + XDR_QUADLEN(obj->len); in xdr_encode_netobj()
47 obj->len = len; in xdr_decode_netobj()
48 obj->data = (u8 *) p; in xdr_decode_netobj()
54 * xdr_encode_opaque_fixed - Encode fixed length opaque data
56 * @ptr: pointer to data to encode (or NULL)
57 * @nbytes: size of data.
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
71 unsigned int padding = (quadlen << 2) - nbytes; in xdr_encode_opaque_fixed()
84 * xdr_encode_opaque - Encode variable length opaque data
86 * @ptr: pointer to data to encode (or NULL)
87 * @nbytes: size of data.
121 * xdr_terminate_string - '\0'-terminate a string residing in an xdr_buf
130 kaddr = kmap_atomic(buf->pages[0]); in xdr_terminate_string()
131 kaddr[buf->page_base + len] = '\0'; in xdr_terminate_string()
138 if (!buf->page_len) in xdr_buf_pagecount()
140 return (buf->page_base + buf->page_len + PAGE_SIZE - 1) >> PAGE_SHIFT; in xdr_buf_pagecount()
148 if (n != 0 && buf->bvec == NULL) { in xdr_alloc_bvec()
149 buf->bvec = kmalloc_array(n, sizeof(buf->bvec[0]), gfp); in xdr_alloc_bvec()
150 if (!buf->bvec) in xdr_alloc_bvec()
151 return -ENOMEM; in xdr_alloc_bvec()
153 bvec_set_page(&buf->bvec[i], buf->pages[i], PAGE_SIZE, in xdr_alloc_bvec()
163 kfree(buf->bvec); in xdr_free_bvec()
164 buf->bvec = NULL; in xdr_free_bvec()
168 * xdr_buf_to_bvec - Copy components of an xdr_buf into a bio_vec array
178 const struct kvec *head = xdr->head; in xdr_buf_to_bvec()
179 const struct kvec *tail = xdr->tail; in xdr_buf_to_bvec()
182 if (head->iov_len) { in xdr_buf_to_bvec()
183 bvec_set_virt(bvec++, head->iov_base, head->iov_len); in xdr_buf_to_bvec()
187 if (xdr->page_len) { in xdr_buf_to_bvec()
189 struct page **pages = xdr->pages; in xdr_buf_to_bvec()
191 offset = offset_in_page(xdr->page_base); in xdr_buf_to_bvec()
192 remaining = xdr->page_len; in xdr_buf_to_bvec()
195 PAGE_SIZE - offset); in xdr_buf_to_bvec()
197 remaining -= len; in xdr_buf_to_bvec()
204 if (tail->iov_len) { in xdr_buf_to_bvec()
205 bvec_set_virt(bvec, tail->iov_base, tail->iov_len); in xdr_buf_to_bvec()
214 return count - 1; in xdr_buf_to_bvec()
218 * xdr_inline_pages - Prepare receive buffer for a large reply
220 * @offset: expected offset where data payload will start, in bytes
223 * @len: expected size of the upper layer data payload, in bytes
230 struct kvec *head = xdr->head; in xdr_inline_pages()
231 struct kvec *tail = xdr->tail; in xdr_inline_pages()
232 char *buf = (char *)head->iov_base; in xdr_inline_pages()
233 unsigned int buflen = head->iov_len; in xdr_inline_pages()
235 head->iov_len = offset; in xdr_inline_pages()
237 xdr->pages = pages; in xdr_inline_pages()
238 xdr->page_base = base; in xdr_inline_pages()
239 xdr->page_len = len; in xdr_inline_pages()
241 tail->iov_base = buf + offset; in xdr_inline_pages()
242 tail->iov_len = buflen - offset; in xdr_inline_pages()
243 xdr->buflen += len; in xdr_inline_pages()
295 if (copy > (PAGE_SIZE - pgto_base)) in _shift_data_left_pages()
296 copy = PAGE_SIZE - pgto_base; in _shift_data_left_pages()
297 if (copy > (PAGE_SIZE - pgfrom_base)) in _shift_data_left_pages()
298 copy = PAGE_SIZE - pgfrom_base; in _shift_data_left_pages()
313 } while ((len -= copy) != 0); in _shift_data_left_pages()
356 pgto--; in _shift_data_right_pages()
360 pgfrom--; in _shift_data_right_pages()
368 pgto_base -= copy; in _shift_data_right_pages()
369 pgfrom_base -= copy; in _shift_data_right_pages()
381 } while ((len -= copy) != 0); in _shift_data_right_pages()
388 * @p: pointer to source data
391 * Copies data from an arbitrary memory location into an array of pages
392 * The copy is assumed to be non-overlapping.
408 copy = PAGE_SIZE - pgbase; in _copy_to_pages()
416 len -= copy; in _copy_to_pages()
435 * @pgbase: offset of source data
438 * Copies data into an arbitrary memory location from an array of pages
439 * The copy is assumed to be non-overlapping.
455 copy = PAGE_SIZE - pgbase; in _copy_from_pages()
470 } while ((len -= copy) != 0); in _copy_from_pages()
477 if (base >= iov->iov_len) in xdr_buf_iov_zero()
479 if (len > iov->iov_len - base) in xdr_buf_iov_zero()
480 len = iov->iov_len - base; in xdr_buf_iov_zero()
481 memset(iov->iov_base + base, 0, len); in xdr_buf_iov_zero()
493 struct page **pages = buf->pages; in xdr_buf_pages_zero()
500 if (pgbase >= buf->page_len) { in xdr_buf_pages_zero()
501 xdr_buf_iov_zero(buf->tail, pgbase - buf->page_len, len); in xdr_buf_pages_zero()
504 if (pgbase + len > buf->page_len) { in xdr_buf_pages_zero()
505 xdr_buf_iov_zero(buf->tail, 0, pgbase + len - buf->page_len); in xdr_buf_pages_zero()
506 len = buf->page_len - pgbase; in xdr_buf_pages_zero()
509 pgbase += buf->page_base; in xdr_buf_pages_zero()
515 zero = PAGE_SIZE - pgbase; in xdr_buf_pages_zero()
527 } while ((len -= zero) != 0); in xdr_buf_pages_zero()
535 if (!(buf->flags & XDRBUF_SPARSE_PAGES)) in xdr_buf_pages_fill_sparse()
537 if (buflen <= buf->head->iov_len) in xdr_buf_pages_fill_sparse()
539 pagelen = buflen - buf->head->iov_len; in xdr_buf_pages_fill_sparse()
540 if (pagelen > buf->page_len) in xdr_buf_pages_fill_sparse()
541 pagelen = buf->page_len; in xdr_buf_pages_fill_sparse()
542 npages = (pagelen + buf->page_base + PAGE_SIZE - 1) >> PAGE_SHIFT; in xdr_buf_pages_fill_sparse()
544 if (!buf->pages[i]) in xdr_buf_pages_fill_sparse()
546 buf->pages[i] = alloc_page(gfp); in xdr_buf_pages_fill_sparse()
547 if (likely(buf->pages[i])) in xdr_buf_pages_fill_sparse()
549 buflen -= pagelen; in xdr_buf_pages_fill_sparse()
551 if (pagelen > buf->page_base) in xdr_buf_pages_fill_sparse()
552 buflen += pagelen - buf->page_base; in xdr_buf_pages_fill_sparse()
560 struct kvec *head = buf->head; in xdr_buf_try_expand()
561 struct kvec *tail = buf->tail; in xdr_buf_try_expand()
562 unsigned int sum = head->iov_len + buf->page_len + tail->iov_len; in xdr_buf_try_expand()
565 if (sum > buf->len) { in xdr_buf_try_expand()
566 free_space = min_t(unsigned int, sum - buf->len, len); in xdr_buf_try_expand()
567 newlen = xdr_buf_pages_fill_sparse(buf, buf->len + free_space, in xdr_buf_try_expand()
569 free_space = newlen - buf->len; in xdr_buf_try_expand()
570 buf->len = newlen; in xdr_buf_try_expand()
571 len -= free_space; in xdr_buf_try_expand()
576 if (buf->buflen > sum) { in xdr_buf_try_expand()
578 free_space = min_t(unsigned int, buf->buflen - sum, len); in xdr_buf_try_expand()
579 tail->iov_len += free_space; in xdr_buf_try_expand()
580 buf->len += free_space; in xdr_buf_try_expand()
586 unsigned int shift) in xdr_buf_tail_copy_right() argument
588 const struct kvec *tail = buf->tail; in xdr_buf_tail_copy_right()
589 unsigned int to = base + shift; in xdr_buf_tail_copy_right()
591 if (to >= tail->iov_len) in xdr_buf_tail_copy_right()
593 if (len + to > tail->iov_len) in xdr_buf_tail_copy_right()
594 len = tail->iov_len - to; in xdr_buf_tail_copy_right()
595 memmove(tail->iov_base + to, tail->iov_base + base, len); in xdr_buf_tail_copy_right()
600 unsigned int shift) in xdr_buf_pages_copy_right() argument
602 const struct kvec *tail = buf->tail; in xdr_buf_pages_copy_right()
603 unsigned int to = base + shift; in xdr_buf_pages_copy_right()
607 if (base >= buf->page_len) in xdr_buf_pages_copy_right()
609 if (len > buf->page_len - base) in xdr_buf_pages_copy_right()
610 len = buf->page_len - base; in xdr_buf_pages_copy_right()
611 if (to >= buf->page_len) { in xdr_buf_pages_copy_right()
612 tato = to - buf->page_len; in xdr_buf_pages_copy_right()
613 if (tail->iov_len >= len + tato) in xdr_buf_pages_copy_right()
615 else if (tail->iov_len > tato) in xdr_buf_pages_copy_right()
616 talen = tail->iov_len - tato; in xdr_buf_pages_copy_right()
617 } else if (len + to >= buf->page_len) { in xdr_buf_pages_copy_right()
618 pglen = buf->page_len - to; in xdr_buf_pages_copy_right()
619 talen = len - pglen; in xdr_buf_pages_copy_right()
620 if (talen > tail->iov_len) in xdr_buf_pages_copy_right()
621 talen = tail->iov_len; in xdr_buf_pages_copy_right()
625 _copy_from_pages(tail->iov_base + tato, buf->pages, in xdr_buf_pages_copy_right()
626 buf->page_base + base + pglen, talen); in xdr_buf_pages_copy_right()
627 _shift_data_right_pages(buf->pages, buf->page_base + to, in xdr_buf_pages_copy_right()
628 buf->page_base + base, pglen); in xdr_buf_pages_copy_right()
633 unsigned int shift) in xdr_buf_head_copy_right() argument
635 const struct kvec *head = buf->head; in xdr_buf_head_copy_right()
636 const struct kvec *tail = buf->tail; in xdr_buf_head_copy_right()
637 unsigned int to = base + shift; in xdr_buf_head_copy_right()
641 if (base >= head->iov_len) in xdr_buf_head_copy_right()
643 if (len > head->iov_len - base) in xdr_buf_head_copy_right()
644 len = head->iov_len - base; in xdr_buf_head_copy_right()
645 if (to >= buf->page_len + head->iov_len) { in xdr_buf_head_copy_right()
646 tato = to - buf->page_len - head->iov_len; in xdr_buf_head_copy_right()
648 } else if (to >= head->iov_len) { in xdr_buf_head_copy_right()
649 pgto = to - head->iov_len; in xdr_buf_head_copy_right()
651 if (pgto + pglen > buf->page_len) { in xdr_buf_head_copy_right()
652 talen = pgto + pglen - buf->page_len; in xdr_buf_head_copy_right()
653 pglen -= talen; in xdr_buf_head_copy_right()
656 pglen = len - to; in xdr_buf_head_copy_right()
657 if (pglen > buf->page_len) { in xdr_buf_head_copy_right()
658 talen = pglen - buf->page_len; in xdr_buf_head_copy_right()
659 pglen = buf->page_len; in xdr_buf_head_copy_right()
663 len -= talen; in xdr_buf_head_copy_right()
665 if (talen + tato > tail->iov_len) in xdr_buf_head_copy_right()
666 talen = tail->iov_len > tato ? tail->iov_len - tato : 0; in xdr_buf_head_copy_right()
667 memcpy(tail->iov_base + tato, head->iov_base + base, talen); in xdr_buf_head_copy_right()
669 len -= pglen; in xdr_buf_head_copy_right()
670 base -= pglen; in xdr_buf_head_copy_right()
671 _copy_to_pages(buf->pages, buf->page_base + pgto, head->iov_base + base, in xdr_buf_head_copy_right()
674 base -= len; in xdr_buf_head_copy_right()
675 memmove(head->iov_base + to, head->iov_base + base, len); in xdr_buf_head_copy_right()
680 unsigned int shift) in xdr_buf_tail_shift_right() argument
682 const struct kvec *tail = buf->tail; in xdr_buf_tail_shift_right()
684 if (base >= tail->iov_len || !shift || !len) in xdr_buf_tail_shift_right()
686 xdr_buf_tail_copy_right(buf, base, len, shift); in xdr_buf_tail_shift_right()
691 unsigned int shift) in xdr_buf_pages_shift_right() argument
693 if (!shift || !len) in xdr_buf_pages_shift_right()
695 if (base >= buf->page_len) { in xdr_buf_pages_shift_right()
696 xdr_buf_tail_shift_right(buf, base - buf->page_len, len, shift); in xdr_buf_pages_shift_right()
699 if (base + len > buf->page_len) in xdr_buf_pages_shift_right()
700 xdr_buf_tail_shift_right(buf, 0, base + len - buf->page_len, in xdr_buf_pages_shift_right()
701 shift); in xdr_buf_pages_shift_right()
702 xdr_buf_pages_copy_right(buf, base, len, shift); in xdr_buf_pages_shift_right()
707 unsigned int shift) in xdr_buf_head_shift_right() argument
709 const struct kvec *head = buf->head; in xdr_buf_head_shift_right()
711 if (!shift) in xdr_buf_head_shift_right()
713 if (base >= head->iov_len) { in xdr_buf_head_shift_right()
714 xdr_buf_pages_shift_right(buf, head->iov_len - base, len, in xdr_buf_head_shift_right()
715 shift); in xdr_buf_head_shift_right()
718 if (base + len > head->iov_len) in xdr_buf_head_shift_right()
719 xdr_buf_pages_shift_right(buf, 0, base + len - head->iov_len, in xdr_buf_head_shift_right()
720 shift); in xdr_buf_head_shift_right()
721 xdr_buf_head_copy_right(buf, base, len, shift); in xdr_buf_head_shift_right()
725 unsigned int len, unsigned int shift) in xdr_buf_tail_copy_left() argument
727 const struct kvec *tail = buf->tail; in xdr_buf_tail_copy_left()
729 if (base >= tail->iov_len) in xdr_buf_tail_copy_left()
731 if (len > tail->iov_len - base) in xdr_buf_tail_copy_left()
732 len = tail->iov_len - base; in xdr_buf_tail_copy_left()
733 /* Shift data into head */ in xdr_buf_tail_copy_left()
734 if (shift > buf->page_len + base) { in xdr_buf_tail_copy_left()
735 const struct kvec *head = buf->head; in xdr_buf_tail_copy_left()
737 head->iov_len + buf->page_len + base - shift; in xdr_buf_tail_copy_left()
740 if (WARN_ONCE(shift > head->iov_len + buf->page_len + base, in xdr_buf_tail_copy_left()
741 "SUNRPC: Misaligned data.\n")) in xdr_buf_tail_copy_left()
743 if (hdto + hdlen > head->iov_len) in xdr_buf_tail_copy_left()
744 hdlen = head->iov_len - hdto; in xdr_buf_tail_copy_left()
745 memcpy(head->iov_base + hdto, tail->iov_base + base, hdlen); in xdr_buf_tail_copy_left()
747 len -= hdlen; in xdr_buf_tail_copy_left()
751 /* Shift data into pages */ in xdr_buf_tail_copy_left()
752 if (shift > base) { in xdr_buf_tail_copy_left()
753 unsigned int pgto = buf->page_len + base - shift; in xdr_buf_tail_copy_left()
756 if (pgto + pglen > buf->page_len) in xdr_buf_tail_copy_left()
757 pglen = buf->page_len - pgto; in xdr_buf_tail_copy_left()
758 _copy_to_pages(buf->pages, buf->page_base + pgto, in xdr_buf_tail_copy_left()
759 tail->iov_base + base, pglen); in xdr_buf_tail_copy_left()
761 len -= pglen; in xdr_buf_tail_copy_left()
765 memmove(tail->iov_base + base - shift, tail->iov_base + base, len); in xdr_buf_tail_copy_left()
770 unsigned int shift) in xdr_buf_pages_copy_left() argument
774 if (base >= buf->page_len) in xdr_buf_pages_copy_left()
776 if (len > buf->page_len - base) in xdr_buf_pages_copy_left()
777 len = buf->page_len - base; in xdr_buf_pages_copy_left()
778 /* Shift data into head */ in xdr_buf_pages_copy_left()
779 if (shift > base) { in xdr_buf_pages_copy_left()
780 const struct kvec *head = buf->head; in xdr_buf_pages_copy_left()
781 unsigned int hdto = head->iov_len + base - shift; in xdr_buf_pages_copy_left()
784 if (WARN_ONCE(shift > head->iov_len + base, in xdr_buf_pages_copy_left()
785 "SUNRPC: Misaligned data.\n")) in xdr_buf_pages_copy_left()
787 if (hdto + hdlen > head->iov_len) in xdr_buf_pages_copy_left()
788 hdlen = head->iov_len - hdto; in xdr_buf_pages_copy_left()
789 _copy_from_pages(head->iov_base + hdto, buf->pages, in xdr_buf_pages_copy_left()
790 buf->page_base + base, hdlen); in xdr_buf_pages_copy_left()
792 len -= hdlen; in xdr_buf_pages_copy_left()
796 pgto = base - shift; in xdr_buf_pages_copy_left()
797 _shift_data_left_pages(buf->pages, buf->page_base + pgto, in xdr_buf_pages_copy_left()
798 buf->page_base + base, len); in xdr_buf_pages_copy_left()
803 unsigned int shift) in xdr_buf_tail_shift_left() argument
805 if (!shift || !len) in xdr_buf_tail_shift_left()
807 xdr_buf_tail_copy_left(buf, base, len, shift); in xdr_buf_tail_shift_left()
812 unsigned int shift) in xdr_buf_pages_shift_left() argument
814 if (!shift || !len) in xdr_buf_pages_shift_left()
816 if (base >= buf->page_len) { in xdr_buf_pages_shift_left()
817 xdr_buf_tail_shift_left(buf, base - buf->page_len, len, shift); in xdr_buf_pages_shift_left()
820 xdr_buf_pages_copy_left(buf, base, len, shift); in xdr_buf_pages_shift_left()
822 if (len <= buf->page_len) in xdr_buf_pages_shift_left()
824 xdr_buf_tail_copy_left(buf, 0, len - buf->page_len, shift); in xdr_buf_pages_shift_left()
829 unsigned int shift) in xdr_buf_head_shift_left() argument
831 const struct kvec *head = buf->head; in xdr_buf_head_shift_left()
834 if (!shift || !len) in xdr_buf_head_shift_left()
837 if (shift > base) { in xdr_buf_head_shift_left()
838 bytes = (shift - base); in xdr_buf_head_shift_left()
842 len -= bytes; in xdr_buf_head_shift_left()
845 if (base < head->iov_len) { in xdr_buf_head_shift_left()
846 bytes = min_t(unsigned int, len, head->iov_len - base); in xdr_buf_head_shift_left()
847 memmove(head->iov_base + (base - shift), in xdr_buf_head_shift_left()
848 head->iov_base + base, bytes); in xdr_buf_head_shift_left()
850 len -= bytes; in xdr_buf_head_shift_left()
852 xdr_buf_pages_shift_left(buf, base - head->iov_len, len, shift); in xdr_buf_head_shift_left()
858 * @len: new length of buf->head[0]
860 * Shrinks XDR buffer's header kvec buf->head[0], setting it to
861 * 'len' bytes. The extra data is not lost, but is instead
866 struct kvec *head = buf->head; in xdr_shrink_bufhead()
867 unsigned int shift, buflen = max(buf->len, len); in xdr_shrink_bufhead() local
869 WARN_ON_ONCE(len > head->iov_len); in xdr_shrink_bufhead()
870 if (head->iov_len > buflen) { in xdr_shrink_bufhead()
871 buf->buflen -= head->iov_len - buflen; in xdr_shrink_bufhead()
872 head->iov_len = buflen; in xdr_shrink_bufhead()
874 if (len >= head->iov_len) in xdr_shrink_bufhead()
876 shift = head->iov_len - len; in xdr_shrink_bufhead()
877 xdr_buf_try_expand(buf, shift); in xdr_shrink_bufhead()
878 xdr_buf_head_shift_right(buf, len, buflen - len, shift); in xdr_shrink_bufhead()
879 head->iov_len = len; in xdr_shrink_bufhead()
880 buf->buflen -= shift; in xdr_shrink_bufhead()
881 buf->len -= shift; in xdr_shrink_bufhead()
882 return shift; in xdr_shrink_bufhead()
886 * xdr_shrink_pagelen - shrinks buf->pages to @len bytes
890 * The extra data is not lost, but is instead moved into buf->tail.
895 unsigned int shift, buflen = buf->len - buf->head->iov_len; in xdr_shrink_pagelen() local
897 WARN_ON_ONCE(len > buf->page_len); in xdr_shrink_pagelen()
898 if (buf->head->iov_len >= buf->len || len > buflen) in xdr_shrink_pagelen()
900 if (buf->page_len > buflen) { in xdr_shrink_pagelen()
901 buf->buflen -= buf->page_len - buflen; in xdr_shrink_pagelen()
902 buf->page_len = buflen; in xdr_shrink_pagelen()
904 if (len >= buf->page_len) in xdr_shrink_pagelen()
906 shift = buf->page_len - len; in xdr_shrink_pagelen()
907 xdr_buf_try_expand(buf, shift); in xdr_shrink_pagelen()
908 xdr_buf_pages_shift_right(buf, len, buflen - len, shift); in xdr_shrink_pagelen()
909 buf->page_len = len; in xdr_shrink_pagelen()
910 buf->len -= shift; in xdr_shrink_pagelen()
911 buf->buflen -= shift; in xdr_shrink_pagelen()
912 return shift; in xdr_shrink_pagelen()
916 * xdr_stream_pos - Return the current offset from the start of the xdr_stream
921 return (unsigned int)(XDR_QUADLEN(xdr->buf->len) - xdr->nwords) << 2; in xdr_stream_pos()
927 unsigned int blen = xdr->buf->len; in xdr_stream_set_pos()
929 xdr->nwords = blen > pos ? XDR_QUADLEN(blen) - XDR_QUADLEN(pos) : 0; in xdr_stream_set_pos()
934 xdr_stream_set_pos(xdr, pos + xdr->buf->head[0].iov_len); in xdr_stream_page_set_pos()
938 * xdr_page_pos - Return the current offset from the start of the xdr pages
945 WARN_ON(pos < xdr->buf->head[0].iov_len); in xdr_page_pos()
946 return pos - xdr->buf->head[0].iov_len; in xdr_page_pos()
951 * xdr_init_encode - Initialize a struct xdr_stream for sending data.
953 * @buf: pointer to XDR buffer in which to encode data
960 * data. With the new scheme, the xdr_stream manages the details
967 struct kvec *iov = buf->head; in xdr_init_encode()
968 int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len; in xdr_init_encode()
972 xdr->buf = buf; in xdr_init_encode()
973 xdr->iov = iov; in xdr_init_encode()
974 xdr->p = (__be32 *)((char *)iov->iov_base + iov->iov_len); in xdr_init_encode()
975 xdr->end = (__be32 *)((char *)iov->iov_base + scratch_len); in xdr_init_encode()
976 BUG_ON(iov->iov_len > scratch_len); in xdr_init_encode()
978 if (p != xdr->p && p != NULL) { in xdr_init_encode()
981 BUG_ON(p < xdr->p || p > xdr->end); in xdr_init_encode()
982 len = (char *)p - (char *)xdr->p; in xdr_init_encode()
983 xdr->p = p; in xdr_init_encode()
984 buf->len += len; in xdr_init_encode()
985 iov->iov_len += len; in xdr_init_encode()
987 xdr->rqst = rqst; in xdr_init_encode()
992 * xdr_init_encode_pages - Initialize an xdr_stream for encoding into pages
994 * @buf: pointer to XDR buffer into which to encode data
1004 xdr->buf = buf; in xdr_init_encode_pages()
1005 xdr->page_ptr = pages; in xdr_init_encode_pages()
1006 xdr->iov = NULL; in xdr_init_encode_pages()
1007 xdr->p = page_address(*pages); in xdr_init_encode_pages()
1008 xdr->end = (void *)xdr->p + min_t(u32, buf->buflen, PAGE_SIZE); in xdr_init_encode_pages()
1009 xdr->rqst = rqst; in xdr_init_encode_pages()
1014 * __xdr_commit_encode - Ensure all data is written to buffer
1018 * temporary location to write to, then later copying the data into
1024 * data might be read.
1028 size_t shift = xdr->scratch.iov_len; in __xdr_commit_encode() local
1031 page = page_address(*xdr->page_ptr); in __xdr_commit_encode()
1032 memcpy(xdr->scratch.iov_base, page, shift); in __xdr_commit_encode()
1033 memmove(page, page + shift, (void *)xdr->p - page); in __xdr_commit_encode()
1040 * xdr->buf->head and xdr->buf->pages, or between two pages
1041 * in xdr->buf->pages.
1052 if (xdr->buf->len + nbytes > xdr->buf->buflen) in xdr_get_next_encode_buffer()
1054 frag1bytes = (xdr->end - xdr->p) << 2; in xdr_get_next_encode_buffer()
1055 frag2bytes = nbytes - frag1bytes; in xdr_get_next_encode_buffer()
1056 if (xdr->iov) in xdr_get_next_encode_buffer()
1057 xdr->iov->iov_len += frag1bytes; in xdr_get_next_encode_buffer()
1059 xdr->buf->page_len += frag1bytes; in xdr_get_next_encode_buffer()
1060 xdr->page_ptr++; in xdr_get_next_encode_buffer()
1061 xdr->iov = NULL; in xdr_get_next_encode_buffer()
1070 xdr_set_scratch_buffer(xdr, xdr->p, frag1bytes); in xdr_get_next_encode_buffer()
1073 * xdr->p is where the next encode will start after in xdr_get_next_encode_buffer()
1076 p = page_address(*xdr->page_ptr); in xdr_get_next_encode_buffer()
1077 xdr->p = p + frag2bytes; in xdr_get_next_encode_buffer()
1078 space_left = xdr->buf->buflen - xdr->buf->len; in xdr_get_next_encode_buffer()
1079 if (space_left - frag1bytes >= PAGE_SIZE) in xdr_get_next_encode_buffer()
1080 xdr->end = p + PAGE_SIZE; in xdr_get_next_encode_buffer()
1082 xdr->end = p + space_left - frag1bytes; in xdr_get_next_encode_buffer()
1084 xdr->buf->page_len += frag2bytes; in xdr_get_next_encode_buffer()
1085 xdr->buf->len += nbytes; in xdr_get_next_encode_buffer()
1093 * xdr_reserve_space - Reserve buffer space for sending
1098 * bytes of data. If so, update the total xdr_buf length, and
1103 __be32 *p = xdr->p; in xdr_reserve_space()
1107 /* align nbytes on the next 32-bit boundary */ in xdr_reserve_space()
1111 if (unlikely(q > xdr->end || q < p)) in xdr_reserve_space()
1113 xdr->p = q; in xdr_reserve_space()
1114 if (xdr->iov) in xdr_reserve_space()
1115 xdr->iov->iov_len += nbytes; in xdr_reserve_space()
1117 xdr->buf->page_len += nbytes; in xdr_reserve_space()
1118 xdr->buf->len += nbytes; in xdr_reserve_space()
1124 * xdr_reserve_space_vec - Reserves a large amount of buffer space for sending
1134 * %-EMSGSIZE: not enough space is available in @xdr
1143 * in xdr->pages. in xdr_reserve_space_vec()
1145 if (xdr->iov == xdr->buf->head) { in xdr_reserve_space_vec()
1146 xdr->iov = NULL; in xdr_reserve_space_vec()
1147 xdr->end = xdr->p; in xdr_reserve_space_vec()
1152 thislen = xdr->buf->page_len % PAGE_SIZE; in xdr_reserve_space_vec()
1153 thislen = min_t(size_t, nbytes, PAGE_SIZE - thislen); in xdr_reserve_space_vec()
1157 return -EMSGSIZE; in xdr_reserve_space_vec()
1159 nbytes -= thislen; in xdr_reserve_space_vec()
1167 * xdr_truncate_encode - truncate an encode buffer
1171 * Truncates the xdr stream, so that xdr->buf->len == len,
1172 * and xdr->p points at offset len from the start of the buffer, and
1175 * If this means moving xdr->p to a different buffer, we assume that
1181 * cache pages (as in a zero-copy server read reply), except for the
1187 struct xdr_buf *buf = xdr->buf; in xdr_truncate_encode()
1188 struct kvec *head = buf->head; in xdr_truncate_encode()
1189 struct kvec *tail = buf->tail; in xdr_truncate_encode()
1193 if (len > buf->len) { in xdr_truncate_encode()
1199 fraglen = min_t(int, buf->len - len, tail->iov_len); in xdr_truncate_encode()
1200 tail->iov_len -= fraglen; in xdr_truncate_encode()
1201 buf->len -= fraglen; in xdr_truncate_encode()
1202 if (tail->iov_len) { in xdr_truncate_encode()
1203 xdr->p = tail->iov_base + tail->iov_len; in xdr_truncate_encode()
1204 WARN_ON_ONCE(!xdr->end); in xdr_truncate_encode()
1205 WARN_ON_ONCE(!xdr->iov); in xdr_truncate_encode()
1209 fraglen = min_t(int, buf->len - len, buf->page_len); in xdr_truncate_encode()
1210 buf->page_len -= fraglen; in xdr_truncate_encode()
1211 buf->len -= fraglen; in xdr_truncate_encode()
1213 new = buf->page_base + buf->page_len; in xdr_truncate_encode()
1215 xdr->page_ptr = buf->pages + (new >> PAGE_SHIFT); in xdr_truncate_encode()
1217 if (buf->page_len) { in xdr_truncate_encode()
1218 xdr->p = page_address(*xdr->page_ptr); in xdr_truncate_encode()
1219 xdr->end = (void *)xdr->p + PAGE_SIZE; in xdr_truncate_encode()
1220 xdr->p = (void *)xdr->p + (new % PAGE_SIZE); in xdr_truncate_encode()
1221 WARN_ON_ONCE(xdr->iov); in xdr_truncate_encode()
1225 xdr->end = head->iov_base + head->iov_len; in xdr_truncate_encode()
1226 /* (otherwise assume xdr->end is already set) */ in xdr_truncate_encode()
1227 xdr->page_ptr--; in xdr_truncate_encode()
1228 head->iov_len = len; in xdr_truncate_encode()
1229 buf->len = len; in xdr_truncate_encode()
1230 xdr->p = head->iov_base + head->iov_len; in xdr_truncate_encode()
1231 xdr->iov = buf->head; in xdr_truncate_encode()
1236 * xdr_truncate_decode - Truncate a decoding stream
1245 xdr->buf->len -= nbytes; in xdr_truncate_decode()
1246 xdr->nwords -= XDR_QUADLEN(nbytes); in xdr_truncate_decode()
1251 * xdr_restrict_buflen - decrease available buffer space
1256 * If we've already used too much space in the buffer, returns -1.
1258 * and does nothing. Otherwise, adjusts xdr->buf->buflen to newbuflen
1259 * and ensures xdr->end is set at most offset newbuflen from the start
1264 struct xdr_buf *buf = xdr->buf; in xdr_restrict_buflen()
1265 int left_in_this_buf = (void *)xdr->end - (void *)xdr->p; in xdr_restrict_buflen()
1266 int end_offset = buf->len + left_in_this_buf; in xdr_restrict_buflen()
1268 if (newbuflen < 0 || newbuflen < buf->len) in xdr_restrict_buflen()
1269 return -1; in xdr_restrict_buflen()
1270 if (newbuflen > buf->buflen) in xdr_restrict_buflen()
1273 xdr->end = (void *)xdr->end + newbuflen - end_offset; in xdr_restrict_buflen()
1274 buf->buflen = newbuflen; in xdr_restrict_buflen()
1280 * xdr_write_pages - Insert a list of pages into an XDR buffer for sending
1283 * @base: starting offset of first data byte in @pages
1284 * @len: number of data bytes in @pages to insert
1293 struct xdr_buf *buf = xdr->buf; in xdr_write_pages()
1294 struct kvec *tail = buf->tail; in xdr_write_pages()
1296 buf->pages = pages; in xdr_write_pages()
1297 buf->page_base = base; in xdr_write_pages()
1298 buf->page_len = len; in xdr_write_pages()
1300 tail->iov_base = xdr->p; in xdr_write_pages()
1301 tail->iov_len = 0; in xdr_write_pages()
1302 xdr->iov = tail; in xdr_write_pages()
1305 unsigned int pad = 4 - (len & 3); in xdr_write_pages()
1307 BUG_ON(xdr->p >= xdr->end); in xdr_write_pages()
1308 tail->iov_base = (char *)xdr->p + (len & 3); in xdr_write_pages()
1309 tail->iov_len += pad; in xdr_write_pages()
1311 *xdr->p++ = 0; in xdr_write_pages()
1313 buf->buflen += len; in xdr_write_pages()
1314 buf->len += len; in xdr_write_pages()
1321 if (len > iov->iov_len) in xdr_set_iov()
1322 len = iov->iov_len; in xdr_set_iov()
1325 xdr->p = (__be32*)(iov->iov_base + base); in xdr_set_iov()
1326 xdr->end = (__be32*)(iov->iov_base + len); in xdr_set_iov()
1327 xdr->iov = iov; in xdr_set_iov()
1328 xdr->page_ptr = NULL; in xdr_set_iov()
1329 return len - base; in xdr_set_iov()
1335 struct xdr_buf *buf = xdr->buf; in xdr_set_tail_base()
1337 xdr_stream_set_pos(xdr, base + buf->page_len + buf->head->iov_len); in xdr_set_tail_base()
1338 return xdr_set_iov(xdr, buf->tail, base, len); in xdr_set_tail_base()
1343 if (xdr->page_kaddr) { in xdr_stream_unmap_current_page()
1344 kunmap_local(xdr->page_kaddr); in xdr_stream_unmap_current_page()
1345 xdr->page_kaddr = NULL; in xdr_stream_unmap_current_page()
1358 maxlen = xdr->buf->page_len; in xdr_set_page_base()
1362 maxlen -= base; in xdr_set_page_base()
1368 base += xdr->buf->page_base; in xdr_set_page_base()
1371 xdr->page_ptr = &xdr->buf->pages[pgnr]; in xdr_set_page_base()
1373 if (PageHighMem(*xdr->page_ptr)) { in xdr_set_page_base()
1374 xdr->page_kaddr = kmap_local_page(*xdr->page_ptr); in xdr_set_page_base()
1375 kaddr = xdr->page_kaddr; in xdr_set_page_base()
1377 kaddr = page_address(*xdr->page_ptr); in xdr_set_page_base()
1380 xdr->p = (__be32*)(kaddr + pgoff); in xdr_set_page_base()
1385 xdr->end = (__be32*)(kaddr + pgend); in xdr_set_page_base()
1386 xdr->iov = NULL; in xdr_set_page_base()
1394 base -= xdr->buf->page_len; in xdr_set_page()
1403 newbase = (1 + xdr->page_ptr - xdr->buf->pages) << PAGE_SHIFT; in xdr_set_next_page()
1404 newbase -= xdr->buf->page_base; in xdr_set_next_page()
1405 if (newbase < xdr->buf->page_len) in xdr_set_next_page()
1413 if (xdr->page_ptr != NULL) in xdr_set_next_buffer()
1415 else if (xdr->iov == xdr->buf->head) in xdr_set_next_buffer()
1417 return xdr->p != xdr->end; in xdr_set_next_buffer()
1421 * xdr_init_decode - Initialize an xdr_stream for decoding data.
1423 * @buf: pointer to XDR buffer from which to decode data
1430 xdr->buf = buf; in xdr_init_decode()
1431 xdr->page_kaddr = NULL; in xdr_init_decode()
1433 xdr->nwords = XDR_QUADLEN(buf->len); in xdr_init_decode()
1434 if (xdr_set_iov(xdr, buf->head, 0, buf->len) == 0 && in xdr_init_decode()
1435 xdr_set_page_base(xdr, 0, buf->len) == 0) in xdr_init_decode()
1436 xdr_set_iov(xdr, buf->tail, 0, buf->len); in xdr_init_decode()
1437 if (p != NULL && p > xdr->p && xdr->end >= p) { in xdr_init_decode()
1438 xdr->nwords -= p - xdr->p; in xdr_init_decode()
1439 xdr->p = p; in xdr_init_decode()
1441 xdr->rqst = rqst; in xdr_init_decode()
1446 * xdr_init_decode_pages - Initialize an xdr_stream for decoding into pages
1448 * @buf: pointer to XDR buffer from which to decode data
1456 buf->pages = pages; in xdr_init_decode_pages()
1457 buf->page_len = len; in xdr_init_decode_pages()
1458 buf->buflen = len; in xdr_init_decode_pages()
1459 buf->len = len; in xdr_init_decode_pages()
1465 * xdr_finish_decode - Clean up the xdr_stream after decoding data.
1477 __be32 *p = xdr->p; in __xdr_inline_decode()
1480 if (unlikely(nwords > xdr->nwords || q > xdr->end || q < p)) in __xdr_inline_decode()
1482 xdr->p = q; in __xdr_inline_decode()
1483 xdr->nwords -= nwords; in __xdr_inline_decode()
1490 char *cpdest = xdr->scratch.iov_base; in xdr_copy_to_scratch()
1491 size_t cplen = (char *)xdr->end - (char *)xdr->p; in xdr_copy_to_scratch()
1493 if (nbytes > xdr->scratch.iov_len) in xdr_copy_to_scratch()
1502 nbytes -= cplen; in xdr_copy_to_scratch()
1507 return xdr->scratch.iov_base; in xdr_copy_to_scratch()
1514 * xdr_inline_decode - Retrieve XDR data to decode
1516 * @nbytes: number of bytes of data to decode
1519 * 'nbytes' more bytes of data starting at the current position.
1528 return xdr->p; in xdr_inline_decode()
1529 if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr)) in xdr_inline_decode()
1543 struct xdr_buf *buf = xdr->buf; in xdr_realign_pages()
1544 struct kvec *iov = buf->head; in xdr_realign_pages()
1549 if (iov->iov_len > cur) { in xdr_realign_pages()
1552 xdr_set_page(xdr, 0, buf->page_len); in xdr_realign_pages()
1558 struct xdr_buf *buf = xdr->buf; in xdr_align_pages()
1562 if (xdr->nwords == 0) in xdr_align_pages()
1566 if (nwords > xdr->nwords) { in xdr_align_pages()
1567 nwords = xdr->nwords; in xdr_align_pages()
1570 if (buf->page_len <= len) in xdr_align_pages()
1571 len = buf->page_len; in xdr_align_pages()
1572 else if (nwords < xdr->nwords) { in xdr_align_pages()
1573 /* Truncate page data and move it into the tail */ in xdr_align_pages()
1581 * xdr_read_pages - align page-based XDR data to current pointer position
1583 * @len: number of bytes of page data
1585 * Moves data beyond the current pointer position from the XDR head[] buffer
1586 * into the page list. Any data that lies beyond current position + @len
1588 * then advanced past that data to align to the next XDR object in the tail.
1601 base = (nwords << 2) - pglen; in xdr_read_pages()
1602 end = xdr_stream_remaining(xdr) - pglen; in xdr_read_pages()
1610 * xdr_set_pagelen - Sets the length of the XDR pages
1612 * @len: new length of the XDR page data
1615 * @len bytes. When shrinking, any extra data is moved into buf->tail, whereas
1616 * when growing any data beyond the current pointer is moved into the tail.
1622 struct xdr_buf *buf = xdr->buf; in xdr_set_pagelen()
1626 if (len < buf->page_len) { in xdr_set_pagelen()
1627 base = buf->page_len - len; in xdr_set_pagelen()
1631 buf->page_len, remaining); in xdr_set_pagelen()
1632 if (len > buf->page_len) in xdr_set_pagelen()
1633 xdr_buf_try_expand(buf, len - buf->page_len); in xdr_set_pagelen()
1640 * xdr_enter_page - decode data from the XDR page
1642 * @len: number of bytes of page data
1644 * Moves data beyond the current pointer position from the XDR head[] buffer
1645 * into the page list. Any data that lies beyond current position + "len"
1665 buf->head[0] = *iov; in xdr_buf_from_iov()
1666 buf->tail[0] = empty_iov; in xdr_buf_from_iov()
1667 buf->page_len = 0; in xdr_buf_from_iov()
1668 buf->buflen = buf->len = iov->iov_len; in xdr_buf_from_iov()
1673 * xdr_buf_subsegment - set subbuf to a portion of buf
1684 * Returns -1 if base or length are out of bounds.
1689 subbuf->buflen = subbuf->len = len; in xdr_buf_subsegment()
1690 if (base < buf->head[0].iov_len) { in xdr_buf_subsegment()
1691 subbuf->head[0].iov_base = buf->head[0].iov_base + base; in xdr_buf_subsegment()
1692 subbuf->head[0].iov_len = min_t(unsigned int, len, in xdr_buf_subsegment()
1693 buf->head[0].iov_len - base); in xdr_buf_subsegment()
1694 len -= subbuf->head[0].iov_len; in xdr_buf_subsegment()
1697 base -= buf->head[0].iov_len; in xdr_buf_subsegment()
1698 subbuf->head[0].iov_base = buf->head[0].iov_base; in xdr_buf_subsegment()
1699 subbuf->head[0].iov_len = 0; in xdr_buf_subsegment()
1702 if (base < buf->page_len) { in xdr_buf_subsegment()
1703 subbuf->page_len = min(buf->page_len - base, len); in xdr_buf_subsegment()
1704 base += buf->page_base; in xdr_buf_subsegment()
1705 subbuf->page_base = base & ~PAGE_MASK; in xdr_buf_subsegment()
1706 subbuf->pages = &buf->pages[base >> PAGE_SHIFT]; in xdr_buf_subsegment()
1707 len -= subbuf->page_len; in xdr_buf_subsegment()
1710 base -= buf->page_len; in xdr_buf_subsegment()
1711 subbuf->pages = buf->pages; in xdr_buf_subsegment()
1712 subbuf->page_base = 0; in xdr_buf_subsegment()
1713 subbuf->page_len = 0; in xdr_buf_subsegment()
1716 if (base < buf->tail[0].iov_len) { in xdr_buf_subsegment()
1717 subbuf->tail[0].iov_base = buf->tail[0].iov_base + base; in xdr_buf_subsegment()
1718 subbuf->tail[0].iov_len = min_t(unsigned int, len, in xdr_buf_subsegment()
1719 buf->tail[0].iov_len - base); in xdr_buf_subsegment()
1720 len -= subbuf->tail[0].iov_len; in xdr_buf_subsegment()
1723 base -= buf->tail[0].iov_len; in xdr_buf_subsegment()
1724 subbuf->tail[0].iov_base = buf->tail[0].iov_base; in xdr_buf_subsegment()
1725 subbuf->tail[0].iov_len = 0; in xdr_buf_subsegment()
1729 return -1; in xdr_buf_subsegment()
1735 * xdr_stream_subsegment - set @subbuf to a portion of @xdr
1743 * XDR data item following that portion.
1755 /* Extract @subbuf and bounds-check the fn arguments */ in xdr_stream_subsegment()
1756 if (xdr_buf_subsegment(xdr->buf, subbuf, start, nbytes)) in xdr_stream_subsegment()
1761 if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr)) in xdr_stream_subsegment()
1764 len = (char *)xdr->end - (char *)xdr->p; in xdr_stream_subsegment()
1766 xdr->p = (__be32 *)((char *)xdr->p + in xdr_stream_subsegment()
1771 xdr->p = (__be32 *)((char *)xdr->p + len); in xdr_stream_subsegment()
1772 xdr->end = xdr->p; in xdr_stream_subsegment()
1773 remaining -= len; in xdr_stream_subsegment()
1782 * xdr_stream_move_subsegment - Move part of a stream to another position
1795 unsigned int shift; in xdr_stream_move_subsegment() local
1798 shift = target - offset; in xdr_stream_move_subsegment()
1799 if (xdr_buf_subsegment(xdr->buf, &buf, offset, shift + length) < 0) in xdr_stream_move_subsegment()
1801 xdr_buf_head_shift_right(&buf, 0, length, shift); in xdr_stream_move_subsegment()
1803 shift = offset - target; in xdr_stream_move_subsegment()
1804 if (xdr_buf_subsegment(xdr->buf, &buf, target, shift + length) < 0) in xdr_stream_move_subsegment()
1806 xdr_buf_head_shift_left(&buf, shift, length, shift); in xdr_stream_move_subsegment()
1813 * xdr_stream_zero - zero out a portion of an xdr_stream
1823 if (xdr_buf_subsegment(xdr->buf, &buf, offset, length) < 0) in xdr_stream_zero()
1836 * xdr_buf_trim - lop at most "len" bytes off the end of "buf"
1850 if (buf->tail[0].iov_len) { in xdr_buf_trim()
1851 cur = min_t(size_t, buf->tail[0].iov_len, trim); in xdr_buf_trim()
1852 buf->tail[0].iov_len -= cur; in xdr_buf_trim()
1853 trim -= cur; in xdr_buf_trim()
1858 if (buf->page_len) { in xdr_buf_trim()
1859 cur = min_t(unsigned int, buf->page_len, trim); in xdr_buf_trim()
1860 buf->page_len -= cur; in xdr_buf_trim()
1861 trim -= cur; in xdr_buf_trim()
1866 if (buf->head[0].iov_len) { in xdr_buf_trim()
1867 cur = min_t(size_t, buf->head[0].iov_len, trim); in xdr_buf_trim()
1868 buf->head[0].iov_len -= cur; in xdr_buf_trim()
1869 trim -= cur; in xdr_buf_trim()
1872 buf->len -= (len - trim); in xdr_buf_trim()
1881 this_len = min_t(unsigned int, len, subbuf->head[0].iov_len); in __read_bytes_from_xdr_buf()
1882 memcpy(obj, subbuf->head[0].iov_base, this_len); in __read_bytes_from_xdr_buf()
1883 len -= this_len; in __read_bytes_from_xdr_buf()
1885 this_len = min_t(unsigned int, len, subbuf->page_len); in __read_bytes_from_xdr_buf()
1886 _copy_from_pages(obj, subbuf->pages, subbuf->page_base, this_len); in __read_bytes_from_xdr_buf()
1887 len -= this_len; in __read_bytes_from_xdr_buf()
1889 this_len = min_t(unsigned int, len, subbuf->tail[0].iov_len); in __read_bytes_from_xdr_buf()
1890 memcpy(obj, subbuf->tail[0].iov_base, this_len); in __read_bytes_from_xdr_buf()
1913 this_len = min_t(unsigned int, len, subbuf->head[0].iov_len); in __write_bytes_to_xdr_buf()
1914 memcpy(subbuf->head[0].iov_base, obj, this_len); in __write_bytes_to_xdr_buf()
1915 len -= this_len; in __write_bytes_to_xdr_buf()
1917 this_len = min_t(unsigned int, len, subbuf->page_len); in __write_bytes_to_xdr_buf()
1918 _copy_to_pages(subbuf->pages, subbuf->page_base, obj, this_len); in __write_bytes_to_xdr_buf()
1919 len -= this_len; in __write_bytes_to_xdr_buf()
1921 this_len = min_t(unsigned int, len, subbuf->tail[0].iov_len); in __write_bytes_to_xdr_buf()
1922 memcpy(subbuf->tail[0].iov_base, obj, this_len); in __write_bytes_to_xdr_buf()
1971 if (xdr_encode_word(buf, base, desc->array_len) != 0) in xdr_xcode_array2()
1972 return -EINVAL; in xdr_xcode_array2()
1974 if (xdr_decode_word(buf, base, &desc->array_len) != 0 || in xdr_xcode_array2()
1975 desc->array_len > desc->array_maxlen || in xdr_xcode_array2()
1976 (unsigned long) base + 4 + desc->array_len * in xdr_xcode_array2()
1977 desc->elem_size > buf->len) in xdr_xcode_array2()
1978 return -EINVAL; in xdr_xcode_array2()
1982 if (!desc->xcode) in xdr_xcode_array2()
1985 todo = desc->array_len * desc->elem_size; in xdr_xcode_array2()
1988 if (todo && base < buf->head->iov_len) { in xdr_xcode_array2()
1989 c = buf->head->iov_base + base; in xdr_xcode_array2()
1991 buf->head->iov_len - base); in xdr_xcode_array2()
1992 todo -= avail_here; in xdr_xcode_array2()
1994 while (avail_here >= desc->elem_size) { in xdr_xcode_array2()
1995 err = desc->xcode(desc, c); in xdr_xcode_array2()
1998 c += desc->elem_size; in xdr_xcode_array2()
1999 avail_here -= desc->elem_size; in xdr_xcode_array2()
2003 elem = kmalloc(desc->elem_size, GFP_KERNEL); in xdr_xcode_array2()
2004 err = -ENOMEM; in xdr_xcode_array2()
2009 err = desc->xcode(desc, elem); in xdr_xcode_array2()
2017 base = buf->head->iov_len; /* align to start of pages */ in xdr_xcode_array2()
2021 base -= buf->head->iov_len; in xdr_xcode_array2()
2022 if (todo && base < buf->page_len) { in xdr_xcode_array2()
2025 avail_here = min(todo, buf->page_len - base); in xdr_xcode_array2()
2026 todo -= avail_here; in xdr_xcode_array2()
2028 base += buf->page_base; in xdr_xcode_array2()
2029 ppages = buf->pages + (base >> PAGE_SHIFT); in xdr_xcode_array2()
2031 avail_page = min_t(unsigned int, PAGE_SIZE - base, in xdr_xcode_array2()
2036 avail_here -= avail_page; in xdr_xcode_array2()
2037 if (copied || avail_page < desc->elem_size) { in xdr_xcode_array2()
2039 desc->elem_size - copied); in xdr_xcode_array2()
2041 elem = kmalloc(desc->elem_size, in xdr_xcode_array2()
2043 err = -ENOMEM; in xdr_xcode_array2()
2049 err = desc->xcode(desc, elem); in xdr_xcode_array2()
2055 if (copied == desc->elem_size) in xdr_xcode_array2()
2060 if (copied == desc->elem_size) { in xdr_xcode_array2()
2061 err = desc->xcode(desc, elem); in xdr_xcode_array2()
2067 avail_page -= l; in xdr_xcode_array2()
2070 while (avail_page >= desc->elem_size) { in xdr_xcode_array2()
2071 err = desc->xcode(desc, c); in xdr_xcode_array2()
2074 c += desc->elem_size; in xdr_xcode_array2()
2075 avail_page -= desc->elem_size; in xdr_xcode_array2()
2079 desc->elem_size - copied); in xdr_xcode_array2()
2081 elem = kmalloc(desc->elem_size, in xdr_xcode_array2()
2083 err = -ENOMEM; in xdr_xcode_array2()
2089 err = desc->xcode(desc, elem); in xdr_xcode_array2()
2095 if (copied == desc->elem_size) in xdr_xcode_array2()
2100 if (copied == desc->elem_size) { in xdr_xcode_array2()
2101 err = desc->xcode(desc, elem); in xdr_xcode_array2()
2117 base = buf->page_len; /* align to start of tail */ in xdr_xcode_array2()
2121 base -= buf->page_len; in xdr_xcode_array2()
2123 c = buf->tail->iov_base + base; in xdr_xcode_array2()
2125 unsigned int l = desc->elem_size - copied; in xdr_xcode_array2()
2131 err = desc->xcode(desc, elem); in xdr_xcode_array2()
2135 todo -= l; in xdr_xcode_array2()
2139 err = desc->xcode(desc, c); in xdr_xcode_array2()
2142 c += desc->elem_size; in xdr_xcode_array2()
2143 todo -= desc->elem_size; in xdr_xcode_array2()
2158 if (base >= buf->len) in xdr_decode_array2()
2159 return -EINVAL; in xdr_decode_array2()
2168 if ((unsigned long) base + 4 + desc->array_len * desc->elem_size > in xdr_encode_array2()
2169 buf->head->iov_len + buf->page_len + buf->tail->iov_len) in xdr_encode_array2()
2170 return -EINVAL; in xdr_encode_array2()
2178 int (*actor)(struct scatterlist *, void *), void *data) in xdr_process_buf() argument
2186 if (offset >= buf->head[0].iov_len) { in xdr_process_buf()
2187 offset -= buf->head[0].iov_len; in xdr_process_buf()
2189 thislen = buf->head[0].iov_len - offset; in xdr_process_buf()
2192 sg_set_buf(sg, buf->head[0].iov_base + offset, thislen); in xdr_process_buf()
2193 ret = actor(sg, data); in xdr_process_buf()
2197 len -= thislen; in xdr_process_buf()
2202 if (offset >= buf->page_len) { in xdr_process_buf()
2203 offset -= buf->page_len; in xdr_process_buf()
2205 page_len = buf->page_len - offset; in xdr_process_buf()
2208 len -= page_len; in xdr_process_buf()
2209 page_offset = (offset + buf->page_base) & (PAGE_SIZE - 1); in xdr_process_buf()
2210 i = (offset + buf->page_base) >> PAGE_SHIFT; in xdr_process_buf()
2211 thislen = PAGE_SIZE - page_offset; in xdr_process_buf()
2215 sg_set_page(sg, buf->pages[i], thislen, page_offset); in xdr_process_buf()
2216 ret = actor(sg, data); in xdr_process_buf()
2219 page_len -= thislen; in xdr_process_buf()
2228 if (offset < buf->tail[0].iov_len) { in xdr_process_buf()
2229 thislen = buf->tail[0].iov_len - offset; in xdr_process_buf()
2232 sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen); in xdr_process_buf()
2233 ret = actor(sg, data); in xdr_process_buf()
2234 len -= thislen; in xdr_process_buf()
2237 ret = -EINVAL; in xdr_process_buf()
2244 * xdr_stream_decode_opaque - Decode variable length opaque
2246 * @ptr: location to store opaque data
2251 * %-EBADMSG on XDR buffer overflow
2252 * %-EMSGSIZE on overflow of storage buffer @ptr
2268 * xdr_stream_decode_opaque_dup - Decode and duplicate variable length opaque
2270 * @ptr: location to store pointer to opaque data
2276 * %-EBADMSG on XDR buffer overflow
2277 * %-EMSGSIZE if the size of the object would exceed @maxlen
2278 * %-ENOMEM on memory allocation failure
2291 ret = -ENOMEM; in xdr_stream_decode_opaque_dup()
2299 * xdr_stream_decode_string - Decode variable length string
2305 * On success, returns length of NUL-terminated string stored in *@str
2306 * %-EBADMSG on XDR buffer overflow
2307 * %-EMSGSIZE on overflow of storage buffer @str
2326 * xdr_stream_decode_string_dup - Decode and duplicate variable length string
2333 * On success, returns length of NUL-terminated string stored in *@ptr
2334 * %-EBADMSG on XDR buffer overflow
2335 * %-EMSGSIZE if the size of the string would exceed @maxlen
2336 * %-ENOMEM on memory allocation failure
2351 ret = -ENOMEM; in xdr_stream_decode_string_dup()
2359 * xdr_stream_decode_opaque_auth - Decode struct opaque_auth (RFC5531 S8.2)
2367 * %-EBADMSG on XDR buffer overflow
2368 * %-EMSGSIZE if the decoded size of the body field exceeds 400 octets
2387 * xdr_stream_encode_opaque_auth - Encode struct opaque_auth (RFC5531 S8.2)
2395 * %-EBADMSG on XDR buffer overflow
2396 * %-EMSGSIZE if the size of @body exceeds 400 octets
2404 return -EMSGSIZE; in xdr_stream_encode_opaque_auth()