aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/ib_recv.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-11-20 09:21:14 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-11-24 05:16:43 -0500
commitc310e72c89926e06138e4881f21e4c8da3e7ef18 (patch)
treecf40fae1e3639f0ff3607561c1e4fd484b7b53e9 /net/rds/ib_recv.c
parent7424ce65065852bdf7a040bf2490da4a8fc4b464 (diff)
rds: switch ->inc_copy_to_user() to passing iov_iter
instances get considerably simpler from that... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/rds/ib_recv.c')
-rw-r--r--net/rds/ib_recv.c37
1 files changed, 11 insertions, 26 deletions
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index d67de453c35a..1b981a4e42c2 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -472,15 +472,12 @@ static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache
472 return head; 472 return head;
473} 473}
474 474
475int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, 475int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
476 size_t size)
477{ 476{
478 struct rds_ib_incoming *ibinc; 477 struct rds_ib_incoming *ibinc;
479 struct rds_page_frag *frag; 478 struct rds_page_frag *frag;
480 struct iovec *iov = first_iov;
481 unsigned long to_copy; 479 unsigned long to_copy;
482 unsigned long frag_off = 0; 480 unsigned long frag_off = 0;
483 unsigned long iov_off = 0;
484 int copied = 0; 481 int copied = 0;
485 int ret; 482 int ret;
486 u32 len; 483 u32 len;
@@ -489,37 +486,25 @@ int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
489 frag = list_entry(ibinc->ii_frags.next, struct rds_page_frag, f_item); 486 frag = list_entry(ibinc->ii_frags.next, struct rds_page_frag, f_item);
490 len = be32_to_cpu(inc->i_hdr.h_len); 487 len = be32_to_cpu(inc->i_hdr.h_len);
491 488
492 while (copied < size && copied < len) { 489 while (iov_iter_count(to) && copied < len) {
493 if (frag_off == RDS_FRAG_SIZE) { 490 if (frag_off == RDS_FRAG_SIZE) {
494 frag = list_entry(frag->f_item.next, 491 frag = list_entry(frag->f_item.next,
495 struct rds_page_frag, f_item); 492 struct rds_page_frag, f_item);
496 frag_off = 0; 493 frag_off = 0;
497 } 494 }
498 while (iov_off == iov->iov_len) { 495 to_copy = min_t(unsigned long, iov_iter_count(to),
499 iov_off = 0; 496 RDS_FRAG_SIZE - frag_off);
500 iov++;
501 }
502
503 to_copy = min(iov->iov_len - iov_off, RDS_FRAG_SIZE - frag_off);
504 to_copy = min_t(size_t, to_copy, size - copied);
505 to_copy = min_t(unsigned long, to_copy, len - copied); 497 to_copy = min_t(unsigned long, to_copy, len - copied);
506 498
507 rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag "
508 "[%p, %u] + %lu\n",
509 to_copy, iov->iov_base, iov->iov_len, iov_off,
510 sg_page(&frag->f_sg), frag->f_sg.offset, frag_off);
511
512 /* XXX needs + offset for multiple recvs per page */ 499 /* XXX needs + offset for multiple recvs per page */
513 ret = rds_page_copy_to_user(sg_page(&frag->f_sg), 500 rds_stats_add(s_copy_to_user, to_copy);
514 frag->f_sg.offset + frag_off, 501 ret = copy_page_to_iter(sg_page(&frag->f_sg),
515 iov->iov_base + iov_off, 502 frag->f_sg.offset + frag_off,
516 to_copy); 503 to_copy,
517 if (ret) { 504 to);
518 copied = ret; 505 if (ret != to_copy)
519 break; 506 return -EFAULT;
520 }
521 507
522 iov_off += to_copy;
523 frag_off += to_copy; 508 frag_off += to_copy;
524 copied += to_copy; 509 copied += to_copy;
525 } 510 }