SUNRPC: Split out _shift_data_right_tail()
authorAnna Schumaker <Anna.Schumaker@Netapp.com>
Wed, 6 May 2020 17:21:30 +0000 (13:21 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Wed, 7 Oct 2020 18:28:39 +0000 (14:28 -0400)
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>
net/sunrpc/xdr.c

index d93bcad5ba9f5e1f0fe393d614011600be592cf0..10a88a67206a5633d7b1f5c5db635ac83124b49d 100644 (file)
@@ -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? */