diff mbox series

[v2] backing-file: clean up the API

Message ID 20241021103340.260731-1-mszeredi@redhat.com (mailing list archive)
State New
Headers show
Series [v2] backing-file: clean up the API | expand

Commit Message

Miklos Szeredi Oct. 21, 2024, 10:33 a.m. UTC
- Pass iocb to ctx->end_write() instead of file + pos

 - Get rid of ctx->user_file, which is redundant most of the time

 - Instead pass iocb to backing_file_splice_read and
   backing_file_splice_write

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
---
v2:
    Pass ioctb to backing_file_splice_{read|write}()

Applies on fuse.git#for-next.

 fs/backing-file.c            | 33 ++++++++++++++++-----------------
 fs/fuse/passthrough.c        | 32 ++++++++++++++++++--------------
 fs/overlayfs/file.c          | 22 +++++++++++++---------
 include/linux/backing-file.h | 11 +++++------
 4 files changed, 52 insertions(+), 46 deletions(-)

Comments

Amir Goldstein Oct. 21, 2024, 11:58 a.m. UTC | #1
On Mon, Oct 21, 2024 at 12:33 PM Miklos Szeredi <mszeredi@redhat.com> wrote:
>
>  - Pass iocb to ctx->end_write() instead of file + pos
>
>  - Get rid of ctx->user_file, which is redundant most of the time
>
>  - Instead pass iocb to backing_file_splice_read and
>    backing_file_splice_write
>
> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> ---
> v2:
>     Pass ioctb to backing_file_splice_{read|write}()
>
> Applies on fuse.git#for-next.

This looks good to me.
you may add
Reviewed-by: Amir Goldstein <amir73il@gmail.com>

However, this conflicts with ovl_real_file() changes on overlayfs-next
AND on the fixes in fuse.git#for-next, so we will need to collaborate.

Were you planning to send the fuse fixes for the 6.12 cycle?
If so, I could rebase overlayfs-next over 6.12-rcX after fuse fixes
are merged and then apply your patch to overlayfs-next and resolve conflicts.

Thanks,
Amir.


