mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
SUNRPC: Cleanup xdr_shrink_bufhead()
Clean up xdr_shrink_bufhead() to use the new helpers instead of doing its own thing. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
parent
c4f2f591f0
commit
6707fbd7d3
164
net/sunrpc/xdr.c
164
net/sunrpc/xdr.c
@ -550,6 +550,53 @@ static void xdr_buf_pages_copy_right(const struct xdr_buf *buf,
|
||||
buf->page_base + base, pglen);
|
||||
}
|
||||
|
||||
static void xdr_buf_head_copy_right(const struct xdr_buf *buf,
|
||||
unsigned int base, unsigned int len,
|
||||
unsigned int shift)
|
||||
{
|
||||
const struct kvec *head = buf->head;
|
||||
const struct kvec *tail = buf->tail;
|
||||
unsigned int to = base + shift;
|
||||
unsigned int pglen = 0, pgto = 0;
|
||||
unsigned int talen = 0, tato = 0;
|
||||
|
||||
if (base >= head->iov_len)
|
||||
return;
|
||||
if (len > head->iov_len - base)
|
||||
len = head->iov_len - base;
|
||||
if (to >= buf->page_len + head->iov_len) {
|
||||
tato = to - buf->page_len - head->iov_len;
|
||||
talen = len;
|
||||
} else if (to >= head->iov_len) {
|
||||
pgto = to - head->iov_len;
|
||||
pglen = len;
|
||||
if (pgto + pglen > buf->page_len) {
|
||||
talen = pgto + pglen - buf->page_len;
|
||||
pglen -= talen;
|
||||
}
|
||||
} else {
|
||||
pglen = len - to;
|
||||
if (pglen > buf->page_len) {
|
||||
talen = pglen - buf->page_len;
|
||||
pglen = buf->page_len;
|
||||
}
|
||||
}
|
||||
|
||||
len -= talen;
|
||||
base += len;
|
||||
if (talen + tato > tail->iov_len)
|
||||
talen = tail->iov_len > tato ? tail->iov_len - tato : 0;
|
||||
memcpy(tail->iov_base + tato, head->iov_base + base, talen);
|
||||
|
||||
len -= pglen;
|
||||
base -= pglen;
|
||||
_copy_to_pages(buf->pages, buf->page_base + pgto, head->iov_base + base,
|
||||
pglen);
|
||||
|
||||
base -= len;
|
||||
memmove(head->iov_base + to, head->iov_base + base, len);
|
||||
}
|
||||
|
||||
static void xdr_buf_tail_shift_right(const struct xdr_buf *buf,
|
||||
unsigned int base, unsigned int len,
|
||||
unsigned int shift)
|
||||
@ -577,6 +624,25 @@ static void xdr_buf_pages_shift_right(const struct xdr_buf *buf,
|
||||
xdr_buf_pages_copy_right(buf, base, len, shift);
|
||||
}
|
||||
|
||||
static void xdr_buf_head_shift_right(const struct xdr_buf *buf,
|
||||
unsigned int base, unsigned int len,
|
||||
unsigned int shift)
|
||||
{
|
||||
const struct kvec *head = buf->head;
|
||||
|
||||
if (!shift)
|
||||
return;
|
||||
if (base >= head->iov_len) {
|
||||
xdr_buf_pages_shift_right(buf, head->iov_len - base, len,
|
||||
shift);
|
||||
return;
|
||||
}
|
||||
if (base + len > head->iov_len)
|
||||
xdr_buf_pages_shift_right(buf, 0, base + len - head->iov_len,
|
||||
shift);
|
||||
xdr_buf_head_copy_right(buf, base, len, shift);
|
||||
}
|
||||
|
||||
static void xdr_buf_tail_copy_left(const struct xdr_buf *buf, unsigned int base,
|
||||
unsigned int len, unsigned int shift)
|
||||
{
|
||||
@ -683,86 +749,31 @@ static void xdr_buf_pages_shift_left(const struct xdr_buf *buf,
|
||||
/**
|
||||
* xdr_shrink_bufhead
|
||||
* @buf: xdr_buf
|
||||
* @len: bytes to remove from buf->head[0]
|
||||
* @len: new length of buf->head[0]
|
||||
*
|
||||
* Shrinks XDR buffer's header kvec buf->head[0] by
|
||||
* Shrinks XDR buffer's header kvec buf->head[0], setting it to
|
||||
* 'len' bytes. The extra data is not lost, but is instead
|
||||
* moved into the inlined pages and/or the tail.
|
||||
*/
|
||||
static unsigned int
|
||||
xdr_shrink_bufhead(struct xdr_buf *buf, size_t len)
|
||||
static unsigned int xdr_shrink_bufhead(struct xdr_buf *buf, unsigned int len)
|
||||
{
|
||||
struct kvec *head, *tail;
|
||||
size_t copy, offs;
|
||||
unsigned int pglen = buf->page_len;
|
||||
unsigned int result;
|
||||
|
||||
result = 0;
|
||||
tail = buf->tail;
|
||||
head = buf->head;
|
||||
struct kvec *head = buf->head;
|
||||
unsigned int shift, buflen = max(buf->len, len);
|
||||
|
||||
WARN_ON_ONCE(len > head->iov_len);
|
||||
if (len > head->iov_len)
|
||||
len = head->iov_len;
|
||||
|
||||
/* Shift the tail first */
|
||||
if (tail->iov_len != 0) {
|
||||
if (tail->iov_len > len) {
|
||||
copy = tail->iov_len - len;
|
||||
memmove((char *)tail->iov_base + len,
|
||||
tail->iov_base, copy);
|
||||
result += copy;
|
||||
}
|
||||
/* Copy from the inlined pages into the tail */
|
||||
copy = len;
|
||||
if (copy > pglen)
|
||||
copy = pglen;
|
||||
offs = len - copy;
|
||||
if (offs >= tail->iov_len)
|
||||
copy = 0;
|
||||
else if (copy > tail->iov_len - offs)
|
||||
copy = tail->iov_len - offs;
|
||||
if (copy != 0) {
|
||||
_copy_from_pages((char *)tail->iov_base + offs,
|
||||
buf->pages,
|
||||
buf->page_base + pglen + offs - len,
|
||||
copy);
|
||||
result += copy;
|
||||
}
|
||||
/* Do we also need to copy data from the head into the tail ? */
|
||||
if (len > pglen) {
|
||||
offs = copy = len - pglen;
|
||||
if (copy > tail->iov_len)
|
||||
copy = tail->iov_len;
|
||||
memcpy(tail->iov_base,
|
||||
(char *)head->iov_base +
|
||||
head->iov_len - offs,
|
||||
copy);
|
||||
result += copy;
|
||||
}
|
||||
if (head->iov_len > buflen) {
|
||||
buf->buflen -= head->iov_len - buflen;
|
||||
head->iov_len = buflen;
|
||||
}
|
||||
/* Now handle pages */
|
||||
if (pglen != 0) {
|
||||
if (pglen > len)
|
||||
_shift_data_right_pages(buf->pages,
|
||||
buf->page_base + len,
|
||||
buf->page_base,
|
||||
pglen - len);
|
||||
copy = len;
|
||||
if (len > pglen)
|
||||
copy = pglen;
|
||||
_copy_to_pages(buf->pages, buf->page_base,
|
||||
(char *)head->iov_base + head->iov_len - len,
|
||||
copy);
|
||||
result += copy;
|
||||
}
|
||||
head->iov_len -= len;
|
||||
buf->buflen -= len;
|
||||
/* Have we truncated the message? */
|
||||
if (buf->len > buf->buflen)
|
||||
buf->len = buf->buflen;
|
||||
|
||||
return result;
|
||||
if (len >= head->iov_len)
|
||||
return 0;
|
||||
shift = head->iov_len - len;
|
||||
xdr_buf_try_expand(buf, shift);
|
||||
xdr_buf_head_shift_right(buf, len, buflen - len, shift);
|
||||
head->iov_len = len;
|
||||
buf->buflen -= shift;
|
||||
buf->len -= shift;
|
||||
return shift;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -798,7 +809,7 @@ static unsigned int xdr_shrink_pagelen(struct xdr_buf *buf, unsigned int len)
|
||||
void
|
||||
xdr_shift_buf(struct xdr_buf *buf, size_t len)
|
||||
{
|
||||
xdr_shrink_bufhead(buf, len);
|
||||
xdr_shrink_bufhead(buf, buf->head->iov_len - len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xdr_shift_buf);
|
||||
|
||||
@ -1371,13 +1382,12 @@ static void xdr_realign_pages(struct xdr_stream *xdr)
|
||||
struct xdr_buf *buf = xdr->buf;
|
||||
struct kvec *iov = buf->head;
|
||||
unsigned int cur = xdr_stream_pos(xdr);
|
||||
unsigned int copied, offset;
|
||||
unsigned int copied;
|
||||
|
||||
/* Realign pages to current pointer position */
|
||||
if (iov->iov_len > cur) {
|
||||
offset = iov->iov_len - cur;
|
||||
copied = xdr_shrink_bufhead(buf, offset);
|
||||
trace_rpc_xdr_alignment(xdr, offset, copied);
|
||||
copied = xdr_shrink_bufhead(buf, cur);
|
||||
trace_rpc_xdr_alignment(xdr, cur, copied);
|
||||
xdr->nwords = XDR_QUADLEN(buf->len - cur);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user