On Wed, 8 Mar 2023 at 15:38, David Howells <dhowells@xxxxxxxxxx> wrote: > > Implement splice-read for overlayfs by passing the request down a layer > rather than going through generic_file_splice_read() which is going to be > changed to assume that ->read_folio() is present on buffered files. > > Signed-off-by: David Howells <dhowells@xxxxxxxxxx> > cc: Christoph Hellwig <hch@xxxxxx> > cc: Jens Axboe <axboe@xxxxxxxxx> > cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> > cc: John Hubbard <jhubbard@xxxxxxxxxx> > cc: David Hildenbrand <david@xxxxxxxxxx> > cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> > cc: Miklos Szeredi <miklos@xxxxxxxxxx> > cc: linux-unionfs@xxxxxxxxxxxxxxx > cc: linux-block@xxxxxxxxxxxxxxx > cc: linux-fsdevel@xxxxxxxxxxxxxxx > cc: linux-mm@xxxxxxxxx > --- > > Notes: > ver #15) > - Remove redundant FMODE_CAN_ODIRECT check on real file. > - Do rw_verify_area() on the real file, not the overlay file. > - Fix a file leak. > > fs/overlayfs/file.c | 33 ++++++++++++++++++++++++++++++++- > 1 file changed, 32 insertions(+), 1 deletion(-) > > diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c > index 7c04f033aadd..a12919e9ccba 100644 > --- a/fs/overlayfs/file.c > +++ b/fs/overlayfs/file.c > @@ -419,6 +419,37 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) > return ret; > } > > +static ssize_t ovl_splice_read(struct file *in, loff_t *ppos, > + struct pipe_inode_info *pipe, size_t len, > + unsigned int flags) > +{ > + const struct cred *old_cred; > + struct fd real; > + ssize_t ret; > + > + ret = ovl_real_fdget(in, &real); > + if (ret) > + return ret; > + > + ret = -EINVAL; > + if (!real.file->f_op->splice_read) > + goto out_fdput; > + > + ret = rw_verify_area(READ, real.file, ppos, len); > + if (unlikely(ret < 0)) > + goto out_fdput; > + > + old_cred = ovl_override_creds(file_inode(in)->i_sb); > + ret = real.file->f_op->splice_read(real.file, ppos, pipe, len, flags); I don't think you replied to my suggestion of using a helper here. E.g. it could be as simple as exporting do_splice_to(), or renaming it to vfs_splice_read() to be more readable. It would remove the boilerplate and be more robust if any changes are done to the splice reading code. Thanks, Miklos