>
>  fs/backing-file.c            | 33 ++++++++++++++++-----------------
>  fs/fuse/passthrough.c        | 32 ++++++++++++++++++--------------
>  fs/overlayfs/file.c          | 22 +++++++++++++---------
>  include/linux/backing-file.h | 11 +++++------
>  4 files changed, 52 insertions(+), 46 deletions(-)
>
> diff --git a/fs/backing-file.c b/fs/backing-file.c
> index 09a9be945d45..a38737592ec7 100644
> --- a/fs/backing-file.c
> +++ b/fs/backing-file.c
> @@ -80,7 +80,7 @@ struct backing_aio {
>         refcount_t ref;
>         struct kiocb *orig_iocb;
>         /* used for aio completion */
> -       void (*end_write)(struct file *, loff_t, ssize_t);
> +       void (*end_write)(struct kiocb *iocb, ssize_t);
>         struct work_struct work;
>         long res;
>  };
> @@ -108,10 +108,10 @@ static void backing_aio_cleanup(struct backing_aio *aio, long res)
>         struct kiocb *iocb = &aio->iocb;
>         struct kiocb *orig_iocb = aio->orig_iocb;
>
> +       orig_iocb->ki_pos = iocb->ki_pos;
>         if (aio->end_write)
> -               aio->end_write(orig_iocb->ki_filp, iocb->ki_pos, res);
> +               aio->end_write(orig_iocb, res);
>
> -       orig_iocb->ki_pos = iocb->ki_pos;
>         backing_aio_put(aio);
>  }
>
> @@ -200,7 +200,7 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
>         revert_creds(old_cred);
>
>         if (ctx->accessed)
> -               ctx->accessed(ctx->user_file);
> +               ctx->accessed(iocb->ki_filp);
>
>         return ret;
>  }
> @@ -219,7 +219,7 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
>         if (!iov_iter_count(iter))
>                 return 0;
>
> -       ret = file_remove_privs(ctx->user_file);
> +       ret = file_remove_privs(iocb->ki_filp);
>         if (ret)
>                 return ret;
>
> @@ -239,7 +239,7 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
>
>                 ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf);
>                 if (ctx->end_write)
> -                       ctx->end_write(ctx->user_file, iocb->ki_pos, ret);
> +                       ctx->end_write(iocb, ret);
>         } else {
>                 struct backing_aio *aio;
>
> @@ -270,7 +270,7 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
>  }
>  EXPORT_SYMBOL_GPL(backing_file_write_iter);
>
> -ssize_t backing_file_splice_read(struct file *in, loff_t *ppos,
> +ssize_t backing_file_splice_read(struct file *in, struct kiocb *iocb,
>                                  struct pipe_inode_info *pipe, size_t len,
>                                  unsigned int flags,
>                                  struct backing_file_ctx *ctx)
> @@ -282,19 +282,19 @@ ssize_t backing_file_splice_read(struct file *in, loff_t *ppos,
>                 return -EIO;
>
>         old_cred = override_creds(ctx->cred);
> -       ret = vfs_splice_read(in, ppos, pipe, len, flags);
> +       ret = vfs_splice_read(in, &iocb->ki_pos, pipe, len, flags);
>         revert_creds(old_cred);
>
>         if (ctx->accessed)
> -               ctx->accessed(ctx->user_file);
> +               ctx->accessed(iocb->ki_filp);
>
>         return ret;
>  }
>  EXPORT_SYMBOL_GPL(backing_file_splice_read);
>
>  ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
> -                                 struct file *out, loff_t *ppos, size_t len,
> -                                 unsigned int flags,
> +                                 struct file *out, struct kiocb *iocb,
> +                                 size_t len, unsigned int flags,
>                                   struct backing_file_ctx *ctx)
>  {
>         const struct cred *old_cred;
> @@ -306,18 +306,18 @@ ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
>         if (!out->f_op->splice_write)
>                 return -EINVAL;
>
> -       ret = file_remove_privs(ctx->user_file);
> +       ret = file_remove_privs(iocb->ki_filp);
>         if (ret)
>                 return ret;
>
>         old_cred = override_creds(ctx->cred);
>         file_start_write(out);
> -       ret = out->f_op->splice_write(pipe, out, ppos, len, flags);
> +       ret = out->f_op->splice_write(pipe, out, &iocb->ki_pos, len, flags);
>         file_end_write(out);
>         revert_creds(old_cred);
>
>         if (ctx->end_write)
> -               ctx->end_write(ctx->user_file, ppos ? *ppos : 0, ret);
> +               ctx->end_write(iocb, ret);
>
>         return ret;
>  }
> @@ -329,8 +329,7 @@ int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
>         const struct cred *old_cred;
>         int ret;
>
> -       if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)) ||
> -           WARN_ON_ONCE(ctx->user_file != vma->vm_file))
> +       if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)))
>                 return -EIO;
>
>         if (!file->f_op->mmap)
> @@ -343,7 +342,7 @@ int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
>         revert_creds(old_cred);
>
>         if (ctx->accessed)
> -               ctx->accessed(ctx->user_file);
> +               ctx->accessed(vma->vm_file);
>
>         return ret;
>  }
> diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c
> index bbac547dfcb3..607ef735ad4a 100644
> --- a/fs/fuse/passthrough.c
> +++ b/fs/fuse/passthrough.c
> @@ -18,11 +18,11 @@ static void fuse_file_accessed(struct file *file)
>         fuse_invalidate_atime(inode);
>  }
>
> -static void fuse_passthrough_end_write(struct file *file, loff_t pos, ssize_t ret)
> +static void fuse_passthrough_end_write(struct kiocb *iocb, ssize_t ret)
>  {
> -       struct inode *inode = file_inode(file);
> +       struct inode *inode = file_inode(iocb->ki_filp);
>
> -       fuse_write_update_attr(inode, pos, ret);
> +       fuse_write_update_attr(inode, iocb->ki_pos, ret);
>  }
>
>  ssize_t fuse_passthrough_read_iter(struct kiocb *iocb, struct iov_iter *iter)
> @@ -34,7 +34,6 @@ ssize_t fuse_passthrough_read_iter(struct kiocb *iocb, struct iov_iter *iter)
>         ssize_t ret;
>         struct backing_file_ctx ctx = {
>                 .cred = ff->cred,
> -               .user_file = file,
>                 .accessed = fuse_file_accessed,
>         };
>
> @@ -62,7 +61,6 @@ ssize_t fuse_passthrough_write_iter(struct kiocb *iocb,
>         ssize_t ret;
>         struct backing_file_ctx ctx = {
>                 .cred = ff->cred,
> -               .user_file = file,
>                 .end_write = fuse_passthrough_end_write,
>         };
>
> @@ -88,15 +86,20 @@ ssize_t fuse_passthrough_splice_read(struct file *in, loff_t *ppos,
>         struct file *backing_file = fuse_file_passthrough(ff);
>         struct backing_file_ctx ctx = {
>                 .cred = ff->cred,
> -               .user_file = in,
>                 .accessed = fuse_file_accessed,
>         };
> +       struct kiocb iocb;
> +       ssize_t ret;
>
>         pr_debug("%s: backing_file=0x%p, pos=%lld, len=%zu, flags=0x%x\n", __func__,
> -                backing_file, ppos ? *ppos : 0, len, flags);
> +                backing_file, *ppos, len, flags);
>
> -       return backing_file_splice_read(backing_file, ppos, pipe, len, flags,
> -                                       &ctx);
> +       init_sync_kiocb(&iocb, in);
> +       iocb.ki_pos = *ppos;
> +       ret = backing_file_splice_read(backing_file, &iocb, pipe, len, flags, &ctx);
> +       *ppos = iocb.ki_pos;
> +
> +       return ret;
>  }
>
>  ssize_t fuse_passthrough_splice_write(struct pipe_inode_info *pipe,
> @@ -109,16 +112,18 @@ ssize_t fuse_passthrough_splice_write(struct pipe_inode_info *pipe,
>         ssize_t ret;
>         struct backing_file_ctx ctx = {
>                 .cred = ff->cred,
> -               .user_file = out,
>                 .end_write = fuse_passthrough_end_write,
>         };
> +       struct kiocb iocb;
>
>         pr_debug("%s: backing_file=0x%p, pos=%lld, len=%zu, flags=0x%x\n", __func__,
> -                backing_file, ppos ? *ppos : 0, len, flags);
> +                backing_file, *ppos, len, flags);
>
>         inode_lock(inode);
> -       ret = backing_file_splice_write(pipe, backing_file, ppos, len, flags,
> -                                       &ctx);
> +       init_sync_kiocb(&iocb, out);
> +       iocb.ki_pos = *ppos;
> +       ret = backing_file_splice_write(pipe, backing_file, &iocb, len, flags, &ctx);
> +       *ppos = iocb.ki_pos;
>         inode_unlock(inode);
>
>         return ret;
> @@ -130,7 +135,6 @@ ssize_t fuse_passthrough_mmap(struct file *file, struct vm_area_struct *vma)
>         struct file *backing_file = fuse_file_passthrough(ff);
>         struct backing_file_ctx ctx = {
>                 .cred = ff->cred,
> -               .user_file = file,
>                 .accessed = fuse_file_accessed,
>         };
>
> diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
> index 4444c78e2e0c..12c4d502ff91 100644
> --- a/fs/overlayfs/file.c
> +++ b/fs/overlayfs/file.c
> @@ -231,9 +231,9 @@ static void ovl_file_modified(struct file *file)
>         ovl_copyattr(file_inode(file));
>  }
>
> -static void ovl_file_end_write(struct file *file, loff_t pos, ssize_t ret)
> +static void ovl_file_end_write(struct kiocb *iocb, ssize_t ret)
>  {
> -       ovl_file_modified(file);
> +       ovl_file_modified(iocb->ki_filp);
>  }
>
>  static void ovl_file_accessed(struct file *file)
> @@ -271,7 +271,6 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
>         ssize_t ret;
>         struct backing_file_ctx ctx = {
>                 .cred = ovl_creds(file_inode(file)->i_sb),
> -               .user_file = file,
>                 .accessed = ovl_file_accessed,
>         };
>
> @@ -298,7 +297,6 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
>         int ifl = iocb->ki_flags;
>         struct backing_file_ctx ctx = {
>                 .cred = ovl_creds(inode->i_sb),
> -               .user_file = file,
>                 .end_write = ovl_file_end_write,
>         };
>
> @@ -338,15 +336,18 @@ static ssize_t ovl_splice_read(struct file *in, loff_t *ppos,
>         ssize_t ret;
>         struct backing_file_ctx ctx = {
>                 .cred = ovl_creds(file_inode(in)->i_sb),
> -               .user_file = in,
>                 .accessed = ovl_file_accessed,
>         };
> +       struct kiocb iocb;
>
>         ret = ovl_real_fdget(in, &real);
>         if (ret)
>                 return ret;
>
> -       ret = backing_file_splice_read(fd_file(real), ppos, pipe, len, flags, &ctx);
> +       init_sync_kiocb(&iocb, in);
> +       iocb.ki_pos = *ppos;
> +       ret = backing_file_splice_read(fd_file(real), &iocb, pipe, len, flags, &ctx);
> +       *ppos = iocb.ki_pos;
>         fdput(real);
>
>         return ret;
> @@ -368,9 +369,9 @@ static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
>         ssize_t ret;
>         struct backing_file_ctx ctx = {
>                 .cred = ovl_creds(inode->i_sb),
> -               .user_file = out,
>                 .end_write = ovl_file_end_write,
>         };
> +       struct kiocb iocb;
>
>         inode_lock(inode);
>         /* Update mode */
> @@ -380,9 +381,13 @@ static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
>         if (ret)
>                 goto out_unlock;
>
> -       ret = backing_file_splice_write(pipe, fd_file(real), ppos, len, flags, &ctx);
> +       init_sync_kiocb(&iocb, out);
> +       iocb.ki_pos = *ppos;
> +       ret = backing_file_splice_write(pipe, fd_file(real), &iocb, len, flags, &ctx);
> +       *ppos = iocb.ki_pos;
>         fdput(real);
>
> +
>  out_unlock:
>         inode_unlock(inode);
>
> @@ -420,7 +425,6 @@ static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
>         struct file *realfile = file->private_data;
>         struct backing_file_ctx ctx = {
>                 .cred = ovl_creds(file_inode(file)->i_sb),
> -               .user_file = file,
>                 .accessed = ovl_file_accessed,
>         };
>
> diff --git a/include/linux/backing-file.h b/include/linux/backing-file.h
> index 2eed0ffb5e8f..1476a6ed1bfd 100644
> --- a/include/linux/backing-file.h
> +++ b/include/linux/backing-file.h
> @@ -14,9 +14,8 @@
>
>  struct backing_file_ctx {
>         const struct cred *cred;
> -       struct file *user_file;
> -       void (*accessed)(struct file *);
> -       void (*end_write)(struct file *, loff_t, ssize_t);
> +       void (*accessed)(struct file *file);
> +       void (*end_write)(struct kiocb *iocb, ssize_t);
>  };
>
>  struct file *backing_file_open(const struct path *user_path, int flags,
> @@ -31,13 +30,13 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
>  ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
>                                 struct kiocb *iocb, int flags,
>                                 struct backing_file_ctx *ctx);
> -ssize_t backing_file_splice_read(struct file *in, loff_t *ppos,
> +ssize_t backing_file_splice_read(struct file *in, struct kiocb *iocb,
>                                  struct pipe_inode_info *pipe, size_t len,
>                                  unsigned int flags,
>                                  struct backing_file_ctx *ctx);
>  ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
> -                                 struct file *out, loff_t *ppos, size_t len,
> -                                 unsigned int flags,
> +                                 struct file *out, struct kiocb *iocb,
> +                                 size_t len, unsigned int flags,
>                                   struct backing_file_ctx *ctx);
>  int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
>                       struct backing_file_ctx *ctx);
> --
> 2.47.0
>
Christian Brauner Oct. 21, 2024, 12:22 p.m. UTC | #2
On Mon, Oct 21, 2024 at 01:58:16PM +0200, Amir Goldstein wrote:
> On Mon, Oct 21, 2024 at 12:33 PM Miklos Szeredi <mszeredi@redhat.com> wrote:
> >
> >  - Pass iocb to ctx->end_write() instead of file + pos
> >
> >  - Get rid of ctx->user_file, which is redundant most of the time
> >
> >  - Instead pass iocb to backing_file_splice_read and
> >    backing_file_splice_write
> >
> > Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> > ---
> > v2:
> >     Pass ioctb to backing_file_splice_{read|write}()
> >
> > Applies on fuse.git#for-next.
> 
> This looks good to me.
> you may add
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
> 
> However, this conflicts with ovl_real_file() changes on overlayfs-next
> AND on the fixes in fuse.git#for-next, so we will need to collaborate.
> 
> Were you planning to send the fuse fixes for the 6.12 cycle?
> If so, I could rebase overlayfs-next over 6.12-rcX after fuse fixes
> are merged and then apply your patch to overlayfs-next and resolve conflicts.

