}
# 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 test 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.
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
#!/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.
. "${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_
#!/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.
# 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_
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.
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_
# 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.
. "${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
+++ /dev/null
-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)
tests/factor/run.sh \
tests/factor/create-test.sh \
tests/filefrag-extent-compare \
- tests/fiemap-capable \
+ tests/seek-data-capable \
tests/init.sh \
tests/lang-default \
tests/no-perl \
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 \
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 \
--- /dev/null
+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)