I'm pushing the attached patch, which I hope will fix the problem.
On Thu, Jul 23, 2026 at 8:24 PM James Youngman <[email protected]> wrote:
>
> Yes, the test reproducibly passes for me. But the filesystem I am
> using is ZFS:
>
> $ yes "" | sed -e '765 q'> /tmp/small-text-file.txt ; \
> dd if=/dev/urandom bs=765 of=/tmp/random-data.bin count=1 ; \
> cp /tmp/random-data.bin /tmp/small-text-file.txt . ; \
> find \
> /tmp/random-data.bin random-data.bin /tmp/small-text-file.txt
> small-text-file.txt \
> -printf '%%k=%k %%b=%b %s %p\n' ; \
> sha1sum /tmp/random-data.bin random-data.bin
> /tmp/small-text-file.txt small-text-file.txt
> 1+0 records in
> 1+0 records out
> 765 bytes copied, 3.9558e-05 s, 19.3 MB/s
> %k=4 %b=8 765 /tmp/random-data.bin
> %k=5 %b=9 765 random-data.bin
> %k=4 %b=8 765 /tmp/small-text-file.txt
> %k=1 %b=1 765 small-text-file.txt
> 0156e7e4ea8f26c91c5de2f4337d8e1d44e7c556 /tmp/random-data.bin
> 0156e7e4ea8f26c91c5de2f4337d8e1d44e7c556 random-data.bin
> 38957bd663f7efc364ac7c8ed3589fa69520b9e4 /tmp/small-text-file.txt
> 38957bd663f7efc364ac7c8ed3589fa69520b9e4 small-text-file.txt
> $ stat /tmp/random-data.bin random-data.bin /tmp/small-text-file.txt
> small-text-file.txt
> File: /tmp/random-data.bin
> Size: 765 Blocks: 8 IO Block: 4096 regular file
> Device: 253,2 Inode: 19 Links: 1
> Access: (0664/-rw-rw-r--) Uid: ( 1027/ james) Gid: ( 1027/ james)
> Access: 2026-07-23 20:21:50.226425401 +0100
> Modify: 2026-07-23 20:21:50.222425458 +0100
> Change: 2026-07-23 20:21:50.222425458 +0100
> Birth: 2026-07-23 20:17:57.985621969 +0100
> File: random-data.bin
> Size: 765 Blocks: 9 IO Block: 1024 regular file
> Device: 0,41 Inode: 5342459 Links: 1
> Access: (0664/-rw-rw-r--) Uid: ( 1027/ james) Gid: ( 1027/ james)
> Access: 2026-07-23 20:21:50.230425347 +0100
> Modify: 2026-07-23 20:21:50.226425401 +0100
> Change: 2026-07-23 20:21:50.226425401 +0100
> Birth: 2026-07-23 20:17:57.985621969 +0100
> File: /tmp/small-text-file.txt
> Size: 765 Blocks: 8 IO Block: 4096 regular file
> Device: 253,2 Inode: 16 Links: 1
> Access: (0664/-rw-rw-r--) Uid: ( 1027/ james) Gid: ( 1027/ james)
> Access: 2026-07-23 20:21:50.226425401 +0100
> Modify: 2026-07-23 20:21:50.218425513 +0100
> Change: 2026-07-23 20:21:50.218425513 +0100
> Birth: 2026-07-23 20:17:57.981622024 +0100
> File: small-text-file.txt
> Size: 765 Blocks: 1 IO Block: 1024 regular file
> Device: 0,41 Inode: 5342460 Links: 1
> Access: (0664/-rw-rw-r--) Uid: ( 1027/ james) Gid: ( 1027/ james)
> Access: 2026-07-23 20:21:50.230425347 +0100
> Modify: 2026-07-23 20:21:50.226425401 +0100
> Change: 2026-07-23 20:21:50.226425401 +0100
> Birth: 2026-07-23 20:17:57.985621969 +0100
From eaa3ba5a63b569dbf1a4b1389963f734ebe7edd3 Mon Sep 17 00:00:00 2001
From: James Youngman <[email protected]>
Date: Thu, 23 Jul 2026 20:28:35 +0100
Subject: [PATCH] find: another fix for the still-broken -ls test.
The remaining problem is that the struct stat.st_blocks value for a
file depends on implementation details of the file system and so we
cannot expect to create a file and check the resuting st_blocks value
against a fixed expectation.
* tests/find/ls-format-file.sh (AWK script): do not check the value in
$2, the block count, as this will vary across file systems. Record in
the test log the output of various other commands which examine the
output of -printf %b, -printf %k and -ls for the file with
POSIXLY_CORRECT set and with it unset.
(with_512_byte_blocks): shell function which sets up the environment
such that GNU find will use 512-byte blocks and runs a command.
---
tests/find/ls-format-file.sh | 59 +++++++++++++++++++++++++-----------
1 file changed, 42 insertions(+), 17 deletions(-)
diff --git a/tests/find/ls-format-file.sh b/tests/find/ls-format-file.sh
index cee3737e..b568350b 100755
--- a/tests/find/ls-format-file.sh
+++ b/tests/find/ls-format-file.sh
@@ -22,6 +22,10 @@ print_ver_ find
# Ensure that find does not generally skip warnings due to POSIX requirements.
unset POSIXLY_CORRECT
+with_512_byte_blocks() {
+ env -u BLOCK_SIZE -u BLOCKSIZE POSIXLY_CORRECT=1 "$@"
+}
+
# We want to check the date in the output of -ls, so ensure we're
# dealing with the C locale only.
LC_ALL=C
@@ -121,16 +125,11 @@ then
skip_ "failed to change group of ${testfile} to ${group_owner}"
fi
-# Remember the file's inode number and block count.
+# Remember the file's inode number.
inum="$( find "${testfile}" -printf '%i\n' )"
-blocks_expected="$( ls -s "${testfile}" | sed -e "s/${testfile}//g" )"
-# The system's value of BLOCKSIZE is implementation-dependent
-# ("ls -k" forces ls to use 1KiB blocks, but -ls is intended
-# to look like the output of ls -dils, without -k)
-
# Generate the ls output.
-find "${testfile}" -ls > output.txt
+with_512_byte_blocks find "${testfile}" -ls > output.txt
# Show the reader of the test log what the output was.
echo "output of find ${testfile} -ls:"
@@ -172,7 +171,6 @@ awk < output.txt \
-v ME="${ME_}" \
-v filename_expected="${testfile}" \
-v inodenum="${inum}" \
- -v blocks_expected="${blocks_expected}" \
-v filesize="${filesize}" \
-v uowner="$(id -un)" \
-v gowner="${group_owner}" '
@@ -192,7 +190,7 @@ NR == 1 {
rv=0
st_ino=$1;
- st_blocks=$2;
+ # No check here for the block count, see the -printf tests below
symbolic_st_mode="" $3;
st_nlink=$4;
st_uid=$5;
@@ -211,13 +209,8 @@ NR == 1 {
printf("%s: failed test: expected inode number %d, got %s\n", ME, inodenum, $1);
}
- # field 2: size in blocks
- if (st_blocks != blocks_expected) {
- rv=1
- printf("%s: failed test: expected block count %d got %d\n", ME, blocks_expected, st_blocks);
- } else {
- printf("%s: block count %d looks OK\n", ME, st_blocks);
- }
+ # field 2: size in blocks. We do not check this because the file will take up
+ # a different number of blocks on different filesystems.
# field 3 is the symbolic mode; we allow a final +
# in case there is somehow a non-default ACL on the file.
@@ -296,6 +289,38 @@ then
fi
+##################################################################################
+# Generate various kinds of output which might help with after-the-fact debugging.
+##################################################################################
+
+for env_var_assignment in POSIXLY_CORRECT=1 UNRELATED_VAR=0
+do
+ for size_format_spec in "%6b" "%6k"
+ do
+ format_str="%9i ${size_format_spec} %M %3n %-8u %-8g %8s %3Tb %2Td %5TY %p\n"
+ printf 'with environment variable setting %s and output format %s:\n' "${env_var_assignment}" "${format_str}"
+ env -u POSIXLY_CORRECT env "${env_var_assignment}" find "${testfile}" -printf "${format_str}"
+ echo
+ done
+ printf 'with environment variable setting %s and -ls:\n' "${env_var_assignment}"
+ env -u POSIXLY_CORRECT env "${env_var_assignment}" find "${testfile}" -ls
+ echo
+
+ format_str='%b %k %s %p\n'
+ printf 'with environment variable setting %s and -printf %s:\n' "${env_var_assignment}" "${format_str}"
+ env -u POSIXLY_CORRECT env "${env_var_assignment}" find "${testfile}" -printf "${format_str}"
+ echo
+done
+
+echo "stat(1) output for ${testfile}:"
+stat "${testfile}"
+
+echo "strace -ve statx trace from running stat(1) on ${testfile}:"
+strace -ve statx stat "${testfile}"
+
+find "${testfile}" -printf 'File system type of %p is %F\n'
+
+
###############################################################################
# Checks on the output generated by -ls, including the spaces between
# fields. If these tests break, this may indicate a bug in find, or
@@ -309,7 +334,7 @@ fi
# Generate "by hand" in the file printf-output.txt some output which
# should match the output of -ls.
rm -f -- printf-output.txt
-if ! find "${testfile}" -printf '%9i %6b %M %3n %-8u %-8g %8s %3Tb %2Td %5TY %p\n' > printf-output.txt
+if ! with_512_byte_blocks find "${testfile}" -printf '%9i %6b %M %3n %-8u %-8g %8s %3Tb %2Td %5TY %p\n' > printf-output.txt
then
framework_failure_ "unable to create printf-output.txt"
fi
--
2.47.3