Linux EXT4 FS development
 help / color / mirror / Atom feed
* [RFC] ext4: orphan tracking after a failed truncate
@ 2026-08-09  5:45 Guanghui Yang
  2026-08-17 15:56 ` Jan Kara
  0 siblings, 1 reply; 4+ messages in thread
From: Guanghui Yang @ 2026-08-09  5:45 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Andreas Dilger, Baokun Li, Jan Kara, Ojaswin Mujoo,
	Ritesh Harjani, Zhang Yi, linux-ext4, linux-kernel, Guanghui Yang

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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC] ext4: orphan tracking after a failed truncate
  2026-08-09  5:45 [RFC] ext4: orphan tracking after a failed truncate Guanghui Yang
@ 2026-08-17 15:56 ` Jan Kara
  2026-08-18  3:04   ` Theodore Tso
  2026-08-18  4:41   ` Zhang Yi
  0 siblings, 2 replies; 4+ messages in thread
From: Jan Kara @ 2026-08-17 15:56 UTC (permalink / raw)
  To: Guanghui Yang
  Cc: Theodore Ts'o, Andreas Dilger, Baokun Li, Jan Kara,
	Ojaswin Mujoo, Ritesh Harjani, Zhang Yi, linux-ext4, linux-kernel

Hi!

Quick note for Ted: these kind of reports where LLM complains about
inconsistencies after IO errors or other catastrophic failures are rather
frequent. I think that would be a good candidate for an ext4 specific
prompt for LLMs to explain to it that after metadata IO failure filesystem
inconsistencies are expected and we should just strive to limit lost data.

On Sun 09-08-26 13:45:09, Guanghui Yang wrote:
> 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?

This is expected. If you hit IO error on metadata, all bets are off wrt
filesystem consistency. Running e2fsck to fix the filesystem is the only
way to establish filesystem consistency again. So there's nothing to fix in
the kernel really as the fact that an inode with blocks beyond EOF is not
on orphan list is just a little nuissance...

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC] ext4: orphan tracking after a failed truncate
  2026-08-17 15:56 ` Jan Kara
@ 2026-08-18  3:04   ` Theodore Tso
  2026-08-18  4:41   ` Zhang Yi
  1 sibling, 0 replies; 4+ messages in thread
From: Theodore Tso @ 2026-08-18  3:04 UTC (permalink / raw)
  To: Jan Kara
  Cc: Guanghui Yang, Andreas Dilger, Baokun Li, Ojaswin Mujoo,
	Ritesh Harjani, Zhang Yi, linux-ext4, linux-kernel

On Mon, Aug 17, 2026 at 05:56:24PM -0500, Jan Kara wrote:
> This is expected. If you hit IO error on metadata, all bets are off wrt
> filesystem consistency. Running e2fsck to fix the filesystem is the only
> way to establish filesystem consistency again. So there's nothing to fix in
> the kernel really as the fact that an inode with blocks beyond EOF is not
> on orphan list is just a little nuissance...

If we want to let the system administrator know that they should run
fsck, then perhaps we should call ext4_error_inode() and return
EFSCORRUPTED instead of EIO.  In general, if we are in the middle of
modifying file system metadata, and we run into an error, we should
either try to back out the change so the file system is consistent.

HOWEVER, in this case, blocks beyond EOF is not really a file system
consistency issue, since you can get blocks beyond EOF by using the
fallocate system call with FALLOC_FL_KEEP_SIZE flag.

> Quick note for Ted: these kind of reports where LLM complains about
> inconsistencies after IO errors or other catastrophic failures are rather
> frequent. I think that would be a good candidate for an ext4 specific
> prompt for LLMs to explain to it that after metadata IO failure filesystem
> inconsistencies are expected and we should just strive to limit lost data.

Unfortunately, it's a bit tricky to do that.  The problem is that
LLM's aren't consistent about how they handle AGENTS.md or CLAUDE.md
file.  Despite AGENTS.md being a standard promulgated by the LF's
Agentic AI Foundation, not all LLM harneses will read a AGENTS.md file
located a directory outside of the repository root directory.

So if we put LLM Harness directives in fs/ext4/AGENTS.md, some
harnesses (including Github's Copilot or OpenAI Codex) won't read it
unless there is an explicit request read it in the top-level AGENTS.md
file.  We could have the top-level AGENTS.md say that for any
file-system related code, please read fs/AGENTS.md, and then the
fs/AGENTS.md file could say that in case of a btrfs-related issue,
read fs/btrfs/AGENTS.md, and if it's an ext4-related, to please read
fs/ext4/AGENTS.md, etc.  It very quickly becomes a mess.

Worse, Claude has steadfastly refused to honor the AGENTS.md file
(although at least it will read CLAUDE.md file in subdirectories).  So
we'd have to have CLAUDE.md file be a symlink to AGENTS.md, or to have
an instruction in CLAUDE.md to read AGENTS.md.

Probably the best we can do is to put generic documentation in
Documentation/filesystems/ext4, meant for both humans and LLM's,
describing ext4's error handling philosophy, and hope the LLM
harnesses bothers to read it.

						- Ted



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC] ext4: orphan tracking after a failed truncate
  2026-08-17 15:56 ` Jan Kara
  2026-08-18  3:04   ` Theodore Tso
@ 2026-08-18  4:41   ` Zhang Yi
  1 sibling, 0 replies; 4+ messages in thread
From: Zhang Yi @ 2026-08-18  4:41 UTC (permalink / raw)
  To: Jan Kara, Guanghui Yang
  Cc: Theodore Ts'o, Andreas Dilger, Baokun Li, Ojaswin Mujoo,
	Ritesh Harjani, linux-ext4, linux-kernel

On 8/17/2026 11:56 PM, Jan Kara wrote:
> Hi!
> 
> Quick note for Ted: these kind of reports where LLM complains about
> inconsistencies after IO errors or other catastrophic failures are rather
> frequent. I think that would be a good candidate for an ext4 specific
> prompt for LLMs to explain to it that after metadata IO failure filesystem
> inconsistencies are expected and we should just strive to limit lost data.
> 
> On Sun 09-08-26 13:45:09, Guanghui Yang wrote:
>> 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?
> 
> This is expected. If you hit IO error on metadata, all bets are off wrt
> filesystem consistency. Running e2fsck to fix the filesystem is the only
> way to establish filesystem consistency again. So there's nothing to fix in
> the kernel really as the fact that an inode with blocks beyond EOF is not
> on orphan list is just a little nuissance...
> 
> 								Honza

I think we might want to add a small qualifier here: this is only expected
behavior under errors=continue. For the remount-ro case, we immediately
abort the journal to prevent writing out inconsistent metadata after an I/O
error, which helps contain the damage. So after journal replay, the file
system should still be able to maintain a consistent state.

Thanks,
Yi.




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-18  4:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-09  5:45 [RFC] ext4: orphan tracking after a failed truncate Guanghui Yang
2026-08-17 15:56 ` Jan Kara
2026-08-18  3:04   ` Theodore Tso
2026-08-18  4:41   ` Zhang Yi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox