rds: refactor zcopy code into rds_message_zcopy_from_user
authorSowmini Varadhan <sowmini.varadhan@oracle.com>
Tue, 6 Mar 2018 15:22:33 +0000 (07:22 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 7 Mar 2018 23:05:57 +0000 (18:05 -0500)
Move the large block of code predicated on zcopy from
rds_message_copy_from_user into a new function,
rds_message_zcopy_from_user()

Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/rds/message.c

index 116cf87ccb898081e031e07347a32bd907b843c5..c36edbb92c34eacbfa62eb14b82512b11e23c102 100644 (file)
@@ -333,14 +333,14 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
        return rm;
 }
 
-int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from,
-                              bool zcopy)
+int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from)
 {
-       unsigned long to_copy, nbytes;
        unsigned long sg_off;
        struct scatterlist *sg;
        int ret = 0;
        int length = iov_iter_count(from);
+       int total_copied = 0;
+       struct sk_buff *skb;
 
        rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from));
 
@@ -350,54 +350,66 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from,
        sg = rm->data.op_sg;
        sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */
 
-       if (zcopy) {
-               int total_copied = 0;
-               struct sk_buff *skb;
-
-               skb = alloc_skb(0, GFP_KERNEL);
-               if (!skb)
-                       return -ENOMEM;
-               BUILD_BUG_ON(sizeof(skb->cb) <
-                            max_t(int, sizeof(struct rds_znotifier),
-                                  sizeof(struct rds_zcopy_cookies)));
-               rm->data.op_mmp_znotifier = RDS_ZCOPY_SKB(skb);
-               if (mm_account_pinned_pages(&rm->data.op_mmp_znotifier->z_mmp,
-                                           length)) {
-                       ret = -ENOMEM;
+       skb = alloc_skb(0, GFP_KERNEL);
+       if (!skb)
+               return -ENOMEM;
+       BUILD_BUG_ON(sizeof(skb->cb) < max_t(int, sizeof(struct rds_znotifier),
+                                            sizeof(struct rds_zcopy_cookies)));
+       rm->data.op_mmp_znotifier = RDS_ZCOPY_SKB(skb);
+       if (mm_account_pinned_pages(&rm->data.op_mmp_znotifier->z_mmp,
+                                   length)) {
+               ret = -ENOMEM;
+               goto err;
+       }
+       while (iov_iter_count(from)) {
+               struct page *pages;
+               size_t start;
+               ssize_t copied;
+
+               copied = iov_iter_get_pages(from, &pages, PAGE_SIZE,
+                                           1, &start);
+               if (copied < 0) {
+                       struct mmpin *mmp;
+                       int i;
+
+                       for (i = 0; i < rm->data.op_nents; i++)
+                               put_page(sg_page(&rm->data.op_sg[i]));
+                       mmp = &rm->data.op_mmp_znotifier->z_mmp;
+                       mm_unaccount_pinned_pages(mmp);
+                       ret = -EFAULT;
                        goto err;
                }
-               while (iov_iter_count(from)) {
-                       struct page *pages;
-                       size_t start;
-                       ssize_t copied;
-
-                       copied = iov_iter_get_pages(from, &pages, PAGE_SIZE,
-                                                   1, &start);
-                       if (copied < 0) {
-                               struct mmpin *mmp;
-                               int i;
-
-                               for (i = 0; i < rm->data.op_nents; i++)
-                                       put_page(sg_page(&rm->data.op_sg[i]));
-                               mmp = &rm->data.op_mmp_znotifier->z_mmp;
-                               mm_unaccount_pinned_pages(mmp);
-                               ret = -EFAULT;
-                               goto err;
-                       }
-                       total_copied += copied;
-                       iov_iter_advance(from, copied);
-                       length -= copied;
-                       sg_set_page(sg, pages, copied, start);
-                       rm->data.op_nents++;
-                       sg++;
-               }
-               WARN_ON_ONCE(length != 0);
-               return ret;
+               total_copied += copied;
+               iov_iter_advance(from, copied);
+               length -= copied;
+               sg_set_page(sg, pages, copied, start);
+               rm->data.op_nents++;
+               sg++;
+       }
+       WARN_ON_ONCE(length != 0);
+       return ret;
 err:
-               consume_skb(skb);
-               rm->data.op_mmp_znotifier = NULL;
-               return ret;
-       } /* zcopy */
+       consume_skb(skb);
+       rm->data.op_mmp_znotifier = NULL;
+       return ret;
+}
+
+int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from,
+                              bool zcopy)
+{
+       unsigned long to_copy, nbytes;
+       unsigned long sg_off;
+       struct scatterlist *sg;
+       int ret = 0;
+
+       rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from));
+
+       /* now allocate and copy in the data payload.  */
+       sg = rm->data.op_sg;
+       sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */
+
+       if (zcopy)
+               return rds_message_zcopy_from_user(rm, from);
 
        while (iov_iter_count(from)) {
                if (!sg_page(sg)) {