Fast commits only log operations that have dedicated replay support.
EXT4_IOC_GROUP_EXTEND grows the filesystem to the end of the last
block group and updates the same on-disk metadata without going
through the fast commit tracking paths.
In practice these operations are rare and usually followed by further
updates, but mixing them into a fast commit makes the overall
semantics harder to reason about and risks replay gaps if new call
sites appear.
Teach ext4 to mark the filesystem fast-commit ineligible when
EXT4_IOC_GROUP_EXTEND grows the filesystem.
This forces those transactions to fall back to a full commit,
ensuring that the group extension changes are captured by the normal
journal rather than partially encoded in fast commit TLVs.
This change should not affect common workloads but makes online
resize via GROUP_EXTEND safer and easier to reason about under fast
commit.
Testing:
1. prepare:
dd if=/dev/zero of=/root/fc_resize.img bs=1M count=0 seek=256
mkfs.ext4 -O fast_commit -F /root/fc_resize.img
mkdir -p /mnt/fc_resize && mount -t ext4 -o loop /root/fc_resize.img /mnt/fc_resize
2. Extended the filesystem to the end of the last block group using a
helper that calls EXT4_IOC_GROUP_EXTEND on the mounted filesystem
and checked fc_info:
./group_extend_helper /mnt/fc_resize
cat /proc/fs/ext4/loop0/fc_info
shows the "Resize" ineligible reason increased.
3. Fsynced a file on the resized filesystem and confirmed that the fast
commit ineligible counter incremented for the resize transaction:
touch /mnt/fc_resize/file
/root/fsync_file /mnt/fc_resize/file
sync
cat /proc/fs/ext4/loop0/fc_info
Signed-off-by: Li Chen <me@linux.beauty>
---
fs/ext4/ioctl.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 57b47b9843f3..ce92652f8332 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -1608,6 +1608,8 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count);
if (EXT4_SB(sb)->s_journal) {
+ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_RESIZE,
+ NULL);
jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal, 0);
jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
--
2.51.0
On Thu, Dec 11, 2025 at 07:51:42PM +0800, Li Chen wrote: > Fast commits only log operations that have dedicated replay support. > EXT4_IOC_GROUP_EXTEND grows the filesystem to the end of the last > block group and updates the same on-disk metadata without going > through the fast commit tracking paths. > In practice these operations are rare and usually followed by further > updates, but mixing them into a fast commit makes the overall > semantics harder to reason about and risks replay gaps if new call > sites appear. > > Teach ext4 to mark the filesystem fast-commit ineligible when > EXT4_IOC_GROUP_EXTEND grows the filesystem. > This forces those transactions to fall back to a full commit, > ensuring that the group extension changes are captured by the normal > journal rather than partially encoded in fast commit TLVs. > This change should not affect common workloads but makes online > resize via GROUP_EXTEND safer and easier to reason about under fast > commit. > > Testing: > 1. prepare: > dd if=/dev/zero of=/root/fc_resize.img bs=1M count=0 seek=256 > mkfs.ext4 -O fast_commit -F /root/fc_resize.img > mkdir -p /mnt/fc_resize && mount -t ext4 -o loop /root/fc_resize.img /mnt/fc_resize > 2. Extended the filesystem to the end of the last block group using a > helper that calls EXT4_IOC_GROUP_EXTEND on the mounted filesystem > and checked fc_info: > ./group_extend_helper /mnt/fc_resize > cat /proc/fs/ext4/loop0/fc_info > shows the "Resize" ineligible reason increased. > 3. Fsynced a file on the resized filesystem and confirmed that the fast > commit ineligible counter incremented for the resize transaction: > touch /mnt/fc_resize/file > /root/fsync_file /mnt/fc_resize/file > sync > cat /proc/fs/ext4/loop0/fc_info > > Signed-off-by: Li Chen <me@linux.beauty> I'm curious what version of the kernel you were testing against? I needed to mnake the final fix up to allow the patch to compile: diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index 9354083222b1..ce1f738dff93 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c @@ -321,7 +321,8 @@ static int mext_move_extent(struct mext_data *mext, u64 *m_len) ret = PTR_ERR(handle); goto out; } - ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_MOVE_EXT, handle); + ext4_fc_mark_ineligible(orig_inode->i_sb, EXT4_FC_REASON_MOVE_EXT, + handle); ret = mext_move_begin(mext, folio, &move_type); if (ret) - Ted
Hi Theodore, Thanks for your reply. > On Thu, Dec 11, 2025 at 07:51:42PM +0800, Li Chen wrote: > > Fast commits only log operations that have dedicated replay support. > > EXT4_IOC_GROUP_EXTEND grows the filesystem to the end of the last > > block group and updates the same on-disk metadata without going > > through the fast commit tracking paths. > > In practice these operations are rare and usually followed by further > > updates, but mixing them into a fast commit makes the overall > > semantics harder to reason about and risks replay gaps if new call > > sites appear. > > > > Teach ext4 to mark the filesystem fast-commit ineligible when > > EXT4_IOC_GROUP_EXTEND grows the filesystem. > > This forces those transactions to fall back to a full commit, > > ensuring that the group extension changes are captured by the normal > > journal rather than partially encoded in fast commit TLVs. > > This change should not affect common workloads but makes online > > resize via GROUP_EXTEND safer and easier to reason about under fast > > commit. > > > > Testing: > > 1. prepare: > > dd if=/dev/zero of=/root/fc_resize.img bs=1M count=0 seek=256 > > mkfs.ext4 -O fast_commit -F /root/fc_resize.img > > mkdir -p /mnt/fc_resize && mount -t ext4 -o loop /root/fc_resize.img /mnt/fc_resize > > 2. Extended the filesystem to the end of the last block group using a > > helper that calls EXT4_IOC_GROUP_EXTEND on the mounted filesystem > > and checked fc_info: > > ./group_extend_helper /mnt/fc_resize > > cat /proc/fs/ext4/loop0/fc_info > > shows the "Resize" ineligible reason increased. > > 3. Fsynced a file on the resized filesystem and confirmed that the fast > > commit ineligible counter incremented for the resize transaction: > > touch /mnt/fc_resize/file > > /root/fsync_file /mnt/fc_resize/file > > sync > > cat /proc/fs/ext4/loop0/fc_info > > > > Signed-off-by: Li Chen <me@linux.beauty> > > I'm curious what version of the kernel you were testing against? I > needed to mnake the final fix up to allow the patch to compile: I'm sorry I didn't mention the kernel version in the cover letter. This patchset is built against 7d0a66e4bb90 (tag: v6.18) Linux 6.18. Regards, Li > diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c > index 9354083222b1..ce1f738dff93 100644 > --- a/fs/ext4/move_extent.c > +++ b/fs/ext4/move_extent.c > @@ -321,7 +321,8 @@ static int mext_move_extent(struct mext_data *mext, u64 *m_len) > ret = PTR_ERR(handle); > goto out; > } > - ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_MOVE_EXT, handle); > + ext4_fc_mark_ineligible(orig_inode->i_sb, EXT4_FC_REASON_MOVE_EXT, > + handle); > > ret = mext_move_begin(mext, folio, &move_type); > if (ret) > > - Ted >
On Sun, Jan 18, 2026 at 04:58:57PM -1000, Theodore Tso wrote:
>
> I'm curious what version of the kernel you were testing against? I
> needed to mnake the final fix up to allow the patch to compile:
Oops, sorry, I replied to the wrong patch. This fix is relevant to:
[RFC 3/5] ext4: mark move extents fast-commit ineligible
- Ted
© 2016 - 2026 Red Hat, Inc.