All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Amir Goldstein <amir73il@gmail.com>,
	Christian Brauner <brauner@kernel.org>
Cc: Josef Bacik <josef@toxicpanda.com>,
	Christoph Hellwig <hch@lst.de>, Jan Kara <jack@suse.cz>,
	David Howells <dhowells@redhat.com>, Jens Axboe <axboe@kernel.dk>,
	 Miklos Szeredi <miklos@szeredi.hu>,
	Al Viro <viro@zeniv.linux.org.uk>,
	linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v2 1/3] fs: fork splice_file_range() from do_splice_direct()
Date: Thu, 30 Nov 2023 11:27:42 -0500	[thread overview]
Message-ID: <a0011d31ad58112a13a0cad5746095f508a3eb99.camel@kernel.org> (raw)
In-Reply-To: <20231130141624.3338942-2-amir73il@gmail.com>

On Thu, 2023-11-30 at 16:16 +0200, Amir Goldstein wrote:
> In preparation of calling do_splice_direct() without file_start_write()
> held, create a new helper splice_file_range(), to be called from context
> of ->copy_file_range() methods instead of do_splice_direct().
> 
> Currently, the only difference is that splice_file_range() does not take
> flags argument and that it asserts that file_start_write() is held, but
> we factor out a common helper do_splice_direct_actor() that will be used
> later.
> 
> Use the new helper from __ceph_copy_file_range(), that was incorrectly
> passing to do_splice_direct() the copy flags argument as splice flags.
> The value of copy flags in ceph is always 0, so it is a smenatic bug fix.
> 
> Move the declaration of both helpers to linux/splice.h.
> 
> Reviewed-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Amir Goldstein <amir73il@gmail.com>
> ---
>  fs/ceph/file.c         |  9 +++---
>  fs/read_write.c        |  6 ++--
>  fs/splice.c            | 71 ++++++++++++++++++++++++++++++------------
>  include/linux/fs.h     |  2 --
>  include/linux/splice.h | 13 +++++---
>  5 files changed, 66 insertions(+), 35 deletions(-)
> 
> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> index 3b5aae29e944..f11de6e1f1c1 100644
> --- a/fs/ceph/file.c
> +++ b/fs/ceph/file.c
> @@ -12,6 +12,7 @@
>  #include <linux/falloc.h>
>  #include <linux/iversion.h>
>  #include <linux/ktime.h>
> +#include <linux/splice.h>
>  
>  #include "super.h"
>  #include "mds_client.h"
> @@ -3010,8 +3011,8 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
>  		 * {read,write}_iter, which will get caps again.
>  		 */
>  		put_rd_wr_caps(src_ci, src_got, dst_ci, dst_got);
> -		ret = do_splice_direct(src_file, &src_off, dst_file,
> -				       &dst_off, src_objlen, flags);
> +		ret = splice_file_range(src_file, &src_off, dst_file, &dst_off,
> +					src_objlen);
>  		/* Abort on short copies or on error */
>  		if (ret < (long)src_objlen) {
>  			doutc(cl, "Failed partial copy (%zd)\n", ret);
> @@ -3065,8 +3066,8 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
>  	 */
>  	if (len && (len < src_ci->i_layout.object_size)) {
>  		doutc(cl, "Final partial copy of %zu bytes\n", len);
> -		bytes = do_splice_direct(src_file, &src_off, dst_file,
> -					 &dst_off, len, flags);
> +		bytes = splice_file_range(src_file, &src_off, dst_file,
> +					  &dst_off, len);
>  		if (bytes > 0)
>  			ret += bytes;
>  		else
> diff --git a/fs/read_write.c b/fs/read_write.c
> index f791555fa246..642c7ce1ced1 100644
> --- a/fs/read_write.c
> +++ b/fs/read_write.c
> @@ -1423,10 +1423,8 @@ ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in,
>  				struct file *file_out, loff_t pos_out,
>  				size_t len, unsigned int flags)
>  {
> -	lockdep_assert(file_write_started(file_out));
> -
> -	return do_splice_direct(file_in, &pos_in, file_out, &pos_out,
> -				len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0);
> +	return splice_file_range(file_in, &pos_in, file_out, &pos_out,
> +				 min_t(size_t, len, MAX_RW_COUNT));
>  }
>  EXPORT_SYMBOL(generic_copy_file_range);
>  
> diff --git a/fs/splice.c b/fs/splice.c
> index 3fce5f6072dd..9007b2c8baa8 100644
> --- a/fs/splice.c
> +++ b/fs/splice.c
> @@ -1170,25 +1170,10 @@ static void direct_file_splice_eof(struct splice_desc *sd)
>  		file->f_op->splice_eof(file);
>  }
>  
> -/**
> - * do_splice_direct - splices data directly between two files
> - * @in:		file to splice from
> - * @ppos:	input file offset
> - * @out:	file to splice to
> - * @opos:	output file offset
> - * @len:	number of bytes to splice
> - * @flags:	splice modifier flags
> - *
> - * Description:
> - *    For use by do_sendfile(). splice can easily emulate sendfile, but
> - *    doing it in the application would incur an extra system call
> - *    (splice in + splice out, as compared to just sendfile()). So this helper
> - *    can splice directly through a process-private pipe.
> - *
> - * Callers already called rw_verify_area() on the entire range.
> - */
> -long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
> -		      loff_t *opos, size_t len, unsigned int flags)
> +static long do_splice_direct_actor(struct file *in, loff_t *ppos,
> +				   struct file *out, loff_t *opos,
> +				   size_t len, unsigned int flags,
> +				   splice_direct_actor *actor)
>  {
>  	struct splice_desc sd = {
>  		.len		= len,
> @@ -1207,14 +1192,60 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
>  	if (unlikely(out->f_flags & O_APPEND))
>  		return -EINVAL;
>  
> -	ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
> +	ret = splice_direct_to_actor(in, &sd, actor);
>  	if (ret > 0)
>  		*ppos = sd.pos;
>  
>  	return ret;
>  }
> +/**
> + * do_splice_direct - splices data directly between two files
> + * @in:		file to splice from
> + * @ppos:	input file offset
> + * @out:	file to splice to
> + * @opos:	output file offset
> + * @len:	number of bytes to splice
> + * @flags:	splice modifier flags
> + *
> + * Description:
> + *    For use by do_sendfile(). splice can easily emulate sendfile, but
> + *    doing it in the application would incur an extra system call
> + *    (splice in + splice out, as compared to just sendfile()). So this helper
> + *    can splice directly through a process-private pipe.
> + *
> + * Callers already called rw_verify_area() on the entire range.
> + */
> +long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
> +		      loff_t *opos, size_t len, unsigned int flags)
> +{
> +	return do_splice_direct_actor(in, ppos, out, opos, len, flags,
> +				      direct_splice_actor);
> +}
>  EXPORT_SYMBOL(do_splice_direct);
>  
> +/**
> + * splice_file_range - splices data between two files for copy_file_range()
> + * @in:		file to splice from
> + * @ppos:	input file offset
> + * @out:	file to splice to
> + * @opos:	output file offset
> + * @len:	number of bytes to splice
> + *
> + * Description:
> + *    For use by generic_copy_file_range() and ->copy_file_range() methods.
> + *
> + * Callers already called rw_verify_area() on the entire range.
> + */
> +long splice_file_range(struct file *in, loff_t *ppos, struct file *out,
> +		       loff_t *opos, size_t len)
> +{
> +	lockdep_assert(file_write_started(out));
> +
> +	return do_splice_direct_actor(in, ppos, out, opos, len, 0,
> +				      direct_splice_actor);
> +}
> +EXPORT_SYMBOL(splice_file_range);
> +
>  static int wait_for_space(struct pipe_inode_info *pipe, unsigned flags)
>  {
>  	for (;;) {
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index ae0e2fb7bcea..04422a0eccdd 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -3052,8 +3052,6 @@ ssize_t copy_splice_read(struct file *in, loff_t *ppos,
>  			 size_t len, unsigned int flags);
>  extern ssize_t iter_file_splice_write(struct pipe_inode_info *,
>  		struct file *, loff_t *, size_t, unsigned int);
> -extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
> -		loff_t *opos, size_t len, unsigned int flags);
>  
>  
>  extern void
> diff --git a/include/linux/splice.h b/include/linux/splice.h
> index 6c461573434d..49532d5dda52 100644
> --- a/include/linux/splice.h
> +++ b/include/linux/splice.h
> @@ -80,11 +80,14 @@ extern ssize_t add_to_pipe(struct pipe_inode_info *,
>  long vfs_splice_read(struct file *in, loff_t *ppos,
>  		     struct pipe_inode_info *pipe, size_t len,
>  		     unsigned int flags);
> -extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
> -				      splice_direct_actor *);
> -extern long do_splice(struct file *in, loff_t *off_in,
> -		      struct file *out, loff_t *off_out,
> -		      size_t len, unsigned int flags);
> +ssize_t splice_direct_to_actor(struct file *file, struct splice_desc *sd,
> +			       splice_direct_actor *actor);
> +long do_splice(struct file *in, loff_t *off_in, struct file *out,
> +	       loff_t *off_out, size_t len, unsigned int flags);
> +long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
> +		      loff_t *opos, size_t len, unsigned int flags);
> +long splice_file_range(struct file *in, loff_t *ppos, struct file *out,
> +		       loff_t *opos, size_t len);
>  
>  extern long do_tee(struct file *in, struct file *out, size_t len,
>  		   unsigned int flags);

Looks OK to me:

Acked-by: Jeff Layton <jlayton@kernel.org>

  reply	other threads:[~2023-11-30 16:27 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-30 14:16 [PATCH v2 0/3] Avert possible deadlock with splice() and fanotify Amir Goldstein
2023-11-30 14:16 ` [PATCH v2 1/3] fs: fork splice_file_range() from do_splice_direct() Amir Goldstein
2023-11-30 16:27   ` Jeff Layton [this message]
2023-12-04  8:37   ` Christoph Hellwig
2023-12-04  8:38     ` Christoph Hellwig
2023-12-04 13:29       ` Amir Goldstein
2023-12-04 14:07         ` Christoph Hellwig
2023-12-04 14:29           ` Amir Goldstein
2023-12-04 17:16             ` Jan Kara
2023-12-04 18:53               ` Amir Goldstein
2023-11-30 14:16 ` [PATCH v2 2/3] fs: move file_start_write() into direct_splice_actor() Amir Goldstein
2023-12-04  8:38   ` Christoph Hellwig
2023-11-30 14:16 ` [PATCH v2 3/3] fs: use do_splice_direct() for nfsd/ksmbd server-side-copy Amir Goldstein
2023-11-30 16:49   ` Jan Kara
2023-12-04  8:39   ` Christoph Hellwig
2023-12-04 13:19     ` Amir Goldstein
2023-12-04 14:02       ` Christoph Hellwig
2023-12-05  0:16   ` [PATCH] fs: read_write: make default in vfs_copy_file_range() reachable Bert Karwatzki
2023-12-05  3:45     ` Amir Goldstein
2023-12-05  5:01       ` Amir Goldstein
2023-12-05  9:50         ` Bert Karwatzki
2023-11-30 16:32 ` [PATCH v2 0/3] Avert possible deadlock with splice() and fanotify Jeff Layton
2023-12-01 10:40 ` Christian Brauner

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=a0011d31ad58112a13a0cad5746095f508a3eb99.camel@kernel.org \
    --to=jlayton@kernel.org \
    --cc=amir73il@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=brauner@kernel.org \
    --cc=dhowells@redhat.com \
    --cc=hch@lst.de \
    --cc=jack@suse.cz \
    --cc=josef@toxicpanda.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --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.