9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/types.h>
12 #include <linux/string.h>
13 #include <linux/kernel.h>
15 #include <linux/errno.h>
25 unsigned int quadlen = XDR_QUADLEN(obj->len);
29 memcpy(p, obj->data, obj->len);
30 return p + XDR_QUADLEN(obj->len);
43 return p + XDR_QUADLEN(len);
64 unsigned int quadlen = XDR_QUADLEN(nbytes);
65 unsigned int padding = (quadlen << 2) - nbytes;
70 memset((
char *)p + nbytes, 0, padding);
95 return xdr_encode_array(p,
string,
strlen(
string));
101 unsigned int *lenp,
unsigned int maxlen)
110 return p + XDR_QUADLEN(len);
126 kaddr[buf->page_base +
len] =
'\0';
133 struct page **
pages,
unsigned int base,
unsigned int len)
143 xdr->page_base = base;
172 _shift_data_right_pages(
struct page **
pages,
size_t pgto_base,
173 size_t pgfrom_base,
size_t len)
175 struct page **pgfrom, **pgto;
179 BUG_ON(pgto_base <= pgfrom_base);
192 if (pgto_base == 0) {
196 if (pgfrom_base == 0) {
202 if (copy > pgto_base)
204 if (copy > pgfrom_base)
211 memmove(vto + pgto_base, vfrom + pgfrom_base, copy);
216 }
while ((len -= copy) != 0);
230 _copy_to_pages(
struct page **pages,
size_t pgbase,
const char *
p,
size_t len)
245 memcpy(vto + pgbase, p, copy);
276 struct page **pgfrom;
289 memcpy(p, vfrom + pgbase, copy);
299 }
while ((len -= copy) != 0);
313 xdr_shrink_bufhead(
struct xdr_buf *
buf,
size_t len)
317 unsigned int pglen = buf->page_len;
337 else if (copy > tail->
iov_len - offs)
342 buf->page_base + pglen + offs - len,
346 offs = copy = len - pglen;
358 _shift_data_right_pages(buf->pages,
359 buf->page_base + len,
365 _copy_to_pages(buf->pages, buf->page_base,
372 if (buf->len > buf->buflen)
373 buf->len = buf->buflen;
386 xdr_shrink_pagelen(
struct xdr_buf *buf,
size_t len)
390 unsigned int pglen = buf->page_len;
391 unsigned int tailbuf_len;
396 tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len;
399 if (tailbuf_len != 0) {
400 unsigned int free_space = tailbuf_len - tail->
iov_len;
402 if (len < free_space)
408 char *p = (
char *)tail->
iov_base + len;
414 buf->pages, buf->page_base + pglen - len,
417 buf->page_len -= len;
420 if (buf->len > buf->buflen)
421 buf->len = buf->buflen;
427 xdr_shrink_bufhead(buf, len);
437 return (
unsigned int)(XDR_QUADLEN(xdr->buf->len) - xdr->nwords) << 2;
456 struct kvec *iov = buf->head;
457 int scratch_len = buf->buflen - buf->page_len - buf->tail[0].
iov_len;
466 if (p != xdr->p && p !=
NULL) {
469 BUG_ON(p < xdr->p || p > xdr->end);
470 len = (
char *)p - (
char *)xdr->p;
495 q = p + (nbytes >> 2);
496 if (
unlikely(q > xdr->end || q < p))
499 xdr->iov->iov_len +=
nbytes;
516 struct xdr_buf *buf = xdr->buf;
517 struct kvec *iov = buf->tail;
519 buf->page_base = base;
527 unsigned int pad = 4 - (len & 3);
529 BUG_ON(xdr->p >= xdr->end);
530 iov->
iov_base = (
char *)xdr->p + (len & 3);
540 static void xdr_set_iov(
struct xdr_stream *xdr,
struct kvec *iov,
548 xdr->page_ptr =
NULL;
551 static int xdr_set_page_base(
struct xdr_stream *xdr,
552 unsigned int base,
unsigned int len)
560 maxlen = xdr->buf->page_len;
567 base += xdr->buf->page_base;
570 xdr->page_ptr = &xdr->buf->pages[pgnr];
574 xdr->p = (
__be32*)(kaddr + pgoff);
579 xdr->end = (
__be32*)(kaddr + pgend);
584 static void xdr_set_next_page(
struct xdr_stream *xdr)
586 unsigned int newbase;
588 newbase = (1 + xdr->page_ptr - xdr->buf->pages) << PAGE_SHIFT;
589 newbase -= xdr->buf->page_base;
591 if (xdr_set_page_base(xdr, newbase,
PAGE_SIZE) < 0)
592 xdr_set_iov(xdr, xdr->buf->tail, xdr->buf->len);
595 static bool xdr_set_next_buffer(
struct xdr_stream *xdr)
597 if (xdr->page_ptr !=
NULL)
598 xdr_set_next_page(xdr);
599 else if (xdr->iov == xdr->buf->head) {
600 if (xdr_set_page_base(xdr, 0,
PAGE_SIZE) < 0)
601 xdr_set_iov(xdr, xdr->buf->tail, xdr->buf->len);
603 return xdr->p != xdr->end;
615 xdr->scratch.iov_base =
NULL;
616 xdr->scratch.iov_len = 0;
617 xdr->nwords = XDR_QUADLEN(buf->len);
618 if (buf->head[0].iov_len != 0)
619 xdr_set_iov(xdr, buf->head, buf->len);
620 else if (buf->page_len != 0)
621 xdr_set_page_base(xdr, 0, buf->len);
622 if (p !=
NULL && p > xdr->p && xdr->end >= p) {
623 xdr->nwords -= p - xdr->p;
637 struct page **pages,
unsigned int len)
639 memset(buf, 0,
sizeof(*buf));
648 static __be32 * __xdr_inline_decode(
struct xdr_stream *xdr,
size_t nbytes)
650 unsigned int nwords = XDR_QUADLEN(nbytes);
654 if (
unlikely(nwords > xdr->nwords || q > xdr->end || q < p))
657 xdr->nwords -= nwords;
674 xdr->scratch.iov_base =
buf;
675 xdr->scratch.iov_len =
buflen;
679 static __be32 *xdr_copy_to_scratch(
struct xdr_stream *xdr,
size_t nbytes)
682 void *cpdest = xdr->scratch.iov_base;
683 size_t cplen = (
char *)xdr->end - (
char *)xdr->p;
685 if (nbytes > xdr->scratch.iov_len)
687 memcpy(cpdest, xdr->p, cplen);
690 if (!xdr_set_next_buffer(xdr))
692 p = __xdr_inline_decode(xdr, nbytes);
695 memcpy(cpdest, p, nbytes);
696 return xdr->scratch.iov_base;
715 if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr))
717 p = __xdr_inline_decode(xdr, nbytes);
720 return xdr_copy_to_scratch(xdr, nbytes);
724 static unsigned int xdr_align_pages(
struct xdr_stream *xdr,
unsigned int len)
726 struct xdr_buf *buf = xdr->buf;
728 unsigned int nwords = XDR_QUADLEN(len);
731 if (xdr->nwords == 0)
736 xdr_shrink_bufhead(buf, iov->
iov_len - cur);
737 xdr->nwords = XDR_QUADLEN(buf->len - cur);
740 if (nwords > xdr->nwords) {
741 nwords = xdr->nwords;
744 if (buf->page_len <= len)
746 else if (nwords < xdr->nwords) {
748 xdr_shrink_pagelen(buf, buf->page_len - len);
749 xdr->nwords = XDR_QUADLEN(buf->len - cur);
767 struct xdr_buf *buf = xdr->buf;
773 len = xdr_align_pages(xdr, len);
776 nwords = XDR_QUADLEN(len);
777 padding = (nwords << 2) - len;
778 xdr->iov = iov = buf->tail;
780 end = ((xdr->nwords - nwords) << 2) +
padding;
790 xdr->page_ptr =
NULL;
791 xdr->nwords = XDR_QUADLEN(end - padding);
808 len = xdr_align_pages(xdr, len);
814 xdr_set_page_base(xdr, 0, len);
818 static struct kvec empty_iov = {.iov_base =
NULL, .iov_len = 0};
824 buf->tail[0] = empty_iov;
826 buf->buflen = buf->len = iov->
iov_len;
834 unsigned int base,
unsigned int len)
836 subbuf->buflen = subbuf->len = len;
837 if (base < buf->head[0].
iov_len) {
838 subbuf->head[0].iov_base = buf->head[0].iov_base + base;
839 subbuf->head[0].iov_len =
min_t(
unsigned int, len,
840 buf->head[0].iov_len - base);
841 len -= subbuf->head[0].iov_len;
844 subbuf->head[0].iov_base =
NULL;
845 subbuf->head[0].iov_len = 0;
846 base -= buf->head[0].iov_len;
849 if (base < buf->page_len) {
850 subbuf->page_len =
min(buf->page_len - base, len);
851 base += buf->page_base;
854 len -= subbuf->page_len;
857 base -= buf->page_len;
858 subbuf->page_len = 0;
861 if (base < buf->tail[0].iov_len) {
862 subbuf->tail[0].iov_base = buf->tail[0].iov_base + base;
863 subbuf->tail[0].iov_len =
min_t(
unsigned int, len,
864 buf->tail[0].iov_len - base);
865 len -= subbuf->tail[0].iov_len;
868 subbuf->tail[0].iov_base =
NULL;
869 subbuf->tail[0].iov_len = 0;
870 base -= buf->tail[0].iov_len;
879 static void __read_bytes_from_xdr_buf(
struct xdr_buf *subbuf,
void *obj,
unsigned int len)
881 unsigned int this_len;
883 this_len =
min_t(
unsigned int, len, subbuf->head[0].iov_len);
884 memcpy(obj, subbuf->head[0].iov_base, this_len);
887 this_len =
min_t(
unsigned int, len, subbuf->page_len);
892 this_len =
min_t(
unsigned int, len, subbuf->tail[0].iov_len);
893 memcpy(obj, subbuf->tail[0].iov_base, this_len);
899 struct xdr_buf subbuf;
905 __read_bytes_from_xdr_buf(&subbuf, obj, len);
910 static void __write_bytes_to_xdr_buf(
struct xdr_buf *subbuf,
void *obj,
unsigned int len)
912 unsigned int this_len;
914 this_len =
min_t(
unsigned int, len, subbuf->head[0].iov_len);
915 memcpy(subbuf->head[0].iov_base, obj, this_len);
918 this_len =
min_t(
unsigned int, len, subbuf->page_len);
920 _copy_to_pages(subbuf->pages, subbuf->page_base, obj, this_len);
923 this_len =
min_t(
unsigned int, len, subbuf->tail[0].iov_len);
924 memcpy(subbuf->tail[0].iov_base, obj, this_len);
930 struct xdr_buf subbuf;
936 __write_bytes_to_xdr_buf(&subbuf, obj, len);
970 struct xdr_buf subbuf;
978 obj->data = subbuf.head[0].iov_base;
979 if (subbuf.head[0].iov_len == obj->len)
982 obj->data = subbuf.tail[0].iov_base;
983 if (subbuf.tail[0].iov_len == obj->len)
991 if (obj->len > buf->buflen - buf->len)
993 if (buf->tail[0].iov_len != 0)
994 obj->data = buf->tail[0].iov_base + buf->tail[0].iov_len;
996 obj->data = buf->head[0].iov_base + buf->head[0].iov_len;
997 __read_bytes_from_xdr_buf(&subbuf, obj->data, obj->len);
1004 xdr_xcode_array2(
struct xdr_buf *buf,
unsigned int base,
1005 struct xdr_array2_desc *
desc,
int encode)
1008 unsigned int copied = 0,
todo, avail_here;
1017 desc->array_len > desc->array_maxlen ||
1018 (
unsigned long) base + 4 + desc->array_len *
1019 desc->elem_size > buf->len)
1027 todo = desc->array_len * desc->elem_size;
1031 c = buf->head->iov_base + base;
1033 buf->head->iov_len - base);
1036 while (avail_here >= desc->elem_size) {
1037 err = desc->xcode(desc, c);
1040 c += desc->elem_size;
1041 avail_here -= desc->elem_size;
1051 err = desc->xcode(desc, elem);
1054 memcpy(c, elem, avail_here);
1056 memcpy(elem, c, avail_here);
1057 copied = avail_here;
1059 base = buf->head->iov_len;
1063 base -= buf->head->iov_len;
1064 if (
todo && base < buf->page_len) {
1065 unsigned int avail_page;
1067 avail_here =
min(
todo, buf->page_len - base);
1070 base += buf->page_base;
1075 c =
kmap(*ppages) + base;
1077 while (avail_here) {
1078 avail_here -= avail_page;
1079 if (copied || avail_page < desc->elem_size) {
1080 unsigned int l =
min(avail_page,
1081 desc->elem_size - copied);
1083 elem =
kmalloc(desc->elem_size,
1091 err = desc->xcode(desc, elem);
1095 memcpy(c, elem + copied, l);
1097 if (copied == desc->elem_size)
1100 memcpy(elem + copied, c, l);
1102 if (copied == desc->elem_size) {
1103 err = desc->xcode(desc, elem);
1112 while (avail_page >= desc->elem_size) {
1113 err = desc->xcode(desc, c);
1116 c += desc->elem_size;
1117 avail_page -= desc->elem_size;
1120 unsigned int l =
min(avail_page,
1121 desc->elem_size - copied);
1123 elem =
kmalloc(desc->elem_size,
1131 err = desc->xcode(desc, elem);
1135 memcpy(c, elem + copied, l);
1137 if (copied == desc->elem_size)
1140 memcpy(elem + copied, c, l);
1142 if (copied == desc->elem_size) {
1143 err = desc->xcode(desc, elem);
1156 avail_page =
min(avail_here,
1159 base = buf->page_len;
1163 base -= buf->page_len;
1165 c = buf->tail->iov_base + base;
1167 unsigned int l = desc->elem_size - copied;
1170 memcpy(c, elem + copied, l);
1172 memcpy(elem + copied, c, l);
1173 err = desc->xcode(desc, elem);
1181 err = desc->xcode(desc, c);
1184 c += desc->elem_size;
1185 todo -= desc->elem_size;
1199 struct xdr_array2_desc *desc)
1201 if (base >= buf->len)
1204 return xdr_xcode_array2(buf, base, desc, 0);
1210 struct xdr_array2_desc *desc)
1212 if ((
unsigned long) base + 4 + desc->array_len * desc->elem_size >
1213 buf->head->iov_len + buf->page_len + buf->tail->iov_len)
1216 return xdr_xcode_array2(buf, base, desc, 1);
1230 if (offset >= buf->head[0].iov_len) {
1231 offset -= buf->head[0].iov_len;
1233 thislen = buf->head[0].iov_len -
offset;
1236 sg_set_buf(sg, buf->head[0].iov_base + offset, thislen);
1237 ret = actor(sg, data);
1246 if (offset >= buf->page_len) {
1247 offset -= buf->page_len;
1249 page_len = buf->page_len -
offset;
1257 if (thislen > page_len)
1259 sg_set_page(sg, buf->pages[i], thislen, page_offset);
1260 ret = actor(sg, data);
1263 page_len -= thislen;
1267 }
while (page_len != 0);
1273 thislen = buf->tail[0].iov_len -
offset;
1276 sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen);
1277 ret = actor(sg, data);