diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-11-20 09:21:14 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-11-24 05:16:43 -0500 |
commit | c310e72c89926e06138e4881f21e4c8da3e7ef18 (patch) | |
tree | cf40fae1e3639f0ff3607561c1e4fd484b7b53e9 /net/rds/ib_recv.c | |
parent | 7424ce65065852bdf7a040bf2490da4a8fc4b464 (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.c | 37 |
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 | ||
475 | int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, | 475 | int 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 | } |