All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Namjae Jeon <linkinjeon@kernel.org>,
	Luis Henriques <lhenriques@suse.de>,
	Amir Goldstein <amir73il@gmail.com>,
	Al Viro <viro@zeniv.linux.org.uk>
Subject: [PATCH 5.10 03/15] vfs: fix copy_file_range() averts filesystem freeze protection
Date: Thu, 15 Dec 2022 19:10:30 +0100	[thread overview]
Message-ID: <20221215172907.159249413@linuxfoundation.org> (raw)
In-Reply-To: <20221215172906.638553794@linuxfoundation.org>

From: Amir Goldstein <amir73il@gmail.com>

commit 10bc8e4af65946b727728d7479c028742321b60a upstream.

[backport comments for pre v5.15:
- ksmbd mentions are irrelevant - ksmbd hunks were dropped
- sb_write_started() is missing - assert was dropped
]

Commit 868f9f2f8e00 ("vfs: fix copy_file_range() regression in cross-fs
copies") removed fallback to generic_copy_file_range() for cross-fs
cases inside vfs_copy_file_range().

To preserve behavior of nfsd and ksmbd server-side-copy, the fallback to
generic_copy_file_range() was added in nfsd and ksmbd code, but that
call is missing sb_start_write(), fsnotify hooks and more.

Ideally, nfsd and ksmbd would pass a flag to vfs_copy_file_range() that
will take care of the fallback, but that code would be subtle and we got
vfs_copy_file_range() logic wrong too many times already.

Instead, add a flag to explicitly request vfs_copy_file_range() to
perform only generic_copy_file_range() and let nfsd and ksmbd use this
flag only in the fallback path.

This choise keeps the logic changes to minimum in the non-nfsd/ksmbd code
paths to reduce the risk of further regressions.

Fixes: 868f9f2f8e00 ("vfs: fix copy_file_range() regression in cross-fs copies")
Tested-by: Namjae Jeon <linkinjeon@kernel.org>
Tested-by: Luis Henriques <lhenriques@suse.de>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/nfsd/vfs.c      |    4 ++--
 fs/read_write.c    |   17 +++++++++++++----
 include/linux/fs.h |    8 ++++++++
 3 files changed, 23 insertions(+), 6 deletions(-)

--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -584,8 +584,8 @@ ssize_t nfsd_copy_file_range(struct file
 	ret = vfs_copy_file_range(src, src_pos, dst, dst_pos, count, 0);
 
 	if (ret == -EOPNOTSUPP || ret == -EXDEV)
-		ret = generic_copy_file_range(src, src_pos, dst, dst_pos,
-					      count, 0);
+		ret = vfs_copy_file_range(src, src_pos, dst, dst_pos, count,
+					  COPY_FILE_SPLICE);
 	return ret;
 }
 
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1419,7 +1419,9 @@ static int generic_copy_file_checks(stru
 	 * and several different sets of file_operations, but they all end up
 	 * using the same ->copy_file_range() function pointer.
 	 */
-	if (file_out->f_op->copy_file_range) {
+	if (flags & COPY_FILE_SPLICE) {
+		/* cross sb splice is allowed */
+	} else if (file_out->f_op->copy_file_range) {
 		if (file_in->f_op->copy_file_range !=
 		    file_out->f_op->copy_file_range)
 			return -EXDEV;
@@ -1469,8 +1471,9 @@ ssize_t vfs_copy_file_range(struct file
 			    size_t len, unsigned int flags)
 {
 	ssize_t ret;
+	bool splice = flags & COPY_FILE_SPLICE;
 
-	if (flags != 0)
+	if (flags & ~COPY_FILE_SPLICE)
 		return -EINVAL;
 
 	ret = generic_copy_file_checks(file_in, pos_in, file_out, pos_out, &len,
@@ -1496,14 +1499,14 @@ ssize_t vfs_copy_file_range(struct file
 	 * same sb using clone, but for filesystems where both clone and copy
 	 * are supported (e.g. nfs,cifs), we only call the copy method.
 	 */
-	if (file_out->f_op->copy_file_range) {
+	if (!splice && file_out->f_op->copy_file_range) {
 		ret = file_out->f_op->copy_file_range(file_in, pos_in,
 						      file_out, pos_out,
 						      len, flags);
 		goto done;
 	}
 
-	if (file_in->f_op->remap_file_range &&
+	if (!splice && file_in->f_op->remap_file_range &&
 	    file_inode(file_in)->i_sb == file_inode(file_out)->i_sb) {
 		ret = file_in->f_op->remap_file_range(file_in, pos_in,
 				file_out, pos_out,
@@ -1523,6 +1526,8 @@ ssize_t vfs_copy_file_range(struct file
 	 * consistent story about which filesystems support copy_file_range()
 	 * and which filesystems do not, that will allow userspace tools to
 	 * make consistent desicions w.r.t using copy_file_range().
+	 *
+	 * We also get here if caller (e.g. nfsd) requested COPY_FILE_SPLICE.
 	 */
 	ret = generic_copy_file_range(file_in, pos_in, file_out, pos_out, len,
 				      flags);
@@ -1577,6 +1582,10 @@ SYSCALL_DEFINE6(copy_file_range, int, fd
 		pos_out = f_out.file->f_pos;
 	}
 
+	ret = -EINVAL;
+	if (flags != 0)
+		goto out;
+
 	ret = vfs_copy_file_range(f_in.file, pos_in, f_out.file, pos_out, len,
 				  flags);
 	if (ret > 0) {
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1817,6 +1817,14 @@ struct dir_context {
  */
 #define REMAP_FILE_ADVISORY		(REMAP_FILE_CAN_SHORTEN)
 
+/*
+ * These flags control the behavior of vfs_copy_file_range().
+ * They are not available to the user via syscall.
+ *
+ * COPY_FILE_SPLICE: call splice direct instead of fs clone/copy ops
+ */
+#define COPY_FILE_SPLICE		(1 << 0)
+
 struct iov_iter;
 
 struct file_operations {



  parent reply	other threads:[~2022-12-15 18:11 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-15 18:10 [PATCH 5.10 00/15] 5.10.160-rc1 review Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 01/15] x86/smpboot: Move rcu_cpu_starting() earlier Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 02/15] vfs: fix copy_file_range() regression in cross-fs copies Greg Kroah-Hartman
2022-12-15 18:10 ` Greg Kroah-Hartman [this message]
2022-12-15 18:10 ` [PATCH 5.10 04/15] nfp: fix use-after-free in area_cache_get() Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 05/15] fuse: always revalidate if exclusive create Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 06/15] io_uring: add missing item types for splice request Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 07/15] ASoC: fsl_micfil: explicitly clear software reset bit Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 08/15] ASoC: fsl_micfil: explicitly clear CHnF flags Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 09/15] ASoC: ops: Check bounds for second channel in snd_soc_put_volsw_sx() Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 10/15] libbpf: Use page size as max_entries when probing ring buffer map Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 11/15] pinctrl: meditatek: Startup with the IRQs disabled Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 12/15] can: sja1000: fix size of OCR_MODE_MASK define Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 13/15] can: mcba_usb: Fix termination command argument Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 14/15] ASoC: cs42l51: Correct PGA Volume minimum value Greg Kroah-Hartman
2022-12-15 18:10 ` [PATCH 5.10 15/15] nvme-pci: clear the prp2 field when not used Greg Kroah-Hartman
2022-12-15 21:40 ` [PATCH 5.10 00/15] 5.10.160-rc1 review Pavel Machek
2022-12-15 23:50 ` Shuah Khan
2022-12-16 10:02 ` Rudi Heitbaum
2022-12-16 10:21 ` Allen Pais
2022-12-16 11:27 ` Naresh Kamboju
2022-12-16 13:04 ` Jon Hunter
2022-12-16 13:12 ` Sudip Mukherjee (Codethink)
2022-12-16 19:29 ` Florian Fainelli
2022-12-16 21:30 ` Guenter Roeck
2022-12-18  7:06 ` zhouzhixiu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221215172907.159249413@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=amir73il@gmail.com \
    --cc=lhenriques@suse.de \
    --cc=linkinjeon@kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.