Wouldn't you be able to use a shared branch?

If you're able to factor out the backing file changes I could e.g.,
provide you with a base branch that I'll merge into vfs.file, you can
use either as base to overlayfs and fuse or merge into overlayfs and
fuse and fix any potential conflicts. Both works and my PRs all go out
earlier than yours anyway.
Amir Goldstein Oct. 22, 2024, 6:55 p.m. UTC | #3
On Mon, Oct 21, 2024 at 2:22 PM Christian Brauner <brauner@kernel.org> wrote:
>
> On Mon, Oct 21, 2024 at 01:58:16PM +0200, Amir Goldstein wrote:
> > On Mon, Oct 21, 2024 at 12:33 PM Miklos Szeredi <mszeredi@redhat.com> wrote:
> > >
> > >  - Pass iocb to ctx->end_write() instead of file + pos
> > >
> > >  - Get rid of ctx->user_file, which is redundant most of the time
> > >
> > >  - Instead pass iocb to backing_file_splice_read and
> > >    backing_file_splice_write
> > >
> > > Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> > > ---
> > > v2:
> > >     Pass ioctb to backing_file_splice_{read|write}()
> > >
> > > Applies on fuse.git#for-next.
> >
> > This looks good to me.
> > you may add
> > Reviewed-by: Amir Goldstein <amir73il@gmail.com>
> >
> > However, this conflicts with ovl_real_file() changes on overlayfs-next
> > AND on the fixes in fuse.git#for-next, so we will need to collaborate.
> >
> > Were you planning to send the fuse fixes for the 6.12 cycle?
> > If so, I could rebase overlayfs-next over 6.12-rcX after fuse fixes
> > are merged and then apply your patch to overlayfs-next and resolve conflicts.
>
> Wouldn't you be able to use a shared branch?
>
> If you're able to factor out the backing file changes I could e.g.,
> provide you with a base branch that I'll merge into vfs.file, you can
> use either as base to overlayfs and fuse or merge into overlayfs and
> fuse and fix any potential conflicts. Both works and my PRs all go out
> earlier than yours anyway.

