_require_sparse_files is implemented as a list of filesystems known not to support sparse files, and so misses some cases. If sparse files do not really work (as it is the case with CIFS and a Windows Server 2022), this test writes to the disk all the zeros that would normally be free due to sparse files. This amounts to many terabytes and presents a significant media wearout concern. Mitigate this by doing a small-scale test first and checking if the resulting file ends up being not sufficiently sparse. Signed-off-by: Alexander Patrakov <patrakov@xxxxxxxxx> --- src/looptest.c | 9 +++++++-- tests/generic/129 | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/looptest.c b/src/looptest.c index 7194a97d..2e620a60 100644 --- a/src/looptest.c +++ b/src/looptest.c @@ -56,6 +56,7 @@ enum { FLAG_FLUSH = 64, FLAG_DELETE = 128, FLAG_DIRECT = 256, + FLAG_LEAVE = 512, }; void @@ -74,6 +75,7 @@ usage(char *argv0) " -s = sequential\n" " -f = flush\n" " -D = direct-IO\n" + " -L = skip the final truncation\n" " -h = usage\n", argv0); } @@ -94,7 +96,7 @@ main(int argc, char *argv[]) char *buf = NULL; int64_t seek_to = 0; - while ((c = getopt(argc, argv, "i:orwb:svthfFDd?")) != EOF) { + while ((c = getopt(argc, argv, "i:orwb:svthfFDLd?")) != EOF) { switch (c) { case 'i': count = atoi(optarg); @@ -126,6 +128,9 @@ main(int argc, char *argv[]) case 'D': flags |= FLAG_DIRECT; break; + case 'L': + flags |= FLAG_LEAVE; + break; case 'd': flags |= FLAG_DELETE; break; @@ -230,7 +235,7 @@ main(int argc, char *argv[]) } } - if (flags & FLAG_TRUNCATE) { + if ((flags & FLAG_TRUNCATE) && !((flags & FLAG_LEAVE) && (i == count - 1))) { if (flags & FLAG_VERBOSE) printf("seek 0\n"); diff --git a/tests/generic/129 b/tests/generic/129 index 3d3a42a2..d1149b65 100755 --- a/tests/generic/129 +++ b/tests/generic/129 @@ -29,6 +29,14 @@ _scratch_mount "-o nosuid" mkdir $SCRATCH_MNT/looptest +# looptest2, if the missing sparse file support is not detected, writes more +# than 4 TB to the device. There was a complaint about media wearout, so do a +# small-scale test first. +$here/src/looptest -i 10 -L -t -r -w -s -b 102400 $SCRATCH_MNT/looptest/looptest0.tst +resulting_file_size_kb=$( du -sk $SCRATCH_MNT/looptest/looptest0.tst | cut -f 1 ) +rm -f $SCRATCH_MNT/looptest/looptest0.tst +[ $resulting_file_size_kb -gt 256 ] && _notrun "Test skipped due to media wearout concerns - sparse files do not work" + $here/src/looptest -i 100000 -r -w -b 8192 -s $SCRATCH_MNT/looptest/looptest1.tst $here/src/looptest -i 10000 -t -r -w -s -b 102400 $SCRATCH_MNT/looptest/looptest2.tst $here/src/looptest -i 50000 -r -w -b 256 -s $SCRATCH_MNT/looptest/looptest3.tst -- 2.43.0