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

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

 



On Mon, Oct 14, 2024 at 8:30 AM yangyun <yangyun50@xxxxxxxxxx> wrote:
>
> On Fri, Oct 11, 2024 at 03:53:26PM +0200, Amir Goldstein 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>
> > ---
> >
> > Doh! force of habbit - fixed subject s/ovl/fuse
> >
> > Thanks,
> > Amir.
> >
> >  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
>
> Sorry for a late reply. Because I have spent some time on figuring out whether we
> need some FUSE_I_SIZE_UNSTABLE bit operations before and after the write which are
> provided in your v14 patch of fuse passthrough, just like in fuse_perform_write.
>
> The conclusion is not, IMO. The FUSE_I_SIZE_UNSTABLE bit is provided in
> commit 06a7c3c2781(fuse: hotfix truncate_pagecache() issue) for the
> races between i_size updates and truncate_pagecache() in
> fuse_change_attributes. Because the pagecache operations of fuse inode
> is not allowed in fuse passthrough mode, this FUSE_I_SIZE_UNSTABLE bit is useless.
> And we just need the minimum fix for extending writes by now.
>

That was my conclusion as well.
In general, too large i_size is less of a problem IMO.
Shortening i_size on short read/truncate is an optimization.

> I have also tested this patch with xfstests (using ./check -fuse -b) and libfuse
> test. In xfstest, this patch does not import new failed tests compared with pre-this
> patch. And in libfuse test, this patch can solve the problem test_copy_file_range().

Thanks for testing!
Amir.





[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