Commit 3eccc0c8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-6.5/splice-2023-06-23' of git://git.kernel.dk/linux

Pull splice updates from Jens Axboe:
 "This kills off ITER_PIPE to avoid a race between truncate,
  iov_iter_revert() on the pipe and an as-yet incomplete DMA to a bio
  with unpinned/unref'ed pages from an O_DIRECT splice read. This causes
  memory corruption.

  Instead, we either use (a) filemap_splice_read(), which invokes the
  buffered file reading code and splices from the pagecache into the
  pipe; (b) copy_splice_read(), which bulk-allocates a buffer, reads
  into it and then pushes the filled pages into the pipe; or (c) handle
  it in filesystem-specific code.

  Summary:

   - Rename direct_splice_read() to copy_splice_read()

   - Simplify the calculations for the number of pages to be reclaimed
     in copy_splice_read()

   - Turn do_splice_to() into a helper, vfs_splice_read(), so that it
     can be used by overlayfs and coda to perform the checks on the
     lower fs

   - Make vfs_splice_read() jump to copy_splice_read() to handle
     direct-I/O and DAX

   - Provide shmem with its own splice_read to handle non-existent pages
     in the pagecache. We don't want a ->read_folio() as we don't want
     to populate holes, but filemap_get_pages() requires it

   - Provide overlayfs with its own splice_read to call down to a lower
     layer as overlayfs doesn't provide ->read_folio()

   - Provide coda with its own splice_read to call down to a lower layer
     as coda doesn't provide ->read_folio()

   - Direct ->splice_read to copy_splice_read() in tty, procfs, kernfs
     and random files as they just copy to the output buffer and don't
     splice pages

   - Provide wrappers for afs, ceph, ecryptfs, ext4, f2fs, nfs, ntfs3,
     ocfs2, orangefs, xfs and zonefs to do locking and/or revalidation

   - Make cifs use filemap_splice_read()

   - Replace pointers to generic_file_splice_read() with pointers to
     filemap_splice_read() as DIO and DAX are handled in the caller;
     filesystems can still provide their own alternate ->splice_read()
     op

   - Remove generic_file_splice_read()

   - Remove ITER_PIPE and its paraphernalia as generic_file_splice_read
     was the only user"

* tag 'for-6.5/splice-2023-06-23' of git://git.kernel.dk/linux: (31 commits)
  splice: kdoc for filemap_splice_read() and copy_splice_read()
  iov_iter: Kill ITER_PIPE
  splice: Remove generic_file_splice_read()
  splice: Use filemap_splice_read() instead of generic_file_splice_read()
  cifs: Use filemap_splice_read()
  trace: Convert trace/seq to use copy_splice_read()
  zonefs: Provide a splice-read wrapper
  xfs: Provide a splice-read wrapper
  orangefs: Provide a splice-read wrapper
  ocfs2: Provide a splice-read wrapper
  ntfs3: Provide a splice-read wrapper
  nfs: Provide a splice-read wrapper
  f2fs: Provide a splice-read wrapper
  ext4: Provide a splice-read wrapper
  ecryptfs: Provide a splice-read wrapper
  ceph: Provide a splice-read wrapper
  afs: Provide a splice-read wrapper
  9p: Add splice_read wrapper
  net: Make sock_splice_read() use copy_splice_read() by default
  tty, proc, kernfs, random: Use copy_splice_read()
  ...
parents cc423f63 9eee8bd8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -701,7 +701,7 @@ const struct file_operations def_blk_fops = {
#ifdef CONFIG_COMPAT
	.compat_ioctl	= compat_blkdev_ioctl,
#endif
	.splice_read	= generic_file_splice_read,
	.splice_read	= filemap_splice_read,
	.splice_write	= iter_file_splice_write,
	.fallocate	= blkdev_fallocate,
};
+2 −2
Original line number Diff line number Diff line
@@ -1546,7 +1546,7 @@ const struct file_operations random_fops = {
	.compat_ioctl = compat_ptr_ioctl,
	.fasync = random_fasync,
	.llseek = noop_llseek,
	.splice_read = generic_file_splice_read,
	.splice_read = copy_splice_read,
	.splice_write = iter_file_splice_write,
};

@@ -1557,7 +1557,7 @@ const struct file_operations urandom_fops = {
	.compat_ioctl = compat_ptr_ioctl,
	.fasync = random_fasync,
	.llseek = noop_llseek,
	.splice_read = generic_file_splice_read,
	.splice_read = copy_splice_read,
	.splice_write = iter_file_splice_write,
};

+2 −2
Original line number Diff line number Diff line
@@ -466,7 +466,7 @@ static const struct file_operations tty_fops = {
	.llseek		= no_llseek,
	.read_iter	= tty_read,
	.write_iter	= tty_write,
	.splice_read	= generic_file_splice_read,
	.splice_read	= copy_splice_read,
	.splice_write	= iter_file_splice_write,
	.poll		= tty_poll,
	.unlocked_ioctl	= tty_ioctl,
@@ -481,7 +481,7 @@ static const struct file_operations console_fops = {
	.llseek		= no_llseek,
	.read_iter	= tty_read,
	.write_iter	= redirected_tty_write,
	.splice_read	= generic_file_splice_read,
	.splice_read	= copy_splice_read,
	.splice_write	= iter_file_splice_write,
	.poll		= tty_poll,
	.unlocked_ioctl	= tty_ioctl,
+24 −2
Original line number Diff line number Diff line
@@ -374,6 +374,28 @@ v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
	return ret;
}

/*
 * v9fs_file_splice_read - splice-read from a file
 * @in: The 9p file to read from
 * @ppos: Where to find/update the file position
 * @pipe: The pipe to splice into
 * @len: The maximum amount of data to splice
 * @flags: SPLICE_F_* flags
 */
static ssize_t v9fs_file_splice_read(struct file *in, loff_t *ppos,
				     struct pipe_inode_info *pipe,
				     size_t len, unsigned int flags)
{
	struct p9_fid *fid = in->private_data;

	p9_debug(P9_DEBUG_VFS, "fid %d count %zu offset %lld\n",
		 fid->fid, len, *ppos);

	if (fid->mode & P9L_DIRECT)
		return copy_splice_read(in, ppos, pipe, len, flags);
	return filemap_splice_read(in, ppos, pipe, len, flags);
}

/**
 * v9fs_file_write_iter - write to a file
 * @iocb: The operation parameters
@@ -569,7 +591,7 @@ const struct file_operations v9fs_file_operations = {
	.release = v9fs_dir_release,
	.lock = v9fs_file_lock,
	.mmap = generic_file_readonly_mmap,
	.splice_read = generic_file_splice_read,
	.splice_read = v9fs_file_splice_read,
	.splice_write = iter_file_splice_write,
	.fsync = v9fs_file_fsync,
};
@@ -583,7 +605,7 @@ const struct file_operations v9fs_file_operations_dotl = {
	.lock = v9fs_file_lock_dotl,
	.flock = v9fs_file_flock_dotl,
	.mmap = v9fs_file_mmap,
	.splice_read = generic_file_splice_read,
	.splice_read = v9fs_file_splice_read,
	.splice_write = iter_file_splice_write,
	.fsync = v9fs_file_fsync_dotl,
};
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ const struct file_operations adfs_file_operations = {
	.mmap		= generic_file_mmap,
	.fsync		= generic_file_fsync,
	.write_iter	= generic_file_write_iter,
	.splice_read	= generic_file_splice_read,
	.splice_read	= filemap_splice_read,
};

const struct inode_operations adfs_file_inode_operations = {
Loading