aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/tcp_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/tcp_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/tcp_recv.c')
-rw-r--r--net/rds/tcp_recv.c38
1 files changed, 9 insertions, 29 deletions
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
index 9ae6e0a264ec..fbc5ef88bc0e 100644
--- a/net/rds/tcp_recv.c
+++ b/net/rds/tcp_recv.c
@@ -59,50 +59,30 @@ void rds_tcp_inc_free(struct rds_incoming *inc)
59/* 59/*
60 * this is pretty lame, but, whatever. 60 * this is pretty lame, but, whatever.
61 */ 61 */
62int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, 62int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
63 size_t size)
64{ 63{
65 struct rds_tcp_incoming *tinc; 64 struct rds_tcp_incoming *tinc;
66 struct iovec *iov, tmp;
67 struct sk_buff *skb; 65 struct sk_buff *skb;
68 unsigned long to_copy, skb_off;
69 int ret = 0; 66 int ret = 0;
70 67
71 if (size == 0) 68 if (!iov_iter_count(to))
72 goto out; 69 goto out;
73 70
74 tinc = container_of(inc, struct rds_tcp_incoming, ti_inc); 71 tinc = container_of(inc, struct rds_tcp_incoming, ti_inc);
75 iov = first_iov;
76 tmp = *iov;
77 72
78 skb_queue_walk(&tinc->ti_skb_list, skb) { 73 skb_queue_walk(&tinc->ti_skb_list, skb) {
79 skb_off = 0; 74 unsigned long to_copy, skb_off;
80 while (skb_off < skb->len) { 75 for (skb_off = 0; skb_off < skb->len; skb_off += to_copy) {
81 while (tmp.iov_len == 0) { 76 to_copy = iov_iter_count(to);
82 iov++;
83 tmp = *iov;
84 }
85
86 to_copy = min(tmp.iov_len, size);
87 to_copy = min(to_copy, skb->len - skb_off); 77 to_copy = min(to_copy, skb->len - skb_off);
88 78
89 rdsdebug("ret %d size %zu skb %p skb_off %lu " 79 if (skb_copy_datagram_iter(skb, skb_off, to, to_copy))
90 "skblen %d iov_base %p iov_len %zu cpy %lu\n", 80 return -EFAULT;
91 ret, size, skb, skb_off, skb->len,
92 tmp.iov_base, tmp.iov_len, to_copy);
93
94 /* modifies tmp as it copies */
95 if (skb_copy_datagram_iovec(skb, skb_off, &tmp,
96 to_copy)) {
97 ret = -EFAULT;
98 goto out;
99 }
100 81
101 rds_stats_add(s_copy_to_user, to_copy); 82 rds_stats_add(s_copy_to_user, to_copy);
102 size -= to_copy;
103 ret += to_copy; 83 ret += to_copy;
104 skb_off += to_copy; 84
105 if (size == 0) 85 if (!iov_iter_count(to))
106 goto out; 86 goto out;
107 } 87 }
108 } 88 }