aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-01-31 23:23:35 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2015-02-17 22:23:29 -0500
commitc993c39b86398c627afda36b45dc92de655e213e (patch)
tree7135add7da7e2c35dc138f2ef69799554c347292 /drivers/usb
parentde2080d41b5d584205e408d72021f0f335a046fc (diff)
gadget/function/f_fs.c: use put iov_iter into io_data
both on aio and non-aio sides Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/function/f_fs.c86
1 files changed, 25 insertions, 61 deletions
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 3ab34a2075df..98610e4595de 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -144,10 +144,9 @@ struct ffs_io_data {
144 bool read; 144 bool read;
145 145
146 struct kiocb *kiocb; 146 struct kiocb *kiocb;
147 const struct iovec *iovec; 147 struct iov_iter data;
148 unsigned long nr_segs; 148 const void *to_free;
149 char __user *buf; 149 char *buf;
150 size_t len;
151 150
152 struct mm_struct *mm; 151 struct mm_struct *mm;
153 struct work_struct work; 152 struct work_struct work;
@@ -649,29 +648,10 @@ static void ffs_user_copy_worker(struct work_struct *work)
649 io_data->req->actual; 648 io_data->req->actual;
650 649
651 if (io_data->read && ret > 0) { 650 if (io_data->read && ret > 0) {
652 int i;
653 size_t pos = 0;
654
655 /*
656 * Since req->length may be bigger than io_data->len (after
657 * being rounded up to maxpacketsize), we may end up with more
658 * data then user space has space for.
659 */
660 ret = min_t(int, ret, io_data->len);
661
662 use_mm(io_data->mm); 651 use_mm(io_data->mm);
663 for (i = 0; i < io_data->nr_segs; i++) { 652 ret = copy_to_iter(io_data->buf, ret, &io_data->data);
664 size_t len = min_t(size_t, ret - pos, 653 if (iov_iter_count(&io_data->data))
665 io_data->iovec[i].iov_len); 654 ret = -EFAULT;
666 if (!len)
667 break;
668 if (unlikely(copy_to_user(io_data->iovec[i].iov_base,
669 &io_data->buf[pos], len))) {
670 ret = -EFAULT;
671 break;
672 }
673 pos += len;
674 }
675 unuse_mm(io_data->mm); 655 unuse_mm(io_data->mm);
676 } 656 }
677 657
@@ -684,7 +664,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
684 664
685 io_data->kiocb->private = NULL; 665 io_data->kiocb->private = NULL;
686 if (io_data->read) 666 if (io_data->read)
687 kfree(io_data->iovec); 667 kfree(io_data->to_free);
688 kfree(io_data->buf); 668 kfree(io_data->buf);
689 kfree(io_data); 669 kfree(io_data);
690} 670}
@@ -743,6 +723,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
743 * before the waiting completes, so do not assign to 'gadget' earlier 723 * before the waiting completes, so do not assign to 'gadget' earlier
744 */ 724 */
745 struct usb_gadget *gadget = epfile->ffs->gadget; 725 struct usb_gadget *gadget = epfile->ffs->gadget;
726 size_t copied;
746 727
747 spin_lock_irq(&epfile->ffs->eps_lock); 728 spin_lock_irq(&epfile->ffs->eps_lock);
748 /* In the meantime, endpoint got disabled or changed. */ 729 /* In the meantime, endpoint got disabled or changed. */
@@ -750,34 +731,21 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
750 spin_unlock_irq(&epfile->ffs->eps_lock); 731 spin_unlock_irq(&epfile->ffs->eps_lock);
751 return -ESHUTDOWN; 732 return -ESHUTDOWN;
752 } 733 }
734 data_len = iov_iter_count(&io_data->data);
753 /* 735 /*
754 * Controller may require buffer size to be aligned to 736 * Controller may require buffer size to be aligned to
755 * maxpacketsize of an out endpoint. 737 * maxpacketsize of an out endpoint.
756 */ 738 */
757 data_len = io_data->read ? 739 if (io_data->read)
758 usb_ep_align_maybe(gadget, ep->ep, io_data->len) : 740 data_len = usb_ep_align_maybe(gadget, ep->ep, data_len);
759 io_data->len;
760 spin_unlock_irq(&epfile->ffs->eps_lock); 741 spin_unlock_irq(&epfile->ffs->eps_lock);
761 742
762 data = kmalloc(data_len, GFP_KERNEL); 743 data = kmalloc(data_len, GFP_KERNEL);
763 if (unlikely(!data)) 744 if (unlikely(!data))
764 return -ENOMEM; 745 return -ENOMEM;
765 if (io_data->aio && !io_data->read) { 746 if (!io_data->read) {
766 int i; 747 copied = copy_from_iter(data, data_len, &io_data->data);
767 size_t pos = 0; 748 if (copied != data_len) {
768 for (i = 0; i < io_data->nr_segs; i++) {
769 if (unlikely(copy_from_user(&data[pos],
770 io_data->iovec[i].iov_base,
771 io_data->iovec[i].iov_len))) {
772 ret = -EFAULT;
773 goto error;
774 }
775 pos += io_data->iovec[i].iov_len;
776 }
777 } else {
778 if (!io_data->read &&
779 unlikely(__copy_from_user(data, io_data->buf,
780 io_data->len))) {
781 ret = -EFAULT; 749 ret = -EFAULT;
782 goto error; 750 goto error;
783 } 751 }
@@ -876,10 +844,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
876 */ 844 */
877 ret = ep->status; 845 ret = ep->status;
878 if (io_data->read && ret > 0) { 846 if (io_data->read && ret > 0) {
879 ret = min_t(size_t, ret, io_data->len); 847 ret = copy_to_iter(data, ret, &io_data->data);
880 848 if (unlikely(iov_iter_count(&io_data->data)))
881 if (unlikely(copy_to_user(io_data->buf,
882 data, ret)))
883 ret = -EFAULT; 849 ret = -EFAULT;
884 } 850 }
885 } 851 }
@@ -903,13 +869,13 @@ ffs_epfile_write(struct file *file, const char __user *buf, size_t len,
903 loff_t *ptr) 869 loff_t *ptr)
904{ 870{
905 struct ffs_io_data io_data; 871 struct ffs_io_data io_data;
872 struct iovec iov = {.iov_base = buf, .iov_len = len};
906 873
907 ENTER(); 874 ENTER();
908 875
909 io_data.aio = false; 876 io_data.aio = false;
910 io_data.read = false; 877 io_data.read = false;
911 io_data.buf = (char * __user)buf; 878 iov_iter_init(&io_data.data, WRITE, &iov, 1, len);
912 io_data.len = len;
913 879
914 return ffs_epfile_io(file, &io_data); 880 return ffs_epfile_io(file, &io_data);
915} 881}
@@ -918,13 +884,14 @@ static ssize_t
918ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr) 884ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr)
919{ 885{
920 struct ffs_io_data io_data; 886 struct ffs_io_data io_data;
887 struct iovec iov = {.iov_base = buf, .iov_len = len};
921 888
922 ENTER(); 889 ENTER();
923 890
924 io_data.aio = false; 891 io_data.aio = false;
925 io_data.read = true; 892 io_data.read = true;
926 io_data.buf = buf; 893 io_data.to_free = NULL;
927 io_data.len = len; 894 iov_iter_init(&io_data.data, READ, &iov, 1, len);
928 895
929 return ffs_epfile_io(file, &io_data); 896 return ffs_epfile_io(file, &io_data);
930} 897}
@@ -981,9 +948,7 @@ static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb,
981 io_data->aio = true; 948 io_data->aio = true;
982 io_data->read = false; 949 io_data->read = false;
983 io_data->kiocb = kiocb; 950 io_data->kiocb = kiocb;
984 io_data->iovec = iovec; 951 iov_iter_init(&io_data->data, WRITE, iovec, nr_segs, kiocb->ki_nbytes);
985 io_data->nr_segs = nr_segs;
986 io_data->len = kiocb->ki_nbytes;
987 io_data->mm = current->mm; 952 io_data->mm = current->mm;
988 953
989 kiocb->private = io_data; 954 kiocb->private = io_data;
@@ -1021,9 +986,8 @@ static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb,
1021 io_data->aio = true; 986 io_data->aio = true;
1022 io_data->read = true; 987 io_data->read = true;
1023 io_data->kiocb = kiocb; 988 io_data->kiocb = kiocb;
1024 io_data->iovec = iovec_copy; 989 io_data->to_free = iovec_copy;
1025 io_data->nr_segs = nr_segs; 990 iov_iter_init(&io_data->data, READ, iovec_copy, nr_segs, kiocb->ki_nbytes);
1026 io_data->len = kiocb->ki_nbytes;
1027 io_data->mm = current->mm; 991 io_data->mm = current->mm;
1028 992
1029 kiocb->private = io_data; 993 kiocb->private = io_data;
@@ -1032,8 +996,8 @@ static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb,
1032 996
1033 res = ffs_epfile_io(kiocb->ki_filp, io_data); 997 res = ffs_epfile_io(kiocb->ki_filp, io_data);
1034 if (res != -EIOCBQUEUED) { 998 if (res != -EIOCBQUEUED) {
999 kfree(io_data->to_free);
1035 kfree(io_data); 1000 kfree(io_data);
1036 kfree(iovec_copy);
1037 } 1001 }
1038 return res; 1002 return res;
1039} 1003}