Re: [PATCH] generic/335: explicitly fsync file foo when running on btrfs

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



On Fri, Dec 10, 2021 at 12:32 AM Dave Chinner <david@xxxxxxxxxxxxx> wrote:
>
> On Thu, Dec 09, 2021 at 02:44:06PM +0000, fdmanana@xxxxxxxxxx wrote:
> > From: Filipe Manana <fdmanana@xxxxxxxx>
> >
> > The test is relying on the fact that an fsync on directory "a" will
> > result in persisting the changes of its subdirectory "b", namely the
> > rename of "/a/b/foo" to "/c/foo". For this particular filesystem layout,
> > that will happen on btrfs, because all the directory entries end up in
> > the same metadata leaf. However that is not a behaviour we can always
> > guarantee on btrfs. For example, if we add more files to directory
> > "a" before and after creating subdirectory "b", like this:
> >
> >   mkdir $SCRATCH_MNT/a
> >   for ((i = 0; i < 1000; i++)); do
> >       echo -n > $SCRATCH_MNT/a/file_$i
> >   done
> >   mkdir $SCRATCH_MNT/a/b
> >   for ((i = 1000; i < 2000; i++)); do
> >       echo -n > $SCRATCH_MNT/a/file_$i
> >   done
> >   mkdir $SCRATCH_MNT/c
> >   touch $SCRATCH_MNT/a/b/foo
> >
> >   sync
> >
> >   # The rest of the test remains unchanged...
> >   (...)
> >
> > Then after fsyncing only directory "a", the rename of file "foo" from
> > "/a/b/foo" to "/c/foo" is not persisted.
> >
> > Guaranteeing that on btrfs would be expensive on large directories, as
> > it would require scanning for every subdirectory. It's also not required
> > by posix for the fsync on a directory to persist changes inside its
> > subdirectories. So add an explicit fsync on file "foo" when the filesystem
> > being tested is btrfs.
> >
> > Signed-off-by: Filipe Manana <fdmanana@xxxxxxxx>
> > ---
> >  tests/generic/335 | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> >
> > diff --git a/tests/generic/335 b/tests/generic/335
> > index e04f7a5f..196ada64 100755
> > --- a/tests/generic/335
> > +++ b/tests/generic/335
> > @@ -51,6 +51,15 @@ mv $SCRATCH_MNT/a/b/foo $SCRATCH_MNT/c/
> >  touch $SCRATCH_MNT/a/bar
> >  $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/a
> >
> > +# btrfs can not guarantee that when we fsync a directory all its subdirectories
> > +# created on past transactions are fsynced as well. It may do it sometimes, but
> > +# it's not guaranteed, giving such guarantees would be too expensive for large
> > +# directories and posix does not require that recursive behaviour. So if we want
> > +# the rename of "foo" to be persisted, explicitly fsync "foo".
> > +if [ $FSTYP == "btrfs" ]; then
> > +     $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/c/foo
> > +fi
>
> Doesn't this imply a regression in the behaviour of btrfs? After
> all, this test was written explicitly to exercise a bug in btrfs log
> recovery:
>
> commit 72da52702a4b5bea1170aed791893487d0748566
> Author: Filipe Manana <fdmanana@xxxxxxxx>
> Date:   Fri Feb 19 12:15:17 2016 +1100
>
>     generic: test directory fsync after rename operation
>
>     Test that if we move one file between directories, fsync the parent
>     directory of the old directory, power fail and remount the filesystem,
>     the file is not lost and it's located at the destination directory.
>
>     This is motivated by a bug found in btrfs, which is fixed by the patch
>     (for the linux kernel) titled:
>
>       "Btrfs: fix file loss on log replay after renaming a file and fsync"
>
>     Tested against ext3, ext4, xfs, f2fs and reiserfs.
>
>     Signed-off-by: Filipe Manana <fdmanana@xxxxxxxx>
>     Reviewed-by: Dave Chinner <dchinner@xxxxxxxxxx>
>     Signed-off-by: Dave Chinner <david@xxxxxxxxxxxxx>
>
> What's changed that now makes this an invalid test for btrfs log
> recovery? Has btrfs loosened it's metadata ordering guarantees in
> the past few years?

No, btrfs has not loosened its metadata ordering guarantees.
The test was written because btrfs had a bug where it would lose file
foo if we fsynced only directory "/a".

I should have made the test check that after log replay, file foo
exists either at "/c/foo" or at "/a/b/foo" - that the file was not
lost.
Perhaps that's a better change than making the test fsync file foo explicitly.

As I mentioned in the changelog, in this particular case the rename is
persisted,
because all the metadata is very small and fits in a single leaf of metadata.

But, for example, adding those 1000 files after creating "/a" and
another 1000 files after creating "/a/b", makes
the test fail because it expects the rename to have been persisted,
that file foo is at "/c/foo" - in that case
the file is still at "/a/b/foo".

Thanks.



>
> Cheers,
>
> Dave.
> --
> Dave Chinner
> david@xxxxxxxxxxxxx



[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux