Re: [PATCH] ext4, jbd2: abort journal on file data write error under data_err=abort
From: Zhang Yi
Date: Tue Jun 23 2026 - 22:42:57 EST
On 6/24/2026 12:11 AM, Aditya Srivastava wrote:
> From: Aditya Prakash Srivastava <aditya.ansh182@xxxxxxxxx>
>
> The "data_err=abort" mount option in ext4 is designed to abort the
> journal and force the filesystem into read-only mode if a file data
> writeback failure is detected (to prevent silent data loss and stale
> data exposure).
>
> However, in standard data=ordered mode, file data writeback is executed
> and waited for during transaction commit in
> journal_finish_inode_data_buffers(). When
> filemap_fdatawait_range_keep_errors() detects and returns a data writeback
> error (e.g. -EIO), JBD2 merely prints a warning message and then
> discards the error. This results in the transaction committing
> successfully, exposing stale/corrupted data and defeating the purpose
> of the data_err=abort option.
Hi, Aditya!
Thanks for the patch. However, after commit ce51afb8cc5e ("ext4: abort
journal on data writeback failure if in data_err=abort mode"), has
already moved the abort logic into the end IO workqueue. In that case,
it seems the journal abort would be triggered properly upon a data
writeback failure. The issue described in this Bugzilla looks like an
outdated one. Have you encountered any actual issues for now?
Thanks,
Yi.
>
> Fix this by:
> 1. Defining a new JBD2 configuration flag, JBD2_ABORT_ON_DATA_ERR.
> 2. In JBD2, if JBD2_ABORT_ON_DATA_ERR is set, abort the transaction commit
> and the journal thread via jbd2_journal_abort() if writeback fails.
> 3. In ext4, configure JBD2_ABORT_ON_DATA_ERR on the journal based on the
> ext4 "data_err=abort" mount option in ext4_init_journal_params().
>
> Reported-by: Anthony Rebello <arebello@xxxxxxxxxx>
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=207729
> Suggested-by: Jan Kara <jack@xxxxxxx>
> Signed-off-by: Aditya Prakash Srivastava <aditya.ansh182@xxxxxxxxx>
> ---
> fs/ext4/super.c | 4 ++++
> fs/jbd2/commit.c | 2 ++
> include/linux/jbd2.h | 1 +
> 3 files changed, 7 insertions(+)
>
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index 7283108d7609..de34490a5b68 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -5875,6 +5875,10 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal)
> journal->j_flags |= JBD2_BARRIER;
> else
> journal->j_flags &= ~JBD2_BARRIER;
> + if (test_opt(sb, DATA_ERR_ABORT))
> + journal->j_flags |= JBD2_ABORT_ON_DATA_ERR;
> + else
> + journal->j_flags &= ~JBD2_ABORT_ON_DATA_ERR;
> /*
> * Always enable journal cycle record option, letting the journal
> * records log transactions continuously between each mount.
> diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
> index d8577725a2fb..49acc9d0809e 100644
> --- a/fs/jbd2/commit.c
> +++ b/fs/jbd2/commit.c
> @@ -768,6 +768,8 @@ void jbd2_journal_commit_transaction(journal_t *journal)
> printk(KERN_WARNING
> "JBD2: Detected IO errors %d while flushing file data on %s\n",
> err, journal->j_devname);
> + if (journal->j_flags & JBD2_ABORT_ON_DATA_ERR)
> + jbd2_journal_abort(journal, err);
> err = 0;
> }
>
> diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
> index 7e785aa6d35d..e39679656de6 100644
> --- a/include/linux/jbd2.h
> +++ b/include/linux/jbd2.h
> @@ -1410,6 +1410,7 @@ JBD2_FEATURE_INCOMPAT_FUNCS(fast_commit, FAST_COMMIT)
> #define JBD2_FLUSHED 0x008 /* The journal superblock has been flushed */
> #define JBD2_LOADED 0x010 /* The journal superblock has been loaded */
> #define JBD2_BARRIER 0x020 /* Use IDE barriers */
> +#define JBD2_ABORT_ON_DATA_ERR 0x040 /* Abort the journal on file data write errors */
> #define JBD2_CYCLE_RECORD 0x080 /* Journal cycled record log on
> * clean and empty filesystem
> * logging area */