Wrong subject line - resending... On Fri, Oct 11, 2024 at 3:46 PM Amir Goldstein <amir73il@xxxxxxxxx> wrote: > > yangyun reported that libfuse test test_copy_file_range() copies zero > bytes from a newly written file when fuse passthrough is enabled. > > The reason is that extending passthrough write is not updating the fuse > inode size and when vfs_copy_file_range() observes a zero size inode, > it returns without calling the filesystem copy_file_range() method. > > Extend the fuse inode size to the size of the backing inode after every > passthrough write if the backing inode size is larger. > > This does not yet provide cache coherency of fuse inode attributes and > backing inode attributes, but it should prevent situations where fuse > inode size is too small, causing read/copy to be wrongly shortened. > > Reported-by: yangyun <yangyun50@xxxxxxxxxx> > Closes: https://github.com/libfuse/libfuse/issues/1048 > Fixes: 57e1176e6086 ("fuse: implement read/write passthrough") > Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> > --- > fs/fuse/passthrough.c | 13 +++++++++++-- > 1 file changed, 11 insertions(+), 2 deletions(-) > > diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c > index ba3207f6c4ce..d3047a4bc40e 100644 > --- a/fs/fuse/passthrough.c > +++ b/fs/fuse/passthrough.c > @@ -20,9 +20,18 @@ static void fuse_file_accessed(struct file *file) > > static void fuse_file_modified(struct file *file) > { > + struct fuse_file *ff = file->private_data; > + struct file *backing_file = fuse_file_passthrough(ff); > struct inode *inode = file_inode(file); > - > - fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE); > + loff_t size = i_size_read(file_inode(backing_file)); > + > + /* > + * Most of the time we will be holding inode_lock(), but even if we are > + * called from async io completion without inode_lock(), the last write > + * will update fuse inode size to the size of the backing inode, even if > + * the last write was not the extending write. > + */ > + fuse_write_update_attr(inode, size, size); > } > > ssize_t fuse_passthrough_read_iter(struct kiocb *iocb, struct iov_iter *iter) > -- > 2.34.1 >