generic/335: explicitly fsync file foo when running on btrfs
authorFilipe Manana <fdmanana@suse.com>
Thu, 9 Dec 2021 14:44:06 +0000 (14:44 +0000)
committerEryu Guan <guaneryu@gmail.com>
Sun, 12 Dec 2021 14:47:08 +0000 (22:47 +0800)
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@suse.com>
Reviewed-by: Eryu Guan <guaneryu@gmail.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
tests/generic/335

index e04f7a5f1556903e504246c94b9cf0a4eb572bdf..196ada6414e8617ed5ddb1019380a6082d268753 100755 (executable)
@@ -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
+
 echo "Filesystem content before power failure:"
 ls -R $SCRATCH_MNT/a $SCRATCH_MNT/c | _filter_scratch