diff options
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/net/socket.c b/net/socket.c index 1bc4167e0da8..df92e4252749 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -95,10 +95,10 @@ | |||
95 | #include <linux/netfilter.h> | 95 | #include <linux/netfilter.h> |
96 | 96 | ||
97 | static int sock_no_open(struct inode *irrelevant, struct file *dontcare); | 97 | static int sock_no_open(struct inode *irrelevant, struct file *dontcare); |
98 | static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf, | 98 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
99 | size_t size, loff_t pos); | 99 | unsigned long nr_segs, loff_t pos); |
100 | static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *buf, | 100 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, |
101 | size_t size, loff_t pos); | 101 | unsigned long nr_segs, loff_t pos); |
102 | static int sock_mmap(struct file *file, struct vm_area_struct *vma); | 102 | static int sock_mmap(struct file *file, struct vm_area_struct *vma); |
103 | 103 | ||
104 | static int sock_close(struct inode *inode, struct file *file); | 104 | static int sock_close(struct inode *inode, struct file *file); |
@@ -664,7 +664,6 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, | |||
664 | } | 664 | } |
665 | 665 | ||
666 | static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, | 666 | static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, |
667 | char __user *ubuf, size_t size, | ||
668 | struct sock_iocb *siocb) | 667 | struct sock_iocb *siocb) |
669 | { | 668 | { |
670 | if (!is_sync_kiocb(iocb)) { | 669 | if (!is_sync_kiocb(iocb)) { |
@@ -675,16 +674,13 @@ static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, | |||
675 | } | 674 | } |
676 | 675 | ||
677 | siocb->kiocb = iocb; | 676 | siocb->kiocb = iocb; |
678 | siocb->async_iov.iov_base = ubuf; | ||
679 | siocb->async_iov.iov_len = size; | ||
680 | |||
681 | iocb->private = siocb; | 677 | iocb->private = siocb; |
682 | return siocb; | 678 | return siocb; |
683 | } | 679 | } |
684 | 680 | ||
685 | static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, | 681 | static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, |
686 | struct file *file, struct iovec *iov, | 682 | struct file *file, const struct iovec *iov, |
687 | unsigned long nr_segs) | 683 | unsigned long nr_segs) |
688 | { | 684 | { |
689 | struct socket *sock = file->private_data; | 685 | struct socket *sock = file->private_data; |
690 | size_t size = 0; | 686 | size_t size = 0; |
@@ -715,32 +711,33 @@ static ssize_t sock_readv(struct file *file, const struct iovec *iov, | |||
715 | init_sync_kiocb(&iocb, NULL); | 711 | init_sync_kiocb(&iocb, NULL); |
716 | iocb.private = &siocb; | 712 | iocb.private = &siocb; |
717 | 713 | ||
718 | ret = do_sock_read(&msg, &iocb, file, (struct iovec *)iov, nr_segs); | 714 | ret = do_sock_read(&msg, &iocb, file, iov, nr_segs); |
719 | if (-EIOCBQUEUED == ret) | 715 | if (-EIOCBQUEUED == ret) |
720 | ret = wait_on_sync_kiocb(&iocb); | 716 | ret = wait_on_sync_kiocb(&iocb); |
721 | return ret; | 717 | return ret; |
722 | } | 718 | } |
723 | 719 | ||
724 | static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf, | 720 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
725 | size_t count, loff_t pos) | 721 | unsigned long nr_segs, loff_t pos) |
726 | { | 722 | { |
727 | struct sock_iocb siocb, *x; | 723 | struct sock_iocb siocb, *x; |
728 | 724 | ||
729 | if (pos != 0) | 725 | if (pos != 0) |
730 | return -ESPIPE; | 726 | return -ESPIPE; |
731 | if (count == 0) /* Match SYS5 behaviour */ | 727 | |
728 | if (iocb->ki_left == 0) /* Match SYS5 behaviour */ | ||
732 | return 0; | 729 | return 0; |
733 | 730 | ||
734 | x = alloc_sock_iocb(iocb, ubuf, count, &siocb); | 731 | |
732 | x = alloc_sock_iocb(iocb, &siocb); | ||
735 | if (!x) | 733 | if (!x) |
736 | return -ENOMEM; | 734 | return -ENOMEM; |
737 | return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, | 735 | return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs); |
738 | &x->async_iov, 1); | ||
739 | } | 736 | } |
740 | 737 | ||
741 | static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, | 738 | static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, |
742 | struct file *file, struct iovec *iov, | 739 | struct file *file, const struct iovec *iov, |
743 | unsigned long nr_segs) | 740 | unsigned long nr_segs) |
744 | { | 741 | { |
745 | struct socket *sock = file->private_data; | 742 | struct socket *sock = file->private_data; |
746 | size_t size = 0; | 743 | size_t size = 0; |
@@ -773,28 +770,28 @@ static ssize_t sock_writev(struct file *file, const struct iovec *iov, | |||
773 | init_sync_kiocb(&iocb, NULL); | 770 | init_sync_kiocb(&iocb, NULL); |
774 | iocb.private = &siocb; | 771 | iocb.private = &siocb; |
775 | 772 | ||
776 | ret = do_sock_write(&msg, &iocb, file, (struct iovec *)iov, nr_segs); | 773 | ret = do_sock_write(&msg, &iocb, file, iov, nr_segs); |
777 | if (-EIOCBQUEUED == ret) | 774 | if (-EIOCBQUEUED == ret) |
778 | ret = wait_on_sync_kiocb(&iocb); | 775 | ret = wait_on_sync_kiocb(&iocb); |
779 | return ret; | 776 | return ret; |
780 | } | 777 | } |
781 | 778 | ||
782 | static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf, | 779 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, |
783 | size_t count, loff_t pos) | 780 | unsigned long nr_segs, loff_t pos) |
784 | { | 781 | { |
785 | struct sock_iocb siocb, *x; | 782 | struct sock_iocb siocb, *x; |
786 | 783 | ||
787 | if (pos != 0) | 784 | if (pos != 0) |
788 | return -ESPIPE; | 785 | return -ESPIPE; |
789 | if (count == 0) /* Match SYS5 behaviour */ | 786 | |
787 | if (iocb->ki_left == 0) /* Match SYS5 behaviour */ | ||
790 | return 0; | 788 | return 0; |
791 | 789 | ||
792 | x = alloc_sock_iocb(iocb, (void __user *)ubuf, count, &siocb); | 790 | x = alloc_sock_iocb(iocb, &siocb); |
793 | if (!x) | 791 | if (!x) |
794 | return -ENOMEM; | 792 | return -ENOMEM; |
795 | 793 | ||
796 | return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, | 794 | return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs); |
797 | &x->async_iov, 1); | ||
798 | } | 795 | } |
799 | 796 | ||
800 | /* | 797 | /* |