diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-08-02 19:21:43 +0200 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-09-28 21:58:42 +0200 |
commit | a11a2bf4de5679fa0b63474c7d39bea2dac7d061 (patch) | |
tree | d59f027797b629d029596f968ccf65dc7916509f /net/sunrpc/xdr.c | |
parent | NFSv4.1: decode_getdeviceinfo should check xdr_read_pages() return value (diff) | |
download | linux-a11a2bf4de5679fa0b63474c7d39bea2dac7d061.tar.xz linux-a11a2bf4de5679fa0b63474c7d39bea2dac7d061.zip |
SUNRPC: Optimise away unnecessary data moves in xdr_align_pages
We only have to call xdr_shrink_pagelen() if the remaining RPC
message does not fit in the page buffer length that we supplied
to xdr_align_pages().
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xdr.c')
-rw-r--r-- | net/sunrpc/xdr.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index fbbd1c475b43..08f50afd5f2a 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -730,21 +730,24 @@ static unsigned int xdr_align_pages(struct xdr_stream *xdr, unsigned int len) if (xdr->nwords == 0) return 0; - if (nwords > xdr->nwords) { - nwords = xdr->nwords; - len = nwords << 2; - } /* Realign pages to current pointer position */ iov = buf->head; - if (iov->iov_len > cur) + if (iov->iov_len > cur) { xdr_shrink_bufhead(buf, iov->iov_len - cur); + xdr->nwords = XDR_QUADLEN(buf->len - cur); + } - /* Truncate page data and move it into the tail */ - if (buf->page_len > len) - xdr_shrink_pagelen(buf, buf->page_len - len); - else + if (nwords > xdr->nwords) { + nwords = xdr->nwords; + len = nwords << 2; + } + if (buf->page_len <= len) len = buf->page_len; - xdr->nwords = XDR_QUADLEN(buf->len - cur); + else if (nwords < xdr->nwords) { + /* Truncate page data and move it into the tail */ + xdr_shrink_pagelen(buf, buf->page_len - len); + xdr->nwords = XDR_QUADLEN(buf->len - cur); + } return len; } |