Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[atm] switch vcc_sendmsg() to copy_from_iter()

... and make it handle multi-segment iovecs - deals with that
"fix this later" issue for free. A bit of shame, really - it
had been there since 2.3.15pre3 when the whole thing went into the
tree, practically a historical artefact by now...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 7424ce65 0f7db23a

+6 -11
+6 -11
net/atm/common.c
··· 570 570 } 571 571 572 572 int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, 573 - size_t total_len) 573 + size_t size) 574 574 { 575 575 struct sock *sk = sock->sk; 576 576 DEFINE_WAIT(wait); 577 577 struct atm_vcc *vcc; 578 578 struct sk_buff *skb; 579 579 int eff, error; 580 - const void __user *buff; 581 - int size; 580 + struct iov_iter from; 581 + 582 + iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, size); 582 583 583 584 lock_sock(sk); 584 585 if (sock->state != SS_CONNECTED) { ··· 590 589 error = -EISCONN; 591 590 goto out; 592 591 } 593 - if (m->msg_iovlen != 1) { 594 - error = -ENOSYS; /* fix this later @@@ */ 595 - goto out; 596 - } 597 - buff = m->msg_iov->iov_base; 598 - size = m->msg_iov->iov_len; 599 592 vcc = ATM_SD(sock); 600 593 if (test_bit(ATM_VF_RELEASED, &vcc->flags) || 601 594 test_bit(ATM_VF_CLOSE, &vcc->flags) || ··· 602 607 error = 0; 603 608 goto out; 604 609 } 605 - if (size < 0 || size > vcc->qos.txtp.max_sdu) { 610 + if (size > vcc->qos.txtp.max_sdu) { 606 611 error = -EMSGSIZE; 607 612 goto out; 608 613 } ··· 634 639 goto out; 635 640 skb->dev = NULL; /* for paths shared with net_device interfaces */ 636 641 ATM_SKB(skb)->atm_options = vcc->atm_options; 637 - if (copy_from_user(skb_put(skb, size), buff, size)) { 642 + if (copy_from_iter(skb_put(skb, size), size, &from) != size) { 638 643 kfree_skb(skb); 639 644 error = -EFAULT; 640 645 goto out;