From patchwork Mon Feb 23 18:00:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 5867511 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5B5CABF440 for ; Mon, 23 Feb 2015 18:02:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 773B520639 for ; Mon, 23 Feb 2015 18:02:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6522A20619 for ; Mon, 23 Feb 2015 18:02:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752499AbbBWSCq (ORCPT ); Mon, 23 Feb 2015 13:02:46 -0500 Received: from bombadil.infradead.org ([198.137.202.9]:54321 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752333AbbBWSCp (ORCPT ); Mon, 23 Feb 2015 13:02:45 -0500 Received: from bombadil.infradead.org ([2001:1868:205::9] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.80.1 #2 (Red Hat Linux)) id 1YPxL3-0006NY-1M; Mon, 23 Feb 2015 18:02:37 +0000 From: Christoph Hellwig To: Al Viro Cc: Maxim Patlasov , Robert Baldyga , Michal Nazarewicz , Felipe Balbi , linux-aio@kvack.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 05/12] gadget/function/f_fs.c: switch to ->{read, write}_iter() Date: Mon, 23 Feb 2015 10:00:29 -0800 Message-Id: <1424714436-19371-6-git-send-email-hch@lst.de> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1424714436-19371-1-git-send-email-hch@lst.de> References: <1424714436-19371-1-git-send-email-hch@lst.de> X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Al Viro Signed-off-by: Al Viro --- drivers/usb/gadget/function/f_fs.c | 136 ++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 78 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 98610e4..175c995 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -864,38 +864,6 @@ error: return ret; } -static ssize_t -ffs_epfile_write(struct file *file, const char __user *buf, size_t len, - loff_t *ptr) -{ - struct ffs_io_data io_data; - struct iovec iov = {.iov_base = buf, .iov_len = len}; - - ENTER(); - - io_data.aio = false; - io_data.read = false; - iov_iter_init(&io_data.data, WRITE, &iov, 1, len); - - return ffs_epfile_io(file, &io_data); -} - -static ssize_t -ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr) -{ - struct ffs_io_data io_data; - struct iovec iov = {.iov_base = buf, .iov_len = len}; - - ENTER(); - - io_data.aio = false; - io_data.read = true; - io_data.to_free = NULL; - iov_iter_init(&io_data.data, READ, &iov, 1, len); - - return ffs_epfile_io(file, &io_data); -} - static int ffs_epfile_open(struct inode *inode, struct file *file) { @@ -932,72 +900,84 @@ static int ffs_aio_cancel(struct kiocb *kiocb) return value; } -static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb, - const struct iovec *iovec, - unsigned long nr_segs, loff_t loff) +static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from) { - struct ffs_io_data *io_data; + struct ffs_io_data io_data, *p = &io_data; ssize_t res; ENTER(); - io_data = kmalloc(sizeof(*io_data), GFP_KERNEL); - if (unlikely(!io_data)) - return -ENOMEM; + if (!is_sync_kiocb(kiocb)) { + p = kmalloc(sizeof(io_data), GFP_KERNEL); + if (unlikely(!p)) + return -ENOMEM; + p->aio = true; + } else { + p->aio = false; + } - io_data->aio = true; - io_data->read = false; - io_data->kiocb = kiocb; - iov_iter_init(&io_data->data, WRITE, iovec, nr_segs, kiocb->ki_nbytes); - io_data->mm = current->mm; + p->read = false; + p->kiocb = kiocb; + p->data = *from; + p->mm = current->mm; - kiocb->private = io_data; + kiocb->private = p; kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); - res = ffs_epfile_io(kiocb->ki_filp, io_data); - if (res != -EIOCBQUEUED) - kfree(io_data); + res = ffs_epfile_io(kiocb->ki_filp, p); + if (res == -EIOCBQUEUED) + return res; + if (p->aio) + kfree(p); + else + *from = p->data; return res; } -static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb, - const struct iovec *iovec, - unsigned long nr_segs, loff_t loff) +static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to) { - struct ffs_io_data *io_data; - struct iovec *iovec_copy; + struct ffs_io_data io_data, *p = &io_data; ssize_t res; ENTER(); - iovec_copy = kmalloc_array(nr_segs, sizeof(*iovec_copy), GFP_KERNEL); - if (unlikely(!iovec_copy)) - return -ENOMEM; - - memcpy(iovec_copy, iovec, sizeof(struct iovec)*nr_segs); - - io_data = kmalloc(sizeof(*io_data), GFP_KERNEL); - if (unlikely(!io_data)) { - kfree(iovec_copy); - return -ENOMEM; + if (!is_sync_kiocb(kiocb)) { + p = kmalloc(sizeof(io_data), GFP_KERNEL); + if (unlikely(!p)) + return -ENOMEM; + p->aio = true; + } else { + p->aio = false; } - io_data->aio = true; - io_data->read = true; - io_data->kiocb = kiocb; - io_data->to_free = iovec_copy; - iov_iter_init(&io_data->data, READ, iovec_copy, nr_segs, kiocb->ki_nbytes); - io_data->mm = current->mm; + p->read = true; + p->kiocb = kiocb; + if (p->aio) { + p->to_free = dup_iter(&p->data, to, GFP_KERNEL); + if (!p->to_free) { + kfree(p); + return -ENOMEM; + } + } else { + p->data = *to; + p->to_free = NULL; + } + p->mm = current->mm; - kiocb->private = io_data; + kiocb->private = p; kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); - res = ffs_epfile_io(kiocb->ki_filp, io_data); - if (res != -EIOCBQUEUED) { - kfree(io_data->to_free); - kfree(io_data); + res = ffs_epfile_io(kiocb->ki_filp, p); + if (res == -EIOCBQUEUED) + return res; + + if (p->aio) { + kfree(p->to_free); + kfree(p); + } else { + *to = p->data; } return res; } @@ -1079,10 +1059,10 @@ static const struct file_operations ffs_epfile_operations = { .llseek = no_llseek, .open = ffs_epfile_open, - .write = ffs_epfile_write, - .read = ffs_epfile_read, - .aio_write = ffs_epfile_aio_write, - .aio_read = ffs_epfile_aio_read, + .write = new_sync_write, + .read = new_sync_read, + .write_iter = ffs_epfile_write_iter, + .read_iter = ffs_epfile_read_iter, .release = ffs_epfile_release, .unlocked_ioctl = ffs_epfile_ioctl, };