Yes, but the question remains, whether Miklos wants to send the fuse
fixes to 6.12-rcX or to 6.13.
I was under the impression that he was going to send them to 6.12-rcX
and this patch depends on them.

I suggested to Miklos to squash this cleanup patch with the API change
for the fuse passthrough fix, which is a stable backport candidate, but
he preferred to not include this cleanup in the backport candidate patch.

Thanks,
Amir.
Miklos Szeredi Oct. 22, 2024, 7:02 p.m. UTC | #4
On Tue, 22 Oct 2024 at 20:57, Amir Goldstein <amir73il@gmail.com> wrote:
>
> On Mon, Oct 21, 2024 at 2:22 PM Christian Brauner <brauner@kernel.org> wrote:
> >
> > On Mon, Oct 21, 2024 at 01:58:16PM +0200, Amir Goldstein wrote:
> > > On Mon, Oct 21, 2024 at 12:33 PM Miklos Szeredi <mszeredi@redhat.com> wrote:
> > > >
> > > >  - Pass iocb to ctx->end_write() instead of file + pos
> > > >
> > > >  - Get rid of ctx->user_file, which is redundant most of the time
> > > >
> > > >  - Instead pass iocb to backing_file_splice_read and
> > > >    backing_file_splice_write
> > > >
> > > > Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> > > > ---
> > > > v2:
> > > >     Pass ioctb to backing_file_splice_{read|write}()
> > > >
> > > > Applies on fuse.git#for-next.
> > >
> > > This looks good to me.
> > > you may add
> > > Reviewed-by: Amir Goldstein <amir73il@gmail.com>
> > >
> > > However, this conflicts with ovl_real_file() changes on overlayfs-next
> > > AND on the fixes in fuse.git#for-next, so we will need to collaborate.
> > >
> > > Were you planning to send the fuse fixes for the 6.12 cycle?
> > > If so, I could rebase overlayfs-next over 6.12-rcX after fuse fixes
> > > are merged and then apply your patch to overlayfs-next and resolve conflicts.
> >
> > Wouldn't you be able to use a shared branch?
> >
> > If you're able to factor out the backing file changes I could e.g.,
> > provide you with a base branch that I'll merge into vfs.file, you can
> > use either as base to overlayfs and fuse or merge into overlayfs and
> > fuse and fix any potential conflicts. Both works and my PRs all go out
> > earlier than yours anyway.
>
> Yes, but the question remains, whether Miklos wants to send the fuse
> fixes to 6.12-rcX or to 6.13.
> I was under the impression that he was going to send them to 6.12-rcX
> and this patch depends on them.

Yes, the head of the fuse#for-next queue should go to 6.12-rc, the
cleanup should wait for the next merge window.

So after the fixes are in linus tree, both the overlay and fuse trees
can be rebased on top of the shared branch containing the cleanup,
right?

Thanks,
Miklos
Amir Goldstein Oct. 26, 2024, 6:29 a.m. UTC | #5
On Tue, Oct 22, 2024 at 9:02 PM Miklos Szeredi <miklos@szeredi.hu> wrote:
>
> On Tue, 22 Oct 2024 at 20:57, Amir Goldstein <amir73il@gmail.com> wrote:
> >
> > On Mon, Oct 21, 2024 at 2:22 PM Christian Brauner <brauner@kernel.org> wrote:
> > >
> > > On Mon, Oct 21, 2024 at 01:58:16PM +0200, Amir Goldstein wrote:
> > > > On Mon, Oct 21, 2024 at 12:33 PM Miklos Szeredi <mszeredi@redhat.com> wrote:
> > > > >
> > > > >  - Pass iocb to ctx->end_write() instead of file + pos
> > > > >
> > > > >  - Get rid of ctx->user_file, which is redundant most of the time
> > > > >
> > > > >  - Instead pass iocb to backing_file_splice_read and
> > > > >    backing_file_splice_write
> > > > >
> > > > > Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> > > > > ---
> > > > > v2:
> > > > >     Pass ioctb to backing_file_splice_{read|write}()
> > > > >
> > > > > Applies on fuse.git#for-next.
> > > >
> > > > This looks good to me.
> > > > you may add
> > > > Reviewed-by: Amir Goldstein <amir73il@gmail.com>
> > > >
> > > > However, this conflicts with ovl_real_file() changes on overlayfs-next
> > > > AND on the fixes in fuse.git#for-next, so we will need to collaborate.
> > > >
> > > > Were you planning to send the fuse fixes for the 6.12 cycle?
> > > > If so, I could rebase overlayfs-next over 6.12-rcX after fuse fixes
> > > > are merged and then apply your patch to overlayfs-next and resolve conflicts.
> > >
> > > Wouldn't you be able to use a shared branch?
> > >
> > > If you're able to factor out the backing file changes I could e.g.,
> > > provide you with a base branch that I'll merge into vfs.file, you can
> > > use either as base to overlayfs and fuse or merge into overlayfs and
> > > fuse and fix any potential conflicts. Both works and my PRs all go out
> > > earlier than yours anyway.
> >
> > Yes, but the question remains, whether Miklos wants to send the fuse
> > fixes to 6.12-rcX or to 6.13.
> > I was under the impression that he was going to send them to 6.12-rcX
> > and this patch depends on them.
>
> Yes, the head of the fuse#for-next queue should go to 6.12-rc, the
> cleanup should wait for the next merge window.
>
> So after the fixes are in linus tree, both the overlay and fuse trees
> can be rebased on top of the shared branch containing the cleanup,
> right?

Right. I see that fuse fixes are merged, so I will rebase
overlayfs-next and apply this patch there.

I don't think you will have any fuse passthrough changes for v6.13,
so we should not have any conflicts.

Thanks,
Amir.
diff mbox series

Patch

diff --git a/fs/backing-file.c b/fs/backing-file.c
index 09a9be945d45..a38737592ec7 100644
--- a/fs/backing-file.c
+++ b/fs/backing-file.c
@@ -80,7 +80,7 @@  struct backing_aio {
 	refcount_t ref;
 	struct kiocb *orig_iocb;
 	/* used for aio completion */
-	void (*end_write)(struct file *, loff_t, ssize_t);
+	void (*end_write)(struct kiocb *iocb, ssize_t);
 	struct work_struct work;
 	long res;
 };
@@ -108,10 +108,10 @@  static void backing_aio_cleanup(struct backing_aio *aio, long res)
 	struct kiocb *iocb = &aio->iocb;
 	struct kiocb *orig_iocb = aio->orig_iocb;
 
+	orig_iocb->ki_pos = iocb->ki_pos;
 	if (aio->end_write)
-		aio->end_write(orig_iocb->ki_filp, iocb->ki_pos, res);
+		aio->end_write(orig_iocb, res);
 
-	orig_iocb->ki_pos = iocb->ki_pos;
 	backing_aio_put(aio);
 }
 
@@ -200,7 +200,7 @@  ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
 	revert_creds(old_cred);
 
 	if (ctx->accessed)
-		ctx->accessed(ctx->user_file);
+		ctx->accessed(iocb->ki_filp);
 
 	return ret;
 }
@@ -219,7 +219,7 @@  ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
 	if (!iov_iter_count(iter))
 		return 0;
 
-	ret = file_remove_privs(ctx->user_file);
+	ret = file_remove_privs(iocb->ki_filp);
 	if (ret)
 		return ret;
 
@@ -239,7 +239,7 @@  ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
 
 		ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf);
 		if (ctx->end_write)
-			ctx->end_write(ctx->user_file, iocb->ki_pos, ret);
+			ctx->end_write(iocb, ret);
 	} else {
 		struct backing_aio *aio;
 
@@ -270,7 +270,7 @@  ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
 }
 EXPORT_SYMBOL_GPL(backing_file_write_iter);
 
-ssize_t backing_file_splice_read(struct file *in, loff_t *ppos,
+ssize_t backing_file_splice_read(struct file *in, struct kiocb *iocb,
 				 struct pipe_inode_info *pipe, size_t len,
 				 unsigned int flags,
 				 struct backing_file_ctx *ctx)
@@ -282,19 +282,19 @@  ssize_t backing_file_splice_read(struct file *in, loff_t *ppos,
 		return -EIO;
 
 	old_cred = override_creds(ctx->cred);
-	ret = vfs_splice_read(in, ppos, pipe, len, flags);
+	ret = vfs_splice_read(in, &iocb->ki_pos, pipe, len, flags);
 	revert_creds(old_cred);
 
 	if (ctx->accessed)
-		ctx->accessed(ctx->user_file);
+		ctx->accessed(iocb->ki_filp);
 
 	return ret;
 }
 EXPORT_SYMBOL_GPL(backing_file_splice_read);
 
 ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
-				  struct file *out, loff_t *ppos, size_t len,
-				  unsigned int flags,
+				  struct file *out, struct kiocb *iocb,
+				  size_t len, unsigned int flags,
 				  struct backing_file_ctx *ctx)
 {
 	const struct cred *old_cred;
@@ -306,18 +306,18 @@  ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
 	if (!out->f_op->splice_write)
 		return -EINVAL;
 
-	ret = file_remove_privs(ctx->user_file);
+	ret = file_remove_privs(iocb->ki_filp);
 	if (ret)
 		return ret;
 
 	old_cred = override_creds(ctx->cred);
 	file_start_write(out);
-	ret = out->f_op->splice_write(pipe, out, ppos, len, flags);
+	ret = out->f_op->splice_write(pipe, out, &iocb->ki_pos, len, flags);
 	file_end_write(out);
 	revert_creds(old_cred);
 
 	if (ctx->end_write)
-		ctx->end_write(ctx->user_file, ppos ? *ppos : 0, ret);
+		ctx->end_write(iocb, ret);
 
 	return ret;
 }
