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/tcp_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/tcp_recv.c')
-rw-r--r-- | net/rds/tcp_recv.c | 38 |
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 | */ |
62 | int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, | 62 | int 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 | } |