diff options
Diffstat (limited to 'net/sunrpc/xdr.c')
-rw-r--r-- | net/sunrpc/xdr.c | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index a1f82a87d34d..cd9e841e7492 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -111,6 +111,23 @@ xdr_decode_string_inplace(__be32 *p, char **sp, | |||
111 | } | 111 | } |
112 | EXPORT_SYMBOL_GPL(xdr_decode_string_inplace); | 112 | EXPORT_SYMBOL_GPL(xdr_decode_string_inplace); |
113 | 113 | ||
114 | /** | ||
115 | * xdr_terminate_string - '\0'-terminate a string residing in an xdr_buf | ||
116 | * @buf: XDR buffer where string resides | ||
117 | * @len: length of string, in bytes | ||
118 | * | ||
119 | */ | ||
120 | void | ||
121 | xdr_terminate_string(struct xdr_buf *buf, const u32 len) | ||
122 | { | ||
123 | char *kaddr; | ||
124 | |||
125 | kaddr = kmap_atomic(buf->pages[0], KM_USER0); | ||
126 | kaddr[buf->page_base + len] = '\0'; | ||
127 | kunmap_atomic(kaddr, KM_USER0); | ||
128 | } | ||
129 | EXPORT_SYMBOL(xdr_terminate_string); | ||
130 | |||
114 | void | 131 | void |
115 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, | 132 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, |
116 | unsigned int len) | 133 | unsigned int len) |
@@ -395,24 +412,29 @@ xdr_shrink_pagelen(struct xdr_buf *buf, size_t len) | |||
395 | { | 412 | { |
396 | struct kvec *tail; | 413 | struct kvec *tail; |
397 | size_t copy; | 414 | size_t copy; |
398 | char *p; | ||
399 | unsigned int pglen = buf->page_len; | 415 | unsigned int pglen = buf->page_len; |
416 | unsigned int tailbuf_len; | ||
400 | 417 | ||
401 | tail = buf->tail; | 418 | tail = buf->tail; |
402 | BUG_ON (len > pglen); | 419 | BUG_ON (len > pglen); |
403 | 420 | ||
421 | tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len; | ||
422 | |||
404 | /* Shift the tail first */ | 423 | /* Shift the tail first */ |
405 | if (tail->iov_len != 0) { | 424 | if (tailbuf_len != 0) { |
406 | p = (char *)tail->iov_base + len; | 425 | unsigned int free_space = tailbuf_len - tail->iov_len; |
426 | |||
427 | if (len < free_space) | ||
428 | free_space = len; | ||
429 | tail->iov_len += free_space; | ||
430 | |||
431 | copy = len; | ||
407 | if (tail->iov_len > len) { | 432 | if (tail->iov_len > len) { |
408 | copy = tail->iov_len - len; | 433 | char *p = (char *)tail->iov_base + len; |
409 | memmove(p, tail->iov_base, copy); | 434 | memmove(p, tail->iov_base, tail->iov_len - len); |
410 | } else | 435 | } else |
411 | buf->buflen -= len; | ||
412 | /* Copy from the inlined pages into the tail */ | ||
413 | copy = len; | ||
414 | if (copy > tail->iov_len) | ||
415 | copy = tail->iov_len; | 436 | copy = tail->iov_len; |
437 | /* Copy from the inlined pages into the tail */ | ||
416 | _copy_from_pages((char *)tail->iov_base, | 438 | _copy_from_pages((char *)tail->iov_base, |
417 | buf->pages, buf->page_base + pglen - len, | 439 | buf->pages, buf->page_base + pglen - len, |
418 | copy); | 440 | copy); |
@@ -551,6 +573,27 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) | |||
551 | EXPORT_SYMBOL_GPL(xdr_init_decode); | 573 | EXPORT_SYMBOL_GPL(xdr_init_decode); |
552 | 574 | ||
553 | /** | 575 | /** |
576 | * xdr_inline_peek - Allow read-ahead in the XDR data stream | ||
577 | * @xdr: pointer to xdr_stream struct | ||
578 | * @nbytes: number of bytes of data to decode | ||
579 | * | ||
580 | * Check if the input buffer is long enough to enable us to decode | ||
581 | * 'nbytes' more bytes of data starting at the current position. | ||
582 | * If so return the current pointer without updating the current | ||
583 | * pointer position. | ||
584 | */ | ||
585 | __be32 * xdr_inline_peek(struct xdr_stream *xdr, size_t nbytes) | ||
586 | { | ||
587 | __be32 *p = xdr->p; | ||
588 | __be32 *q = p + XDR_QUADLEN(nbytes); | ||
589 | |||
590 | if (unlikely(q > xdr->end || q < p)) | ||
591 | return NULL; | ||
592 | return p; | ||
593 | } | ||
594 | EXPORT_SYMBOL_GPL(xdr_inline_peek); | ||
595 | |||
596 | /** | ||
554 | * xdr_inline_decode - Retrieve non-page XDR data to decode | 597 | * xdr_inline_decode - Retrieve non-page XDR data to decode |
555 | * @xdr: pointer to xdr_stream struct | 598 | * @xdr: pointer to xdr_stream struct |
556 | * @nbytes: number of bytes of data to decode | 599 | * @nbytes: number of bytes of data to decode |