@@ -329,8 +329,7 @@  int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
 	const struct cred *old_cred;
 	int ret;
 
-	if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)) ||
-	    WARN_ON_ONCE(ctx->user_file != vma->vm_file))
+	if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)))
 		return -EIO;
 
 	if (!file->f_op->mmap)
@@ -343,7 +342,7 @@  int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
 	revert_creds(old_cred);
 
 	if (ctx->accessed)
-		ctx->accessed(ctx->user_file);
+		ctx->accessed(vma->vm_file);
 
 	return ret;
 }
diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c
index bbac547dfcb3..607ef735ad4a 100644
--- a/fs/fuse/passthrough.c
+++ b/fs/fuse/passthrough.c
@@ -18,11 +18,11 @@  static void fuse_file_accessed(struct file *file)
 	fuse_invalidate_atime(inode);
 }
 
-static void fuse_passthrough_end_write(struct file *file, loff_t pos, ssize_t ret)
+static void fuse_passthrough_end_write(struct kiocb *iocb, ssize_t ret)
 {
-	struct inode *inode = file_inode(file);
+	struct inode *inode = file_inode(iocb->ki_filp);
 
-	fuse_write_update_attr(inode, pos, ret);
+	fuse_write_update_attr(inode, iocb->ki_pos, ret);
 }
 
 ssize_t fuse_passthrough_read_iter(struct kiocb *iocb, struct iov_iter *iter)
@@ -34,7 +34,6 @@  ssize_t fuse_passthrough_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 	ssize_t ret;
 	struct backing_file_ctx ctx = {
 		.cred = ff->cred,
-		.user_file = file,
 		.accessed = fuse_file_accessed,
 	};
 
@@ -62,7 +61,6 @@  ssize_t fuse_passthrough_write_iter(struct kiocb *iocb,
 	ssize_t ret;
 	struct backing_file_ctx ctx = {
 		.cred = ff->cred,
-		.user_file = file,
 		.end_write = fuse_passthrough_end_write,
 	};
 
@@ -88,15 +86,20 @@  ssize_t fuse_passthrough_splice_read(struct file *in, loff_t *ppos,
 	struct file *backing_file = fuse_file_passthrough(ff);
 	struct backing_file_ctx ctx = {
 		.cred = ff->cred,
-		.user_file = in,
 		.accessed = fuse_file_accessed,
 	};
+	struct kiocb iocb;
+	ssize_t ret;
 
 	pr_debug("%s: backing_file=0x%p, pos=%lld, len=%zu, flags=0x%x\n", __func__,
-		 backing_file, ppos ? *ppos : 0, len, flags);
+		 backing_file, *ppos, len, flags);
 
-	return backing_file_splice_read(backing_file, ppos, pipe, len, flags,
-					&ctx);
+	init_sync_kiocb(&iocb, in);
+	iocb.ki_pos = *ppos;
+	ret = backing_file_splice_read(backing_file, &iocb, pipe, len, flags, &ctx);
+	*ppos = iocb.ki_pos;
+
+	return ret;
 }
 
 ssize_t fuse_passthrough_splice_write(struct pipe_inode_info *pipe,
@@ -109,16 +112,18 @@  ssize_t fuse_passthrough_splice_write(struct pipe_inode_info *pipe,
 	ssize_t ret;
 	struct backing_file_ctx ctx = {
 		.cred = ff->cred,
-		.user_file = out,
 		.end_write = fuse_passthrough_end_write,
 	};
+	struct kiocb iocb;
 
 	pr_debug("%s: backing_file=0x%p, pos=%lld, len=%zu, flags=0x%x\n", __func__,
-		 backing_file, ppos ? *ppos : 0, len, flags);
+		 backing_file, *ppos, len, flags);
 
 	inode_lock(inode);
-	ret = backing_file_splice_write(pipe, backing_file, ppos, len, flags,
-					&ctx);
+	init_sync_kiocb(&iocb, out);
+	iocb.ki_pos = *ppos;
+	ret = backing_file_splice_write(pipe, backing_file, &iocb, len, flags, &ctx);
+	*ppos = iocb.ki_pos;
 	inode_unlock(inode);
 
 	return ret;
@@ -130,7 +135,6 @@  ssize_t fuse_passthrough_mmap(struct file *file, struct vm_area_struct *vma)
 	struct file *backing_file = fuse_file_passthrough(ff);
 	struct backing_file_ctx ctx = {
 		.cred = ff->cred,
-		.user_file = file,
 		.accessed = fuse_file_accessed,
 	};
 
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
index 4444c78e2e0c..12c4d502ff91 100644
--- a/fs/overlayfs/file.c
+++ b/fs/overlayfs/file.c
@@ -231,9 +231,9 @@  static void ovl_file_modified(struct file *file)
 	ovl_copyattr(file_inode(file));
 }
 
