Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp102506pxb; Wed, 20 Jan 2021 02:14:11 -0800 (PST) X-Google-Smtp-Source: ABdhPJy70/9TPls75H4Bh2WjpdG+3MDcKxY4c/VBY1ISvYDsW3j/2alnCwqiNNtqCDdx9U3J2qNL X-Received: by 2002:a05:6402:50c6:: with SMTP id h6mr6697066edb.117.1611137651305; Wed, 20 Jan 2021 02:14:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611137651; cv=none; d=google.com; s=arc-20160816; b=PfK2bfmg08bJXNYPKuT7coHZNk3E+xjZA0Ba5TNf2OjSjuIEarIyJULMGgsa/DyYJ4 n6IVjokTK+FyqfIlps8qm/t4dXaYDIalv/Oo6ml/B/ijw2QP6hqSwpz6ztLzivdSCr1F IdIsqMk1k6h62K8SUgbugCtPWHdExc5o4yOODnwwqAdyRohVyyEYw4ZuPYZIgBiZapzG ZoXEoXxVqaMXb/7Y3jAay0g0qjZxV3sue29pqPg232Apmhc3uqTn+5ovr301Py5q1MfB LU+mUbNoiGzrFOiaFca70F8wsq6OAdUvbYFRvhohDUl8D5qUy77ON4LgcK7tkPJCVjcp 9zHA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=QpKIHOu+0ftGyh0rhFMgW7Ru/eWQHtz/uPpaeBV+9Tg=; b=QkYwq8uVisBBmtbKadCRMzg5SCACVi2/MlqAhTm6zZa/9J4f3NXSi6DW8cf4wSaO4b 8mIKcIZdezJBcE1VAIqMNxw/GCNLZ2EIHzUnKEewTT2icvLSb8PHATbzOzd50/gcriz3 EcWkIZUYwiyV8qVM3ZZRGW9QX9Xm0lIGDIMgVPQxdcKhwNqMFn2pwQKa4XCOU6TapOcA qTOvqFlc4c6chgA581GBVWbzFtsnqfMNnPQYTcDdrSpxWXHmiA+mGyMp1b3mC0lsYHdC g/OmiJSmgEyfEiPKRptvLiAoLSqDa9BhN50IY6es/n/VbSzeuE+dinllh16PiPbjvL0c 9OXA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@infradead.org header.s=casper.20170209 header.b=uuP8R+x4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id t1si473635ejc.524.2021.01.20.02.13.21; Wed, 20 Jan 2021 02:14:11 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@infradead.org header.s=casper.20170209 header.b=uuP8R+x4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729747AbhATKHW (ORCPT + 99 others); Wed, 20 Jan 2021 05:07:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729019AbhATJLs (ORCPT ); Wed, 20 Jan 2021 04:11:48 -0500 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 678E7C061575; Wed, 20 Jan 2021 01:11:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=In-Reply-To:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=QpKIHOu+0ftGyh0rhFMgW7Ru/eWQHtz/uPpaeBV+9Tg=; b=uuP8R+x4VHRgBlkf3bLk7tDMe2 MCavNmul1/R+vwoa+wmZPHxDXOkNdMliMgjOaOI1JRkT21488icN8T2eVclGn+EgS1Q53VcE5JFZp TXe+O/s19ybSx0QQ4i5y6KgrEZOVroJIj9jAh0B5jS/IeeREfgqLFHy8qTTpzpKsbwMDgfzrX+K9S dpBNyyNBZiu/sxWj7ZULRQJDgCzxN2tkia97D65DwKGQrFu3Zutp5R3O3MsqwX8QiyLrzi7DxjuYk aekYthJ31GhcYz+1wUg4KDZZ7EkvGLTxNcuGXuakplMkkTJ5oPzL6VYpsJ4+jlUrYIEvVTJD0Me7U dvVr1T2Q==; Received: from hch by casper.infradead.org with local (Exim 4.94 #2 (Red Hat Linux)) id 1l29VZ-00FSSx-1e; Wed, 20 Jan 2021 09:10:36 +0000 Date: Wed, 20 Jan 2021 09:10:33 +0000 From: Christoph Hellwig To: Siddharth Gupta Cc: mcgrof@kernel.org, gregkh@linuxfoundation.org, rafael@kernel.org, viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org, Linux Kernel Mailing List , "psodagud@codeaurora.org" Subject: Re: PROBLEM: Firmware loader fallback mechanism no longer works with sendfile Message-ID: <20210120091033.GA3683647@infradead.org> References: <7e6f44b1-a0d2-d1d1-9c11-dcea163f8f03@codeaurora.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <7e6f44b1-a0d2-d1d1-9c11-dcea163f8f03@codeaurora.org> X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Can you give this patch a spin? diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index f277d023ebcd14..4b5833b3059f9c 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "kernfs-internal.h" @@ -180,11 +181,10 @@ static const struct seq_operations kernfs_seq_ops = { * it difficult to use seq_file. Implement simplistic custom buffering for * bin files. */ -static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, - char __user *user_buf, size_t count, - loff_t *ppos) +static ssize_t kernfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) { - ssize_t len = min_t(size_t, count, PAGE_SIZE); + struct kernfs_open_file *of = kernfs_of(iocb->ki_filp); + ssize_t len = min_t(size_t, iov_iter_count(iter), PAGE_SIZE); const struct kernfs_ops *ops; char *buf; @@ -210,7 +210,7 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, of->event = atomic_read(&of->kn->attr.open->event); ops = kernfs_ops(of->kn); if (ops->read) - len = ops->read(of, buf, len, *ppos); + len = ops->read(of, buf, len, iocb->ki_pos); else len = -EINVAL; @@ -220,12 +220,12 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, if (len < 0) goto out_free; - if (copy_to_user(user_buf, buf, len)) { + if (copy_to_iter(buf, len, iter) != len) { len = -EFAULT; goto out_free; } - *ppos += len; + iocb->ki_pos += len; out_free: if (buf == of->prealloc_buf) @@ -235,31 +235,14 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of, return len; } -/** - * kernfs_fop_read - kernfs vfs read callback - * @file: file pointer - * @user_buf: data to write - * @count: number of bytes - * @ppos: starting offset - */ -static ssize_t kernfs_fop_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t kernfs_fop_read_iter(struct kiocb *iocb, struct iov_iter *iter) { - struct kernfs_open_file *of = kernfs_of(file); - - if (of->kn->flags & KERNFS_HAS_SEQ_SHOW) - return seq_read(file, user_buf, count, ppos); - else - return kernfs_file_direct_read(of, user_buf, count, ppos); + if (kernfs_of(iocb->ki_filp)->kn->flags & KERNFS_HAS_SEQ_SHOW) + return seq_read_iter(iocb, iter); + return kernfs_file_read_iter(iocb, iter); } -/** - * kernfs_fop_write - kernfs vfs write callback - * @file: file pointer - * @user_buf: data to write - * @count: number of bytes - * @ppos: starting offset - * +/* * Copy data in from userland and pass it to the matching kernfs write * operation. * @@ -269,20 +252,18 @@ static ssize_t kernfs_fop_read(struct file *file, char __user *user_buf, * modify only the the value you're changing, then write entire buffer * back. */ -static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t kernfs_fop_write_iter(struct kiocb *iocb, struct iov_iter *iter) { - struct kernfs_open_file *of = kernfs_of(file); + struct kernfs_open_file *of = kernfs_of(iocb->ki_filp); + ssize_t len = iov_iter_count(iter); const struct kernfs_ops *ops; - ssize_t len; char *buf; if (of->atomic_write_len) { - len = count; if (len > of->atomic_write_len) return -E2BIG; } else { - len = min_t(size_t, count, PAGE_SIZE); + len = min_t(size_t, len, PAGE_SIZE); } buf = of->prealloc_buf; @@ -293,7 +274,7 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, if (!buf) return -ENOMEM; - if (copy_from_user(buf, user_buf, len)) { + if (copy_from_iter(buf, len, iter) != len) { len = -EFAULT; goto out_free; } @@ -312,7 +293,7 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, ops = kernfs_ops(of->kn); if (ops->write) - len = ops->write(of, buf, len, *ppos); + len = ops->write(of, buf, len, iocb->ki_pos); else len = -EINVAL; @@ -320,7 +301,7 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf, mutex_unlock(&of->mutex); if (len > 0) - *ppos += len; + iocb->ki_pos += len; out_free: if (buf == of->prealloc_buf) @@ -960,14 +941,16 @@ void kernfs_notify(struct kernfs_node *kn) EXPORT_SYMBOL_GPL(kernfs_notify); const struct file_operations kernfs_file_fops = { - .read = kernfs_fop_read, - .write = kernfs_fop_write, + .read_iter = kernfs_fop_read_iter, + .write_iter = kernfs_fop_write_iter, .llseek = generic_file_llseek, .mmap = kernfs_fop_mmap, .open = kernfs_fop_open, .release = kernfs_fop_release, .poll = kernfs_fop_poll, .fsync = noop_fsync, + .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, }; /**