[PATCH 03/33] ext/052: use popdir.pl for much faster directory creation

Darrick J. Wong
2025-10-29T01:21:13Z

This program wants to create a large directory htree index, and it
doesn't care what the children are. Reduce the runtime of this program
by 2/3 by using hardlinks when possible instead of allocating 400,000
new child files. This is an even bigger win for fuse2fs, which has a
runtime of 6.5h.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
src/popdir.pl | 9 ++++++++-
tests/ext4/052 | 4 +++-
2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/popdir.pl b/src/popdir.pl
index 0104957a3c941e..251500c2255f33 100755
--- a/src/popdir.pl
+++ b/src/popdir.pl
@@ -72,7 +72,14 @@ for ($i = $start; $i <= $end; $i += $incr) {
} elsif ($hardlink && $i > $start) {
# hardlink everything after the first file
$verbose && print "ln $link_fname $fname\n";
- link $link_fname, $fname;
+ if (not link $link_fname, $fname) {
+ # if hardlink fails, create a new file in case the old
+ # file reached maximum link count
+ $verbose && print "touch $fname\n";
+ open(DONTCARE, ">$fname") or die("touch $fname");
+ close(DONTCARE);
+ $link_fname = $fname;
+ }
} elsif (($i % 100) < $file_pct) {
# create a file
$verbose && print "touch $fname\n";
diff --git a/tests/ext4/052 b/tests/ext4/052
index 0df8a651383ec7..18b2599f43c7ba 100755
--- a/tests/ext4/052
+++ b/tests/ext4/052
@@ -56,7 +56,9 @@ mkdir -p $loop_mnt
_mount -o loop $fs_img $loop_mnt > /dev/null 2>&1 || \
_fail "Couldn't do initial mount"

-if ! $here/src/dirstress -c -d $loop_mnt -p 1 -f 400000 -C >$tmp.out 2>&1
+# popdir.pl is much faster than creating 400k file with dirstress
+mkdir "${loop_mnt}/stress.0"
+if ! $here/src/popdir.pl --dir "${loop_mnt}/stress.0" --end 400000 --hardlink --format "XXXXXXXXXXXX.%ld" > $tmp.out 2>&1
then
echo " dirstress failed"
cat $tmp.out >> $seqres.full