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: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
06216ecbd9
commit
43f0f0816c
@ -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? */
|
||||
|
Loading…
Reference in New Issue
Block a user