summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@codeaurora.org>2016-02-03 11:56:30 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:08:02 -0700
commit16d16b9e26a13f8a256db50353864fa98a0f9e8d (patch)
tree6bf4bde2e3400c51ac5e990c389264c0da9dd7a9 /net
parentbb3068325b72f0662168340f2dfc8d6cb690364b (diff)
net: ipc_router: Use iov_iter accessor functions
The networking module uses iov_iter library to manage the vector buffers from user-space. Use iov_iter accessor functions to copy the data from/to the user-space vector buffers. Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
Diffstat (limited to 'net')
-rw-r--r--net/ipc_router/ipc_router_socket.c97
1 files changed, 42 insertions, 55 deletions
diff --git a/net/ipc_router/ipc_router_socket.c b/net/ipc_router/ipc_router_socket.c
index 088579139cf1..02f1f7759d6a 100644
--- a/net/ipc_router/ipc_router_socket.c
+++ b/net/ipc_router/ipc_router_socket.c
@@ -47,20 +47,20 @@ static const struct proto_ops msm_ipc_proto_ops;
static RAW_NOTIFIER_HEAD(ipcrtr_af_init_chain);
static DEFINE_MUTEX(ipcrtr_af_init_lock);
-static struct sk_buff_head *msm_ipc_router_build_msg(unsigned int num_sect,
- struct iovec const *msg_sect,
+static struct sk_buff_head *msm_ipc_router_build_msg(struct msghdr *m,
size_t total_len)
{
struct sk_buff_head *msg_head;
struct sk_buff *msg;
- int i, copied, first = 1;
- int data_size = 0, request_size, offset;
+ int first = 1;
+ int last = 1;
+ size_t data_size = 0;
+ size_t alloc_size, align_size;
void *data;
- int last = 0;
- int align_size;
+ size_t total_copied_size = 0, copied_size;
- for (i = 0; i < num_sect; i++)
- data_size += msg_sect[i].iov_len;
+ if (iov_iter_count(&m->msg_iter) == total_len)
+ data_size = total_len;
if (!data_size)
return NULL;
@@ -73,52 +73,41 @@ static struct sk_buff_head *msm_ipc_router_build_msg(unsigned int num_sect,
}
skb_queue_head_init(msg_head);
- for (copied = 1, i = 0; copied && (i < num_sect); i++) {
- data_size = msg_sect[i].iov_len;
- offset = 0;
- if (i == (num_sect - 1))
- last = 1;
- while (offset != msg_sect[i].iov_len) {
- request_size = data_size;
- if (first)
- request_size += IPC_ROUTER_HDR_SIZE;
- if (last)
- request_size += align_size;
-
- msg = alloc_skb(request_size, GFP_KERNEL);
- if (!msg) {
- if (request_size <= (PAGE_SIZE/2)) {
- IPC_RTR_ERR(
- "%s: cannot allocated skb\n",
+ while (total_copied_size < total_len) {
+ alloc_size = data_size;
+ if (first)
+ alloc_size += IPC_ROUTER_HDR_SIZE;
+ if (last)
+ alloc_size += align_size;
+
+ msg = alloc_skb(alloc_size, GFP_KERNEL);
+ if (!msg) {
+ if (alloc_size <= (PAGE_SIZE/2)) {
+ IPC_RTR_ERR("%s: cannot allocated skb\n",
__func__);
- goto msg_build_failure;
- }
- data_size = data_size / 2;
- last = 0;
- continue;
+ goto msg_build_failure;
}
+ data_size = data_size / 2;
+ last = 0;
+ continue;
+ }
- if (first) {
- skb_reserve(msg, IPC_ROUTER_HDR_SIZE);
- first = 0;
- }
+ if (first) {
+ skb_reserve(msg, IPC_ROUTER_HDR_SIZE);
+ first = 0;
+ }
- data = skb_put(msg, data_size);
- copied = !copy_from_user(msg->data,
- msg_sect[i].iov_base + offset,
- data_size);
- if (!copied) {
- IPC_RTR_ERR("%s: copy_from_user failed\n",
- __func__);
- kfree_skb(msg);
- goto msg_build_failure;
- }
- skb_queue_tail(msg_head, msg);
- offset += data_size;
- data_size = msg_sect[i].iov_len - offset;
- if (i == (num_sect - 1))
- last = 1;
+ data = skb_put(msg, data_size);
+ copied_size = copy_from_iter(msg->data, data_size, &m->msg_iter);
+ if (copied_size != data_size) {
+ IPC_RTR_ERR("%s: copy_from_iter failed %zu %zu %zu\n", __func__, alloc_size, data_size, copied_size);
+ kfree_skb(msg);
+ goto msg_build_failure;
}
+ skb_queue_tail(msg_head, msg);
+ total_copied_size += data_size;
+ data_size = total_len - total_copied_size;
+ last = 1;
}
return msg_head;
@@ -138,7 +127,7 @@ static int msm_ipc_router_extract_msg(struct msghdr *m,
struct rr_header_v1 *hdr;
struct sk_buff *temp;
union rr_control_msg *ctl_msg;
- int offset = 0, data_len = 0, copy_len;
+ int offset = 0, data_len = 0, copy_len, copied_len;
if (!m || !pkt) {
IPC_RTR_ERR("%s: Invalid pointers passed\n", __func__);
@@ -168,8 +157,8 @@ static int msm_ipc_router_extract_msg(struct msghdr *m,
data_len = hdr->size;
skb_queue_walk(pkt->pkt_fragment_q, temp) {
copy_len = data_len < temp->len ? data_len : temp->len;
- if (copy_to_user(m->msg_iov->iov_base + offset, temp->data,
- copy_len)) {
+ copied_len = copy_to_iter(temp->data, copy_len, &m->msg_iter);
+ if (copy_len != copied_len) {
IPC_RTR_ERR("%s: Copy to user failed\n", __func__);
return -EFAULT;
}
@@ -344,7 +333,7 @@ static int msm_ipc_router_sendmsg(struct socket *sock,
lock_sock(sk);
timeout = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
- msg = msm_ipc_router_build_msg(m->msg_iovlen, m->msg_iov, total_len);
+ msg = msm_ipc_router_build_msg(m, total_len);
if (!msg) {
IPC_RTR_ERR("%s: Msg build failure\n", __func__);
ret = -ENOMEM;
@@ -380,8 +369,6 @@ static int msm_ipc_router_recvmsg(struct socket *sock,
long timeout;
int ret;
- if (m->msg_iovlen != 1)
- return -EOPNOTSUPP;
lock_sock(sk);
if (!buf_len) {
if (flags & MSG_PEEK)