-static void ovl_file_end_write(struct file *file, loff_t pos, ssize_t ret)
+static void ovl_file_end_write(struct kiocb *iocb, ssize_t ret)
 {
-	ovl_file_modified(file);
+	ovl_file_modified(iocb->ki_filp);
 }
 
 static void ovl_file_accessed(struct file *file)
@@ -271,7 +271,6 @@  static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 	ssize_t ret;
 	struct backing_file_ctx ctx = {
 		.cred = ovl_creds(file_inode(file)->i_sb),
-		.user_file = file,
 		.accessed = ovl_file_accessed,
 	};
 
@@ -298,7 +297,6 @@  static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
 	int ifl = iocb->ki_flags;
 	struct backing_file_ctx ctx = {
 		.cred = ovl_creds(inode->i_sb),
-		.user_file = file,
 		.end_write = ovl_file_end_write,
 	};
 
@@ -338,15 +336,18 @@  static ssize_t ovl_splice_read(struct file *in, loff_t *ppos,
 	ssize_t ret;
 	struct backing_file_ctx ctx = {
 		.cred = ovl_creds(file_inode(in)->i_sb),
-		.user_file = in,
 		.accessed = ovl_file_accessed,
 	};
+	struct kiocb iocb;
 
 	ret = ovl_real_fdget(in, &real);
 	if (ret)
 		return ret;
 
-	ret = backing_file_splice_read(fd_file(real), ppos, pipe, len, flags, &ctx);
+	init_sync_kiocb(&iocb, in);
+	iocb.ki_pos = *ppos;
+	ret = backing_file_splice_read(fd_file(real), &iocb, pipe, len, flags, &ctx);
+	*ppos = iocb.ki_pos;
 	fdput(real);
 
 	return ret;
@@ -368,9 +369,9 @@  static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
 	ssize_t ret;
 	struct backing_file_ctx ctx = {
 		.cred = ovl_creds(inode->i_sb),
-		.user_file = out,
 		.end_write = ovl_file_end_write,
 	};
+	struct kiocb iocb;
 
 	inode_lock(inode);
 	/* Update mode */
@@ -380,9 +381,13 @@  static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
 	if (ret)
 		goto out_unlock;
 
-	ret = backing_file_splice_write(pipe, fd_file(real), ppos, len, flags, &ctx);
+	init_sync_kiocb(&iocb, out);
+	iocb.ki_pos = *ppos;
+	ret = backing_file_splice_write(pipe, fd_file(real), &iocb, len, flags, &ctx);
+	*ppos = iocb.ki_pos;
 	fdput(real);
 
+
 out_unlock:
 	inode_unlock(inode);
 
@@ -420,7 +425,6 @@  static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
 	struct file *realfile = file->private_data;
 	struct backing_file_ctx ctx = {
 		.cred = ovl_creds(file_inode(file)->i_sb),
-		.user_file = file,
 		.accessed = ovl_file_accessed,
 	};
 
diff --git a/include/linux/backing-file.h b/include/linux/backing-file.h
index 2eed0ffb5e8f..1476a6ed1bfd 100644
--- a/include/linux/backing-file.h
+++ b/include/linux/backing-file.h
@@ -14,9 +14,8 @@ 
 
 struct backing_file_ctx {
 	const struct cred *cred;
-	struct file *user_file;
-	void (*accessed)(struct file *);
-	void (*end_write)(struct file *, loff_t, ssize_t);
+	void (*accessed)(struct file *file);
+	void (*end_write)(struct kiocb *iocb, ssize_t);
 };
 
 struct file *backing_file_open(const struct path *user_path, int flags,
@@ -31,13 +30,13 @@  ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
 ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
 				struct kiocb *iocb, int flags,
 				struct backing_file_ctx *ctx);
-ssize_t backing_file_splice_read(struct file *in, loff_t *ppos,
+ssize_t backing_file_splice_read(struct file *in, struct kiocb *iocb,
 				 struct pipe_inode_info *pipe, size_t len,
 				 unsigned int flags,
 				 struct backing_file_ctx *ctx);
 ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
-				  struct file *out, loff_t *ppos, size_t len,
-				  unsigned int flags,
+				  struct file *out, struct kiocb *iocb,
+				  size_t len, unsigned int flags,
 				  struct backing_file_ctx *ctx);
 int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
 		      struct backing_file_ctx *ctx);