[RFC] ext4: orphan tracking after a failed truncate
From: Guanghui Yang
Date: Sun Aug 09 2026 - 01:45:52 EST
Hi,
I am looking for clarification about the intended orphan handling when a
truncate fails after its journal transaction has been restarted.
I reproduced the following using the official kernel.org Linux v6.14
source:
- a large truncate naturally triggers jbd2_handle_restart()
- after the restart, a block-layer fault makes ext4_read_bh() return -EIO
- ext4_ext_truncate() and the truncate syscall return -EIO
- the restarted transaction is committed on disk
- before journal replay, e2fsck -fn reports that the orphan file contains
no orphan entries
- the inode has i_size 0 but still has allocated blocks beyond EOF
- mount-time journal recovery completes, but the inconsistency remains
In ext4_truncate(), an error from ext4_ext_truncate() jumps to out_stop.
For an inode with a nonzero link count, that path calls
ext4_orphan_del(handle, inode) regardless of the error. In this run, the
committed post-restart transaction contains the orphan-file block, and the
pre-recovery check reports that the orphan file is clean.
The comment above ext4_truncate() says that an incomplete truncate can be
restarted from ext4_orphan_cleanup() after a crash. Should the on-disk
orphan entry therefore be retained when block removal fails after the
entry has been added?
There is a second part to the recovery contract that I am unsure about.
The EIO marks the filesystem with EXT4_ERROR_FS, and
ext4_orphan_cleanup() skips orphan recovery in that state. Is an e2fsck
repair the intended outcome for this class of error, or should ext4 keep
enough orphan state for mount-time recovery to finish the truncate?
OpenAI Codex (GPT-5)
assisted with reviewing the failure path, preparing the test procedure,
and drafting this RFC. I reviewed the analysis and ran the reproduction.
Assisted-by: Codex:gpt-5