Lines Matching refs:xdr

3  * linux/net/sunrpc/xdr.c
17 #include <linux/sunrpc/xdr.h>
171 * @xdr: xdr_buf to be copied
176 const struct xdr_buf *xdr)
178 const struct kvec *head = xdr->head;
179 const struct kvec *tail = xdr->tail;
187 if (xdr->page_len) {
189 struct page **pages = xdr->pages;
191 offset = offset_in_page(xdr->page_base);
192 remaining = xdr->page_len;
219 * @xdr: xdr_buf into which reply will be placed
227 xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
230 struct kvec *head = xdr->head;
231 struct kvec *tail = xdr->tail;
237 xdr->pages = pages;
238 xdr->page_base = base;
239 xdr->page_len = len;
243 xdr->buflen += len;
917 * @xdr: pointer to struct xdr_stream
919 unsigned int xdr_stream_pos(const struct xdr_stream *xdr)
921 return (unsigned int)(XDR_QUADLEN(xdr->buf->len) - xdr->nwords) << 2;
925 static void xdr_stream_set_pos(struct xdr_stream *xdr, unsigned int pos)
927 unsigned int blen = xdr->buf->len;
929 xdr->nwords = blen > pos ? XDR_QUADLEN(blen) - XDR_QUADLEN(pos) : 0;
932 static void xdr_stream_page_set_pos(struct xdr_stream *xdr, unsigned int pos)
934 xdr_stream_set_pos(xdr, pos + xdr->buf->head[0].iov_len);
938 * xdr_page_pos - Return the current offset from the start of the xdr pages
939 * @xdr: pointer to struct xdr_stream
941 unsigned int xdr_page_pos(const struct xdr_stream *xdr)
943 unsigned int pos = xdr_stream_pos(xdr);
945 WARN_ON(pos < xdr->buf->head[0].iov_len);
946 return pos - xdr->buf->head[0].iov_len;
952 * @xdr: pointer to xdr_stream struct
964 void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
970 xdr_reset_scratch_buffer(xdr);
972 xdr->buf = buf;
973 xdr->iov = iov;
974 xdr->p = (__be32 *)((char *)iov->iov_base + iov->iov_len);
975 xdr->end = (__be32 *)((char *)iov->iov_base + scratch_len);
978 if (p != xdr->p && p != NULL) {
981 BUG_ON(p < xdr->p || p > xdr->end);
982 len = (char *)p - (char *)xdr->p;
983 xdr->p = p;
987 xdr->rqst = rqst;
993 * @xdr: pointer to xdr_stream struct
999 void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf,
1002 xdr_reset_scratch_buffer(xdr);
1004 xdr->buf = buf;
1005 xdr->page_ptr = pages;
1006 xdr->iov = NULL;
1007 xdr->p = page_address(*pages);
1008 xdr->end = (void *)xdr->p + min_t(u32, buf->buflen, PAGE_SIZE);
1009 xdr->rqst = rqst;
1015 * @xdr: pointer to xdr_stream
1026 void __xdr_commit_encode(struct xdr_stream *xdr)
1028 size_t shift = xdr->scratch.iov_len;
1031 page = page_address(*xdr->page_ptr);
1032 memcpy(xdr->scratch.iov_base, page, shift);
1033 memmove(page, page + shift, (void *)xdr->p - page);
1034 xdr_reset_scratch_buffer(xdr);
1040 * xdr->buf->head and xdr->buf->pages, or between two pages
1041 * in xdr->buf->pages.
1043 static noinline __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
1052 if (xdr->buf->len + nbytes > xdr->buf->buflen)
1054 frag1bytes = (xdr->end - xdr->p) << 2;
1056 if (xdr->iov)
1057 xdr->iov->iov_len += frag1bytes;
1059 xdr->buf->page_len += frag1bytes;
1060 xdr->page_ptr++;
1061 xdr->iov = NULL;
1070 xdr_set_scratch_buffer(xdr, xdr->p, frag1bytes);
1073 * xdr->p is where the next encode will start after
1076 p = page_address(*xdr->page_ptr);
1077 xdr->p = p + frag2bytes;
1078 space_left = xdr->buf->buflen - xdr->buf->len;
1080 xdr->end = p + PAGE_SIZE;
1082 xdr->end = p + space_left - frag1bytes;
1084 xdr->buf->page_len += frag2bytes;
1085 xdr->buf->len += nbytes;
1088 trace_rpc_xdr_overflow(xdr, nbytes);
1094 * @xdr: pointer to xdr_stream
1101 __be32 * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
1103 __be32 *p = xdr->p;
1106 xdr_commit_encode(xdr);
1111 if (unlikely(q > xdr->end || q < p))
1112 return xdr_get_next_encode_buffer(xdr, nbytes);
1113 xdr->p = q;
1114 if (xdr->iov)
1115 xdr->iov->iov_len += nbytes;
1117 xdr->buf->page_len += nbytes;
1118 xdr->buf->len += nbytes;
1125 * @xdr: pointer to xdr_stream
1134 * %-EMSGSIZE: not enough space is available in @xdr
1136 int xdr_reserve_space_vec(struct xdr_stream *xdr, size_t nbytes)
1143 * in xdr->pages.
1145 if (xdr->iov == xdr->buf->head) {
1146 xdr->iov = NULL;
1147 xdr->end = xdr->p;
1152 thislen = xdr->buf->page_len % PAGE_SIZE;
1155 p = xdr_reserve_space(xdr, thislen);
1168 * @xdr: pointer to xdr_stream
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
1185 void xdr_truncate_encode(struct xdr_stream *xdr, size_t len)
1187 struct xdr_buf *buf = xdr->buf;
1197 xdr_commit_encode(xdr);
1203 xdr->p = tail->iov_base + tail->iov_len;
1204 WARN_ON_ONCE(!xdr->end);
1205 WARN_ON_ONCE(!xdr->iov);
1215 xdr->page_ptr = buf->pages + (new >> PAGE_SHIFT);
1218 xdr->p = page_address(*xdr->page_ptr);
1219 xdr->end = (void *)xdr->p + PAGE_SIZE;
1220 xdr->p = (void *)xdr->p + (new % PAGE_SIZE);
1221 WARN_ON_ONCE(xdr->iov);
1225 xdr->end = head->iov_base + head->iov_len;
1226 /* (otherwise assume xdr->end is already set) */
1227 xdr->page_ptr--;
1230 xdr->p = head->iov_base + head->iov_len;
1231 xdr->iov = buf->head;
1237 * @xdr: pointer to struct xdr_stream
1241 void xdr_truncate_decode(struct xdr_stream *xdr, size_t len)
1245 xdr->buf->len -= nbytes;
1246 xdr->nwords -= XDR_QUADLEN(nbytes);
1252 * @xdr: pointer to xdr_stream
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
1262 int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen)
1264 struct xdr_buf *buf = xdr->buf;
1265 int left_in_this_buf = (void *)xdr->end - (void *)xdr->p;
1273 xdr->end = (void *)xdr->end + newbuflen - end_offset;
1281 * @xdr: pointer to xdr_stream
1290 void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int base,
1293 struct xdr_buf *buf = xdr->buf;
1300 tail->iov_base = xdr->p;
1302 xdr->iov = tail;
1307 BUG_ON(xdr->p >= xdr->end);
1308 tail->iov_base = (char *)xdr->p + (len & 3);
1311 *xdr->p++ = 0;
1318 static unsigned int xdr_set_iov(struct xdr_stream *xdr, struct kvec *iov,
1325 xdr->p = (__be32*)(iov->iov_base + base);
1326 xdr->end = (__be32*)(iov->iov_base + len);
1327 xdr->iov = iov;
1328 xdr->page_ptr = NULL;
1332 static unsigned int xdr_set_tail_base(struct xdr_stream *xdr,
1335 struct xdr_buf *buf = xdr->buf;
1337 xdr_stream_set_pos(xdr, base + buf->page_len + buf->head->iov_len);
1338 return xdr_set_iov(xdr, buf->tail, base, len);
1341 static void xdr_stream_unmap_current_page(struct xdr_stream *xdr)
1343 if (xdr->page_kaddr) {
1344 kunmap_local(xdr->page_kaddr);
1345 xdr->page_kaddr = NULL;
1349 static unsigned int xdr_set_page_base(struct xdr_stream *xdr,
1358 maxlen = xdr->buf->page_len;
1366 xdr_stream_unmap_current_page(xdr);
1367 xdr_stream_page_set_pos(xdr, base);
1368 base += xdr->buf->page_base;
1371 xdr->page_ptr = &xdr->buf->pages[pgnr];
1373 if (PageHighMem(*xdr->page_ptr)) {
1374 xdr->page_kaddr = kmap_local_page(*xdr->page_ptr);
1375 kaddr = xdr->page_kaddr;
1377 kaddr = page_address(*xdr->page_ptr);
1380 xdr->p = (__be32*)(kaddr + pgoff);
1385 xdr->end = (__be32*)(kaddr + pgend);
1386 xdr->iov = NULL;
1390 static void xdr_set_page(struct xdr_stream *xdr, unsigned int base,
1393 if (xdr_set_page_base(xdr, base, len) == 0) {
1394 base -= xdr->buf->page_len;
1395 xdr_set_tail_base(xdr, base, len);
1399 static void xdr_set_next_page(struct xdr_stream *xdr)
1403 newbase = (1 + xdr->page_ptr - xdr->buf->pages) << PAGE_SHIFT;
1404 newbase -= xdr->buf->page_base;
1405 if (newbase < xdr->buf->page_len)
1406 xdr_set_page_base(xdr, newbase, xdr_stream_remaining(xdr));
1408 xdr_set_tail_base(xdr, 0, xdr_stream_remaining(xdr));
1411 static bool xdr_set_next_buffer(struct xdr_stream *xdr)
1413 if (xdr->page_ptr != NULL)
1414 xdr_set_next_page(xdr);
1415 else if (xdr->iov == xdr->buf->head)
1416 xdr_set_page(xdr, 0, xdr_stream_remaining(xdr));
1417 return xdr->p != xdr->end;
1422 * @xdr: pointer to xdr_stream struct
1427 void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
1430 xdr->buf = buf;
1431 xdr->page_kaddr = NULL;
1432 xdr_reset_scratch_buffer(xdr);
1433 xdr->nwords = XDR_QUADLEN(buf->len);
1434 if (xdr_set_iov(xdr, buf->head, 0, buf->len) == 0 &&
1435 xdr_set_page_base(xdr, 0, buf->len) == 0)
1436 xdr_set_iov(xdr, buf->tail, 0, buf->len);
1437 if (p != NULL && p > xdr->p && xdr->end >= p) {
1438 xdr->nwords -= p - xdr->p;
1439 xdr->p = p;
1441 xdr->rqst = rqst;
1447 * @xdr: pointer to xdr_stream struct
1452 void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf,
1460 xdr_init_decode(xdr, buf, NULL, NULL);
1466 * @xdr: pointer to xdr_stream struct
1468 void xdr_finish_decode(struct xdr_stream *xdr)
1470 xdr_stream_unmap_current_page(xdr);
1474 static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
1477 __be32 *p = xdr->p;
1480 if (unlikely(nwords > xdr->nwords || q > xdr->end || q < p))
1482 xdr->p = q;
1483 xdr->nwords -= nwords;
1487 static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes)
1490 char *cpdest = xdr->scratch.iov_base;
1491 size_t cplen = (char *)xdr->end - (char *)xdr->p;
1493 if (nbytes > xdr->scratch.iov_len)
1495 p = __xdr_inline_decode(xdr, cplen);
1499 if (!xdr_set_next_buffer(xdr))
1503 p = __xdr_inline_decode(xdr, nbytes);
1507 return xdr->scratch.iov_base;
1509 trace_rpc_xdr_overflow(xdr, nbytes);
1515 * @xdr: pointer to xdr_stream struct
1523 __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
1528 return xdr->p;
1529 if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr))
1531 p = __xdr_inline_decode(xdr, nbytes);
1534 return xdr_copy_to_scratch(xdr, nbytes);
1536 trace_rpc_xdr_overflow(xdr, nbytes);
1541 static void xdr_realign_pages(struct xdr_stream *xdr)
1543 struct xdr_buf *buf = xdr->buf;
1545 unsigned int cur = xdr_stream_pos(xdr);
1551 trace_rpc_xdr_alignment(xdr, cur, copied);
1552 xdr_set_page(xdr, 0, buf->page_len);
1556 static unsigned int xdr_align_pages(struct xdr_stream *xdr, unsigned int len)
1558 struct xdr_buf *buf = xdr->buf;
1562 if (xdr->nwords == 0)
1565 xdr_realign_pages(xdr);
1566 if (nwords > xdr->nwords) {
1567 nwords = xdr->nwords;
1572 else if (nwords < xdr->nwords) {
1575 trace_rpc_xdr_alignment(xdr, len, copied);
1582 * @xdr: pointer to xdr_stream struct
1592 unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len)
1597 pglen = xdr_align_pages(xdr, nwords << 2);
1602 end = xdr_stream_remaining(xdr) - pglen;
1604 xdr_set_tail_base(xdr, base, end);
1611 * @xdr: pointer to xdr_stream struct
1614 * Either grows or shrinks the length of the xdr pages by setting pagelen to
1620 void xdr_set_pagelen(struct xdr_stream *xdr, unsigned int len)
1622 struct xdr_buf *buf = xdr->buf;
1623 size_t remaining = xdr_stream_remaining(xdr);
1630 xdr_buf_head_shift_right(buf, xdr_stream_pos(xdr),
1635 xdr_set_tail_base(xdr, base, remaining);
1641 * @xdr: pointer to xdr_stream struct
1649 void xdr_enter_page(struct xdr_stream *xdr, unsigned int len)
1651 len = xdr_align_pages(xdr, len);
1657 xdr_set_page_base(xdr, 0, len);
1674 * @buf: an xdr buffer
1679 * sets @subbuf to an xdr buffer representing the portion of @buf of
1735 * xdr_stream_subsegment - set @subbuf to a portion of @xdr
1736 * @xdr: an xdr_stream set up for decoding
1738 * @nbytes: length of @xdr to extract, in bytes
1740 * Sets up @subbuf to represent a portion of @xdr. The portion
1741 * starts at the current offset in @xdr, and extends for a length
1742 * of @nbytes. If this is successful, @xdr is advanced to the next
1746 * %true: @subbuf has been initialized, and @xdr has been advanced.
1749 bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf,
1752 unsigned int start = xdr_stream_pos(xdr);
1756 if (xdr_buf_subsegment(xdr->buf, subbuf, start, nbytes))
1759 /* Advance @xdr by @nbytes */
1761 if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr))
1764 len = (char *)xdr->end - (char *)xdr->p;
1766 xdr->p = (__be32 *)((char *)xdr->p +
1771 xdr->p = (__be32 *)((char *)xdr->p + len);
1772 xdr->end = xdr->p;
1776 xdr_stream_set_pos(xdr, start + nbytes);
1783 * @xdr: the source xdr_stream
1791 unsigned int xdr_stream_move_subsegment(struct xdr_stream *xdr, unsigned int offset,
1799 if (xdr_buf_subsegment(xdr->buf, &buf, offset, shift + length) < 0)
1804 if (xdr_buf_subsegment(xdr->buf, &buf, target, shift + length) < 0)
1814 * @xdr: an xdr_stream to zero out
1818 unsigned int xdr_stream_zero(struct xdr_stream *xdr, unsigned int offset,
1823 if (xdr_buf_subsegment(xdr->buf, &buf, offset, length) < 0)
2245 * @xdr: pointer to xdr_stream
2254 ssize_t xdr_stream_decode_opaque(struct xdr_stream *xdr, void *ptr, size_t size)
2259 ret = xdr_stream_decode_opaque_inline(xdr, &p, size);
2269 * @xdr: pointer to xdr_stream
2280 ssize_t xdr_stream_decode_opaque_dup(struct xdr_stream *xdr, void **ptr,
2286 ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
2300 * @xdr: pointer to xdr_stream
2309 ssize_t xdr_stream_decode_string(struct xdr_stream *xdr, char *str, size_t size)
2314 ret = xdr_stream_decode_opaque_inline(xdr, &p, size);
2327 * @xdr: pointer to xdr_stream
2338 ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
2344 ret = xdr_stream_decode_opaque_inline(xdr, &p, maxlen);
2360 * @xdr: pointer to xdr_stream
2370 ssize_t xdr_stream_decode_opaque_auth(struct xdr_stream *xdr, u32 *flavor,
2375 len = xdr_stream_decode_u32(xdr, flavor);
2378 ret = xdr_stream_decode_opaque_inline(xdr, body, RPC_MAX_AUTH_SIZE);
2388 * @xdr: pointer to xdr_stream
2398 ssize_t xdr_stream_encode_opaque_auth(struct xdr_stream *xdr, u32 flavor,
2405 len = xdr_stream_encode_u32(xdr, flavor);
2408 ret = xdr_stream_encode_opaque(xdr, body, body_len);