>From 9c404d16208a5ae86b0876f9f2102c7205812b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Sun, 9 May 2021 14:29:01 +0100 Subject: [PATCH] tests: ensure we test SEEK_DATA where used fiemap is no longer the default copy implementation, so check for SEEK_DATA support instead as that's preferred. This will ensure better test coverage on systems without fiemap. * init.cfg: Replace fiemap_capable_ with seek_data_capable_. This is best supported with python 3 so prefer that. * tests/seek-data-capable: A new test script checking for SEEK_DATA support on the passed file name, called from seek_data_capable_. * tests/fiemap-capable: Remove no longer used probing script. * tests/cp/fiemap-perf.sh: Renamed to tests/cp/sparse-perf.sh * tests/cp/fiemap-2.sh: Renamed to tests/cp/sparse-2.sh * tests/cp/fiemap-extents.sh: Renamed to tests/cp/sparse-extents.sh * tests/cp/sparse-fiemap.sh: Renamed to tests/cp/sparse-extents-2.sh * tests/cp/fiemap-FMR.sh: Renamed to tests/cp/copy-FMR.sh * tests/local.mk: Reference the renamed tests. --- init.cfg | 16 +++++---- tests/cp/{fiemap-FMR.sh => copy-FMR.sh} | 1 + tests/cp/{fiemap-2.sh => sparse-2.sh} | 9 +++-- .../{sparse-fiemap.sh => sparse-extents-2.sh} | 12 +++---- .../{fiemap-extents.sh => sparse-extents.sh} | 9 +++-- tests/cp/{fiemap-perf.sh => sparse-perf.sh} | 20 +++-------- tests/fiemap-capable | 16 --------- tests/local.mk | 11 +++---- tests/seek-data-capable | 33 +++++++++++++++++++ 9 files changed, 66 insertions(+), 61 deletions(-) rename tests/cp/{fiemap-FMR.sh => copy-FMR.sh} (95%) rename tests/cp/{fiemap-2.sh => sparse-2.sh} (88%) rename tests/cp/{sparse-fiemap.sh => sparse-extents-2.sh} (91%) rename tests/cp/{fiemap-extents.sh => sparse-extents.sh} (93%) rename tests/cp/{fiemap-perf.sh => sparse-perf.sh} (64%) delete mode 100644 tests/fiemap-capable create mode 100644 tests/seek-data-capable diff --git a/init.cfg b/init.cfg index 4ad2ecd11..568946015 100644 --- a/init.cfg +++ b/init.cfg @@ -530,15 +530,17 @@ require_kill_group_() } # Return nonzero if the specified path is on a file system for -# which FIEMAP support exists. Note some file systems (like ext3 and btrfs) -# only support FIEMAP for files, not directories. -fiemap_capable_() +# which SEEK_DATA support exists. +seek_data_capable_() { - if ! python < /dev/null; then - warn_ 'fiemap_capable_: python missing: assuming not fiemap capable' - return 1 + { python3 < /dev/null && PYTHON_=python3; } || + { python < /dev/null && PYTHON_=python; } + + if x"$PYTHON_" = x; then + warn_ 'seek_data_capable_: python missing: assuming not SEEK_DATA capable' + return 1 fi - python "$abs_srcdir"/tests/fiemap-capable "$@" + $PYTHON_ "$abs_srcdir"/tests/seek-data-capable "$@" } # Skip the current test if "." lacks d_type support. diff --git a/tests/cp/fiemap-FMR.sh b/tests/cp/copy-FMR.sh similarity index 95% rename from tests/cp/fiemap-FMR.sh rename to tests/cp/copy-FMR.sh index 7bbb88a2c..1ecdbe44d 100755 --- a/tests/cp/fiemap-FMR.sh +++ b/tests/cp/copy-FMR.sh @@ -22,6 +22,7 @@ print_ver_ cp require_valgrind_ require_perl_ +# Trigger FMR in fiemap logic from v8.11..v8.19 $PERL -e 'for (1..600) { sysseek (*STDOUT, 4096, 1)' \ -e '&& syswrite (*STDOUT, "a" x 1024) or die "$!"}' > j || fail=1 valgrind --quiet --error-exitcode=3 cp --reflink=never j j2 || fail=1 diff --git a/tests/cp/fiemap-2.sh b/tests/cp/sparse-2.sh similarity index 88% rename from tests/cp/fiemap-2.sh rename to tests/cp/sparse-2.sh index e6b80ebd3..05aa7f980 100755 --- a/tests/cp/fiemap-2.sh +++ b/tests/cp/sparse-2.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Exercise a few more corners of the fiemap-copying code. +# Exercise a few more corners of the copying code. # Copyright (C) 2011-2021 Free Software Foundation, Inc. @@ -19,10 +19,9 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ cp -# Require a fiemap-enabled FS. -touch fiemap_chk # check a file rather than current dir for best coverage -fiemap_capable_ fiemap_chk \ - || skip_ "this file system lacks FIEMAP support" +touch sparse_chk +seek_data_capable_ sparse_chk \ + || skip_ "this file system lacks SEEK_DATA support" # Exercise the code that handles a file ending in a hole. printf x > k || framework_failure_ diff --git a/tests/cp/sparse-fiemap.sh b/tests/cp/sparse-extents-2.sh similarity index 91% rename from tests/cp/sparse-fiemap.sh rename to tests/cp/sparse-extents-2.sh index c66e714fc..544b959ef 100755 --- a/tests/cp/sparse-fiemap.sh +++ b/tests/cp/sparse-extents-2.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Test cp --sparse=always through fiemap copy +# Test cp --sparse=always through SEEK_DATA copy # Copyright (C) 2010-2021 Free Software Foundation, Inc. @@ -22,11 +22,11 @@ require_perl_ # The test was seen to fail on ext3 so exclude that type # (or any file system where the type can't be determined) -touch fiemap_chk -if fiemap_capable_ fiemap_chk && ! df -t ext3 . >/dev/null; then +touch sparse_chk +if seek_data_capable_ sparse_chk && ! df -t ext3 . >/dev/null; then : # Current partition has working extents. Good! else - skip_ "current file system has insufficient FIEMAP support" + skip_ "current file system has insufficient SEEK_DATA support" # It's not; we need to create one, hence we need root access. require_root_ @@ -50,8 +50,8 @@ else fi # ================================================= -# Ensure that we exercise the FIEMAP-copying code enough -# to provoke at least two iterations of the do...while loop +# The data below was set up to ensure that the original FIEMAP-copying code +# was exercised enough to provoke at least two iterations of the do...while loop # in which it calls ioctl (fd, FS_IOC_FIEMAP,... # This also verifies that non-trivial extents are preserved. diff --git a/tests/cp/fiemap-extents.sh b/tests/cp/sparse-extents.sh similarity index 93% rename from tests/cp/fiemap-extents.sh rename to tests/cp/sparse-extents.sh index 23f5cd9a3..1e9156149 100755 --- a/tests/cp/fiemap-extents.sh +++ b/tests/cp/sparse-extents.sh @@ -21,10 +21,9 @@ print_ver_ cp require_sparse_support_ -touch fiemap_chk || framework_failure_ -fiemap_capable_ fiemap_chk || - skip_ 'this file system lacks FIEMAP support' -rm fiemap_chk +touch sparse_chk || framework_failure_ +seek_data_capable_ sparse_chk || + skip_ 'this file system lacks SEEK_DATA support' fallocate --help >/dev/null || skip_ 'The fallocate utility is required' touch falloc.test || framework_failure_ @@ -65,7 +64,7 @@ fi # Ensure we handle extents beyond file size correctly. # Note until we support fallocate, we will not maintain # the file allocation. FIXME: amend this test if fallocate is supported. -# Note currently this only uses fiemap logic when the allocation (-l) +# Note currently this only uses SEEK_DATA logic when the allocation (-l) # is smaller than the size, thus identifying the file as sparse. # Note the '-l 1' case is an effective noop, and just checks # a file with a trailing hole is copied correctly. diff --git a/tests/cp/fiemap-perf.sh b/tests/cp/sparse-perf.sh similarity index 64% rename from tests/cp/fiemap-perf.sh rename to tests/cp/sparse-perf.sh index de110914f..a71b854cf 100755 --- a/tests/cp/fiemap-perf.sh +++ b/tests/cp/sparse-perf.sh @@ -19,30 +19,18 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ cp -# Require a fiemap-enabled FS. -touch fiemap_chk -fiemap_capable_ fiemap_chk || - skip_ "this file system lacks FIEMAP support" - -# Exclude ext[23] (or unknown fs types) -# as the emulated extent scanning can be slow -df -t ext2 -t ext3 . >/dev/null && - skip_ "ext[23] can have slow FIEMAP scanning" +touch sparse_chk +seek_data_capable_ sparse_chk || + skip_ "this file system lacks SEEK_DATA support" # Create a large-but-sparse file. timeout 10 truncate -s1T f || skip_ "unable to create a 1 TiB sparse file" -# Disable this test on old BTRFS (e.g. Fedora 14) -# which reports (unwritten) extents for holes. -filefrag f || skip_ "the 'filefrag' utility is missing" -filefrag f | grep -F ': 0 extents found' > /dev/null || - skip_ 'this file system reports extents for holes' - # Nothing can read (much less write) that many bytes in so little time. timeout 10 cp f f2 || fail=1 -# Ensure that the sparse file copied through fiemap has the same size +# Ensure that the sparse file copied through SEEK_DATA has the same size # in bytes as the original. test "$(stat --printf %s f)" = "$(stat --printf %s f2)" || fail=1 diff --git a/tests/fiemap-capable b/tests/fiemap-capable deleted file mode 100644 index 05c6926a7..000000000 --- a/tests/fiemap-capable +++ /dev/null @@ -1,16 +0,0 @@ -import struct, fcntl, sys, os - -def sizeof(t): return struct.calcsize(t) -IOCPARM_MASK = 0x7f -IOC_OUT = 0x40000000 -IOC_IN = 0x80000000 -IOC_INOUT = (IOC_IN|IOC_OUT) -def _IOWR(x,y,t): return (IOC_INOUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|y) - -try: - fd = os.open (len (sys.argv) == 2 and sys.argv[1] or '.', os.O_RDONLY) - struct_fiemap = '=qqllll' - FS_IOC_FIEMAP = _IOWR (ord ('f'), 11, struct_fiemap) - fcntl.ioctl (fd, FS_IOC_FIEMAP, struct.pack(struct_fiemap, 0,~0,0,0,0,0)) -except: - sys.exit (1) diff --git a/tests/local.mk b/tests/local.mk index a44feca73..7eb9791e3 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -98,7 +98,6 @@ EXTRA_DIST += \ tests/factor/run.sh \ tests/factor/create-test.sh \ tests/filefrag-extent-compare \ - tests/fiemap-capable \ tests/init.sh \ tests/lang-default \ tests/no-perl \ @@ -113,7 +112,7 @@ all_root_tests = \ tests/cp/special-bits.sh \ tests/cp/cp-mv-enotsup-xattr.sh \ tests/cp/capability.sh \ - tests/cp/sparse-fiemap.sh \ + tests/cp/sparse-extents-2.sh \ tests/cp/cross-dev-symlink.sh \ tests/dd/skip-seek-past-dev.sh \ tests/df/problematic-chars.sh \ @@ -481,10 +480,10 @@ all_tests = \ tests/cp/existing-perm-dir.sh \ tests/cp/existing-perm-race.sh \ tests/cp/fail-perm.sh \ - tests/cp/fiemap-extents.sh \ - tests/cp/fiemap-FMR.sh \ - tests/cp/fiemap-perf.sh \ - tests/cp/fiemap-2.sh \ + tests/cp/sparse-extents.sh \ + tests/cp/copy-FMR.sh \ + tests/cp/sparse-perf.sh \ + tests/cp/sparse-2.sh \ tests/cp/file-perm-race.sh \ tests/cp/into-self.sh \ tests/cp/link.sh \ diff --git a/tests/seek-data-capable b/tests/seek-data-capable new file mode 100644 index 000000000..cc6372214 --- /dev/null +++ b/tests/seek-data-capable @@ -0,0 +1,33 @@ +import sys, os, errno, platform + +# Pass an _empty_ file +if len(sys.argv) != 2: + sys.exit(1) + +if not hasattr(os, 'SEEK_DATA'): + # Not available on python 2, or on darwin python 3 + # Also Darwin swaps SEEK_DATA/SEEK_HOLE definitions + if platform.system() == "Darwin": + SEEK_DATA = 4 + else: + SEEK_DATA = 3 # Valid on Linux, FreeBSD, Solaris +else: + SEEK_DATA = os.SEEK_DATA + +# Even if os supports SEEK_DATA or SEEK_HOLE, +# the file system may not, in which case it would report +# current and eof positions respectively. +# Therefore work with an empty file, +# ensuring SEEK_DATA returns ENXIO (no more data) +try: + fd = os.open(sys.argv[1], os.O_RDONLY) +except: + sys.exit(1) + +try: + data = os.lseek(fd, 0, SEEK_DATA) +except OSError as e: + if e.errno == errno.ENXIO: + sys.exit(0) + +sys.exit(1) -- 2.26.2