Skip to content

Commit d99748e

Browse files
zhangyi089tytso
authored andcommitted
ext4: fix LOGFLUSH shutdown ordering to allow ordered-mode data writeback
In EXT4_GOING_FLAGS_LOGFLUSH mode, the EXT4_FLAGS_SHUTDOWN flag was set before calling ext4_force_commit(). This caused ordered-mode data writeback (triggered by journal commit) to fail with -EIO, since ext4_do_writepages() checks for the shutdown flag. The journal would then be aborted prematurely before the commit could succeed. Fix this by calling ext4_force_commit() first, then setting the shutdown flag, so that pending data can be written back correctly. Note that moving ext4_force_commit() before setting the shutdown flag creates a small window in which new writes may occur and generate new journal transactions. When the journal is subsequently aborted, the new transactions will not be able to write to disk. This is intentional because LOGFLUSH's semantics are to flush pre-existing journal entries before shutdown, not to guarantee atomicity for writes that race with the ioctl. Fixes: 783d948 ("ext4: add EXT4_IOC_GOINGDOWN ioctl") Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Baokun Li <libaokun@linux.alibaba.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20260424104201.1930823-1-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent 4bdba81 commit d99748e

1 file changed

Lines changed: 9 additions & 3 deletions

File tree

fs/ext4/ioctl.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -830,11 +830,17 @@ int ext4_force_shutdown(struct super_block *sb, u32 flags)
830830
bdev_thaw(sb->s_bdev);
831831
break;
832832
case EXT4_GOING_FLAGS_LOGFLUSH:
833+
/*
834+
* Call ext4_force_commit() before setting EXT4_FLAGS_SHUTDOWN.
835+
* This is because in data=ordered mode, journal commit
836+
* triggers data writeback which fails if shutdown is already
837+
* set, causing the journal to be aborted prematurely before
838+
* the commit succeeds.
839+
*/
840+
(void) ext4_force_commit(sb);
833841
set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
834-
if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) {
835-
(void) ext4_force_commit(sb);
842+
if (sbi->s_journal && !is_journal_aborted(sbi->s_journal))
836843
jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN);
837-
}
838844
break;
839845
case EXT4_GOING_FLAGS_NOLOGFLUSH:
840846
set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);

0 commit comments

Comments
 (0)