Re: [PATCH] ovl: update inode size after extending passthrough write

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
>





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux