Commit 43f0f081 authored by Anna Schumaker's avatar Anna Schumaker

SUNRPC: Split out _shift_data_right_tail()

xdr_shrink_pagelen() is very similar to what we need for hole expansion,
so split out the common code into its own function that can be used by
both functions.
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 06216ecb
......@@ -266,6 +266,46 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base,
} while ((len -= copy) != 0);
}
static unsigned int
_shift_data_right_tail(struct xdr_buf *buf, unsigned int pgfrom, size_t len)
{
struct kvec *tail = buf->tail;
unsigned int tailbuf_len;
unsigned int result = 0;
size_t copy;
tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len;
/* Shift the tail first */
if (tailbuf_len != 0) {
unsigned int free_space = tailbuf_len - tail->iov_len;
if (len < free_space)
free_space = len;
if (len > free_space)
len = free_space;
tail->iov_len += free_space;
copy = len;
if (tail->iov_len > len) {
char *p = (char *)tail->iov_base + len;
memmove(p, tail->iov_base, tail->iov_len - free_space);
result += tail->iov_len - free_space;
} else
copy = tail->iov_len;
/* Copy from the inlined pages into the tail */
_copy_from_pages((char *)tail->iov_base,
buf->pages,
buf->page_base + pgfrom,
copy);
result += copy;
}
return result;
}
/**
* _copy_to_pages
* @pages: array of pages
......@@ -446,39 +486,13 @@ xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
static unsigned int
xdr_shrink_pagelen(struct xdr_buf *buf, size_t len)
{
struct kvec *tail;
size_t copy;
unsigned int pglen = buf->page_len;
unsigned int tailbuf_len;
unsigned int result;
result = 0;
tail = buf->tail;
if (len > buf->page_len)
len = buf-> page_len;
tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len;
/* Shift the tail first */
if (tailbuf_len != 0) {
unsigned int free_space = tailbuf_len - tail->iov_len;
if (len < free_space)
free_space = len;
tail->iov_len += free_space;
copy = len;
if (tail->iov_len > len) {
char *p = (char *)tail->iov_base + len;
memmove(p, tail->iov_base, tail->iov_len - len);
result += tail->iov_len - len;
} else
copy = tail->iov_len;
/* Copy from the inlined pages into the tail */
_copy_from_pages((char *)tail->iov_base,
buf->pages, buf->page_base + pglen - len,
copy);
result += copy;
}
result = _shift_data_right_tail(buf, pglen - len, len);
buf->page_len -= len;
buf->buflen -= len;
/* Have we truncated the message? */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment