Commit d40a126b authored by Sowmini Varadhan's avatar Sowmini Varadhan Committed by David S. Miller

rds: refactor zcopy code into rds_message_zcopy_from_user

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: default avatarSowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c33b3b9f
...@@ -333,14 +333,14 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in ...@@ -333,14 +333,14 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
return rm; return rm;
} }
int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from, int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from)
bool zcopy)
{ {
unsigned long to_copy, nbytes;
unsigned long sg_off; unsigned long sg_off;
struct scatterlist *sg; struct scatterlist *sg;
int ret = 0; int ret = 0;
int length = iov_iter_count(from); 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)); 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, ...@@ -350,54 +350,66 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from,
sg = rm->data.op_sg; sg = rm->data.op_sg;
sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */
if (zcopy) { skb = alloc_skb(0, GFP_KERNEL);
int total_copied = 0; if (!skb)
struct sk_buff *skb; return -ENOMEM;
BUILD_BUG_ON(sizeof(skb->cb) < max_t(int, sizeof(struct rds_znotifier),
skb = alloc_skb(0, GFP_KERNEL); sizeof(struct rds_zcopy_cookies)));
if (!skb) rm->data.op_mmp_znotifier = RDS_ZCOPY_SKB(skb);
return -ENOMEM; if (mm_account_pinned_pages(&rm->data.op_mmp_znotifier->z_mmp,
BUILD_BUG_ON(sizeof(skb->cb) < length)) {
max_t(int, sizeof(struct rds_znotifier), ret = -ENOMEM;
sizeof(struct rds_zcopy_cookies))); goto err;
rm->data.op_mmp_znotifier = RDS_ZCOPY_SKB(skb); }
if (mm_account_pinned_pages(&rm->data.op_mmp_znotifier->z_mmp, while (iov_iter_count(from)) {
length)) { struct page *pages;
ret = -ENOMEM; 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; goto err;
} }
while (iov_iter_count(from)) { total_copied += copied;
struct page *pages; iov_iter_advance(from, copied);
size_t start; length -= copied;
ssize_t copied; sg_set_page(sg, pages, copied, start);
rm->data.op_nents++;
copied = iov_iter_get_pages(from, &pages, PAGE_SIZE, sg++;
1, &start); }
if (copied < 0) { WARN_ON_ONCE(length != 0);
struct mmpin *mmp; return ret;
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;
err: err:
consume_skb(skb); consume_skb(skb);
rm->data.op_mmp_znotifier = NULL; rm->data.op_mmp_znotifier = NULL;
return ret; return ret;
} /* zcopy */ }
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)) { while (iov_iter_count(from)) {
if (!sg_page(sg)) { if (!sg_page(sg)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment