Linux EXT4 FS development
 help / color / mirror / Atom feed
From: Baokun Li <libaokun@linux.alibaba.com>
To: linux-ext4@vger.kernel.org
Cc: tytso@mit.edu, adilger.kernel@dilger.ca, jack@suse.cz,
	yi.zhang@huawei.com, ojaswin@linux.ibm.com,
	ritesh.list@gmail.com
Subject: [PATCH e2fsprogs 5/5] tests: add orphan-cleanup flush regression test
Date: Tue, 14 Jul 2026 14:31:36 +0800	[thread overview]
Message-ID: <20260714063136.1284287-6-libaokun@linux.alibaba.com> (raw)
In-Reply-To: <20260714063136.1284287-1-libaokun@linux.alibaba.com>

Add f_orphan_flush_abort, which drives e2fsck directly:

1. Build an ext4 image whose inode 12 is an orphan (links_count 0,
   s_last_orphan = 12).
2. Run e2fsck with a nonexistent bad-blocks file so that orphan
   cleanup runs first and then read_bad_blocks_file aborts the run
   via exit() before the normal superblock write-back.
3. Check that s_last_orphan is 0 on disk afterwards.

Without the flush after orphan cleanup, s_last_orphan stays stale on
disk (still 12) while the orphan inode has already been written back,
which the kernel rejects as a "bad orphan inode" on next mount.

Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
 tests/f_orphan_flush_abort/expect.1 |  7 ++++
 tests/f_orphan_flush_abort/name     |  1 +
 tests/f_orphan_flush_abort/script   | 61 +++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+)
 create mode 100644 tests/f_orphan_flush_abort/expect.1
 create mode 100644 tests/f_orphan_flush_abort/name
 create mode 100644 tests/f_orphan_flush_abort/script

diff --git a/tests/f_orphan_flush_abort/expect.1 b/tests/f_orphan_flush_abort/expect.1
new file mode 100644
index 000000000000..0a6d09f16e36
--- /dev/null
+++ b/tests/f_orphan_flush_abort/expect.1
@@ -0,0 +1,7 @@
+Clearing orphaned inode 12 (uid=0, gid=0, mode=0100644, size=8192)
+read_bad_blocks_file: No such file or directory while trying to open test.img
+
+test.img: ***** FILE SYSTEM WAS MODIFIED *****
+Exit status is 9
+Orphan before e2fsck: 12
+Orphan after e2fsck: 0 (cleared)
diff --git a/tests/f_orphan_flush_abort/name b/tests/f_orphan_flush_abort/name
new file mode 100644
index 000000000000..c9292546c6dd
--- /dev/null
+++ b/tests/f_orphan_flush_abort/name
@@ -0,0 +1 @@
+orphan cleanup superblock flush survives a later abort
diff --git a/tests/f_orphan_flush_abort/script b/tests/f_orphan_flush_abort/script
new file mode 100644
index 000000000000..9c18011b40db
--- /dev/null
+++ b/tests/f_orphan_flush_abort/script
@@ -0,0 +1,61 @@
+if ! test -x $DEBUGFS_EXE; then
+	echo "$test_name: $test_description: skipped (no debugfs)"
+	return 0
+fi
+
+TEST_DATA="$test_name.tmp"
+OUT=$test_name.log
+
+dd if=/dev/zero of=$TEST_DATA bs=8k count=1 > /dev/null 2>&1
+
+$MKE2FS -Fq -t ext4 -o Linux $TMPFILE 4M > /dev/null 2>&1
+
+# Create an orphan inode: testfile becomes inode 12 (the first regular inode
+# on a fresh fs), drop its link count to 0 and point s_last_orphan at it so
+# e2fsck will run orphan cleanup.
+$DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1
+write $TEST_DATA testfile
+set_inode_field testfile links_count 0
+set_super_value last_orphan 12
+unlink testfile
+quit
+EOF
+
+ORPHAN_BEFORE=$($DUMPE2FS $TMPFILE 2>&1 | grep -E "First orphan inode" | awk '{print $NF}')
+
+cp /dev/null $OUT
+
+# Run e2fsck with a nonexistent bad blocks file.  Orphan cleanup runs first
+# and clears s_last_orphan, then read_bad_blocks_file fails and e2fsck aborts
+# via exit() before the normal superblock write-back.  The fix flushes the
+# superblock right after orphan cleanup, so s_last_orphan is 0 on disk even
+# though the run aborted; without it the disk keeps a stale s_last_orphan
+# while the orphan inode has already been written back, which the kernel
+# rejects as a "bad orphan inode" on next mount.
+$FSCK -yf -l /nonexistent/bad_blocks_file $TMPFILE > $OUT.new 2>&1
+status=$?
+echo "Exit status is $status" >> $OUT.new
+sed -f $cmd_dir/filter.sed -e "s|$TMPFILE|test.img|g" $OUT.new > $OUT
+rm -f $OUT.new
+
+ORPHAN_AFTER=$($DUMPE2FS $TMPFILE 2>&1 | grep -E "First orphan inode" | awk '{print $NF}')
+
+echo "Orphan before e2fsck: $ORPHAN_BEFORE" >> $OUT
+if [ -z "$ORPHAN_AFTER" ]; then
+	echo "Orphan after e2fsck: 0 (cleared)" >> $OUT
+else
+	echo "Orphan after e2fsck: $ORPHAN_AFTER (BUG: should be 0!)" >> $OUT
+fi
+
+cmp -s $OUT $test_dir/expect.1
+status=$?
+if [ "$status" -eq 0 ]; then
+	echo "$test_name: $test_description: ok"
+	touch $test_name.ok
+else
+	echo "$test_name: $test_description: failed"
+	diff $DIFF_OPTS $test_dir/expect.1 $OUT > $test_name.failed
+fi
+
+rm -f $TEST_DATA
+unset OUT TEST_DATA
-- 
2.43.7


      parent reply	other threads:[~2026-07-14  6:31 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14  6:31 [PATCH e2fsprogs 0/5] fsck: fix stale "bad orphan inode" after fsck runs Baokun Li
2026-07-14  6:31 ` [PATCH e2fsprogs 1/5] fsck: consume -l option instead of passing to e2fsck Baokun Li
2026-07-14  6:31 ` [PATCH e2fsprogs 2/5] fsck: fix -C fd option parsing when fd is a separate argument Baokun Li
2026-07-14  6:31 ` [PATCH e2fsprogs 3/5] e2fsck: flush superblock immediately after orphan cleanup Baokun Li
2026-07-14  6:31 ` [PATCH e2fsprogs 4/5] tests: add fsck option-parsing regression test Baokun Li
2026-07-14  6:31 ` Baokun Li [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260714063136.1284287-6-libaokun@linux.alibaba.com \
    --to=libaokun@linux.alibaba.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=jack@suse.cz \
    --cc=linux-ext4@vger.kernel.org \
    --cc=ojaswin@linux.ibm.com \
    --cc=ritesh.list@gmail.com \
    --cc=tytso@mit.edu \
    --cc=yi.zhang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox