public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/5] ext4: mark more ops fast-commit ineligible
@ 2025-12-11 11:51 Li Chen
  2025-12-11 11:51 ` [RFC 1/5] ext4: mark inode format migration " Li Chen
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Li Chen @ 2025-12-11 11:51 UTC (permalink / raw)
  To: Theodore Ts'o, Andreas Dilger, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-ext4, linux-kernel,
	linux-trace-kernel

ext4 fast commit only logs operations with replay support. This series
marks a few more operations as fast-commit ineligible and accounts
them via fc_info so behaviour under fast commit is easier to reason
about.

Testing was done in a QEMU guest on loopback ext4 filesystems created
with -O fast_commit[/,verity] by exercising each operation and checking
/proc/fs/ext4/*/fc_info for the corresponding ineligible reason and
ineligible commit counters. Detailed steps are in each commit's message.

Li Chen (5):
  ext4: mark inode format migration fast-commit ineligible
  ext4: mark fs-verity enable fast-commit ineligible
  ext4: mark move extents fast-commit ineligible
  ext4: mark group add fast-commit ineligible
  ext4: mark group extend fast-commit ineligible

 fs/ext4/fast_commit.c       |  3 +++
 fs/ext4/fast_commit.h       |  3 +++
 fs/ext4/ioctl.c             |  3 +++
 fs/ext4/migrate.c           | 12 ++++++++++++
 fs/ext4/move_extent.c       |  1 +
 fs/ext4/verity.c            |  2 ++
 include/trace/events/ext4.h |  8 +++++++-
 7 files changed, 31 insertions(+), 1 deletion(-)

-- 
2.51.0


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

* [RFC 1/5] ext4: mark inode format migration fast-commit ineligible
  2025-12-11 11:51 [RFC 0/5] ext4: mark more ops fast-commit ineligible Li Chen
@ 2025-12-11 11:51 ` Li Chen
  2025-12-11 11:51 ` [RFC 2/5] ext4: mark fs-verity enable " Li Chen
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Li Chen @ 2025-12-11 11:51 UTC (permalink / raw)
  To: Theodore Ts'o, Andreas Dilger, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-ext4, linux-kernel,
	linux-trace-kernel
  Cc: Li Chen

Fast commits only log operations that have dedicated replay support.
Inode format migration (indirect<->extent layout changes via
EXT4_IOC_MIGRATE or toggling EXT4_EXTENTS_FL) rewrites the block mapping
representation without going through the fast commit tracking paths.
In practice these migrations 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_ext_migrate() or ext4_ind_migrate() start their journal transactions.
This forces those transactions to fall back to a full commit, ensuring
that the entire inode layout change is captured by the normal journal
rather than partially encoded in fast commit TLVs. This change should
not affect common workloads but makes format migrations safer and easier
to reason about under fast commit.

Testing:
1. prepare:
    dd if=/dev/zero of=/root/fc.img bs=1M count=0 seek=128
    mkfs.ext4 -O fast_commit -F /root/fc.img
    mkdir -p /mnt/fc && mount -t ext4 -o loop /root/fc.img /mnt/fc
2.  Created a test file and toggled the extents flag to exercise both
    ext4_ind_migrate() and ext4_ext_migrate():
    touch /mnt/fc/migtest
    chattr -e /mnt/fc/migtest
    chattr +e /mnt/fc/migtest
3. Verified fast-commit ineligible statistics:
    tail -n 1 /proc/fs/ext4/loop0/fc_info
    "Inode format migration":       2

Signed-off-by: Li Chen <me@linux.beauty>
---
 fs/ext4/fast_commit.c       |  1 +
 fs/ext4/fast_commit.h       |  1 +
 fs/ext4/migrate.c           | 12 ++++++++++++
 include/trace/events/ext4.h |  4 +++-
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
index fa66b08de999..afb28b3e52bb 100644
--- a/fs/ext4/fast_commit.c
+++ b/fs/ext4/fast_commit.c
@@ -2302,6 +2302,7 @@ static const char * const fc_ineligible_reasons[] = {
 	[EXT4_FC_REASON_FALLOC_RANGE] = "Falloc range op",
 	[EXT4_FC_REASON_INODE_JOURNAL_DATA] = "Data journalling",
 	[EXT4_FC_REASON_ENCRYPTED_FILENAME] = "Encrypted filename",
+	[EXT4_FC_REASON_MIGRATE] = "Inode format migration",
 };
 
 int ext4_fc_info_show(struct seq_file *seq, void *v)
diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h
index 3bd534e4dbbf..be3b84a74c32 100644
--- a/fs/ext4/fast_commit.h
+++ b/fs/ext4/fast_commit.h
@@ -97,6 +97,7 @@ enum {
 	EXT4_FC_REASON_FALLOC_RANGE,
 	EXT4_FC_REASON_INODE_JOURNAL_DATA,
 	EXT4_FC_REASON_ENCRYPTED_FILENAME,
+	EXT4_FC_REASON_MIGRATE,
 	EXT4_FC_REASON_MAX
 };
 
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 1b0dfd963d3f..96ab95167bd6 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -449,6 +449,12 @@ int ext4_ext_migrate(struct inode *inode)
 		retval = PTR_ERR(handle);
 		goto out_unlock;
 	}
+	/*
+	 * This operation rewrites the inode's block mapping layout
+	 * (indirect to extents) and is not tracked in the fast commit
+	 * log, so disable fast commits for this transaction.
+	 */
+	ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_MIGRATE, handle);
 	goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) *
 		EXT4_INODES_PER_GROUP(inode->i_sb)) + 1;
 	owner[0] = i_uid_read(inode);
@@ -630,6 +636,12 @@ int ext4_ind_migrate(struct inode *inode)
 		ret = PTR_ERR(handle);
 		goto out_unlock;
 	}
+	/*
+	 * This operation rewrites the inode's block mapping layout
+	 * (extents to indirect blocks) and is not tracked in the fast
+	 * commit log, so disable fast commits for this transaction.
+	 */
+	ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_MIGRATE, handle);
 
 	down_write(&EXT4_I(inode)->i_data_sem);
 	ret = ext4_ext_check_inode(inode);
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index a374e7ea7e57..8f75d41ae5ef 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -102,6 +102,7 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_RENAME_DIR);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_FALLOC_RANGE);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_INODE_JOURNAL_DATA);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_ENCRYPTED_FILENAME);
+TRACE_DEFINE_ENUM(EXT4_FC_REASON_MIGRATE);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
 
 #define show_fc_reason(reason)						\
@@ -115,7 +116,8 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
 		{ EXT4_FC_REASON_RENAME_DIR,	"RENAME_DIR"},		\
 		{ EXT4_FC_REASON_FALLOC_RANGE,	"FALLOC_RANGE"},	\
 		{ EXT4_FC_REASON_INODE_JOURNAL_DATA,	"INODE_JOURNAL_DATA"}, \
-		{ EXT4_FC_REASON_ENCRYPTED_FILENAME,	"ENCRYPTED_FILENAME"})
+		{ EXT4_FC_REASON_ENCRYPTED_FILENAME,	"ENCRYPTED_FILENAME"}, \
+		{ EXT4_FC_REASON_MIGRATE,		"MIGRATE"})
 
 TRACE_DEFINE_ENUM(CR_POWER2_ALIGNED);
 TRACE_DEFINE_ENUM(CR_GOAL_LEN_FAST);
-- 
2.51.0


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

* [RFC 2/5] ext4: mark fs-verity enable fast-commit ineligible
  2025-12-11 11:51 [RFC 0/5] ext4: mark more ops fast-commit ineligible Li Chen
  2025-12-11 11:51 ` [RFC 1/5] ext4: mark inode format migration " Li Chen
@ 2025-12-11 11:51 ` Li Chen
  2025-12-11 11:51 ` [RFC 3/5] ext4: mark move extents " Li Chen
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Li Chen @ 2025-12-11 11:51 UTC (permalink / raw)
  To: Theodore Ts'o, Andreas Dilger, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-ext4, linux-kernel,
	linux-trace-kernel
  Cc: Li Chen

Fast commits only log operations that have dedicated replay support.
Enabling fs-verity builds a Merkle tree and updates inode and orphan
state in ways that are not described by the fast commit replay tags.
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_end_enable_verity() starts its journal transaction.
This forces that transaction to fall back to a full commit, ensuring
that the fs-verity enable changes are captured by the normal journal
rather than partially encoded in fast commit TLVs.
This change should not affect common workloads but makes fs-verity
enable safer and easier to reason about under fast commit.

Testing:
1. prepare:
    dd if=/dev/zero of=/root/fc_verity.img bs=1M count=0 seek=128
    mkfs.ext4 -O fast_commit,verity -F /root/fc_verity.img
    mkdir -p /mnt/fc_verity && mount -t ext4 -o loop /root/fc_verity.img /mnt/fc_verity
2. Enabled fs-verity on a file and verified reason accounting:
    echo "data" > /mnt/fc_verity/verityfile
    /root/enable_verity /mnt/fc_verity/verityfile
    sync
    tail -n 1 /proc/fs/ext4/loop0/fc_info
    "fs-verity enable":     1
3. Enabled fs-verity on a second file, fsynced it, and checked that the
   ineligible commit counter is updated too:
    echo "data2" > /mnt/fc_verity/verityfile2
    /root/enable_verity /mnt/fc_verity/verityfile2
    /root/fsync_file /mnt/fc_verity/verityfile2
    sync
    /proc/fs/ext4/loop0/fc_info shows "fs-verity enable" incremented and
    fc stats ineligible increased accordingly.

Signed-off-by: Li Chen <me@linux.beauty>
---
 fs/ext4/fast_commit.c       | 1 +
 fs/ext4/fast_commit.h       | 1 +
 fs/ext4/verity.c            | 2 ++
 include/trace/events/ext4.h | 4 +++-
 4 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
index afb28b3e52bb..242b69e5fe13 100644
--- a/fs/ext4/fast_commit.c
+++ b/fs/ext4/fast_commit.c
@@ -2303,6 +2303,7 @@ static const char * const fc_ineligible_reasons[] = {
 	[EXT4_FC_REASON_INODE_JOURNAL_DATA] = "Data journalling",
 	[EXT4_FC_REASON_ENCRYPTED_FILENAME] = "Encrypted filename",
 	[EXT4_FC_REASON_MIGRATE] = "Inode format migration",
+	[EXT4_FC_REASON_VERITY] = "fs-verity enable",
 };
 
 int ext4_fc_info_show(struct seq_file *seq, void *v)
diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h
index be3b84a74c32..20f65135208f 100644
--- a/fs/ext4/fast_commit.h
+++ b/fs/ext4/fast_commit.h
@@ -98,6 +98,7 @@ enum {
 	EXT4_FC_REASON_INODE_JOURNAL_DATA,
 	EXT4_FC_REASON_ENCRYPTED_FILENAME,
 	EXT4_FC_REASON_MIGRATE,
+	EXT4_FC_REASON_VERITY,
 	EXT4_FC_REASON_MAX
 };
 
diff --git a/fs/ext4/verity.c b/fs/ext4/verity.c
index b0acb0c50313..6115a365d491 100644
--- a/fs/ext4/verity.c
+++ b/fs/ext4/verity.c
@@ -231,6 +231,8 @@ static int ext4_end_enable_verity(struct file *filp, const void *desc,
 		goto cleanup;
 	}
 
+	ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_VERITY, handle);
+
 	err = ext4_orphan_del(handle, inode);
 	if (err)
 		goto stop_and_cleanup;
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 8f75d41ae5ef..224ab12ee83f 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -103,6 +103,7 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_FALLOC_RANGE);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_INODE_JOURNAL_DATA);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_ENCRYPTED_FILENAME);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_MIGRATE);
+TRACE_DEFINE_ENUM(EXT4_FC_REASON_VERITY);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
 
 #define show_fc_reason(reason)						\
@@ -117,7 +118,8 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
 		{ EXT4_FC_REASON_FALLOC_RANGE,	"FALLOC_RANGE"},	\
 		{ EXT4_FC_REASON_INODE_JOURNAL_DATA,	"INODE_JOURNAL_DATA"}, \
 		{ EXT4_FC_REASON_ENCRYPTED_FILENAME,	"ENCRYPTED_FILENAME"}, \
-		{ EXT4_FC_REASON_MIGRATE,		"MIGRATE"})
+		{ EXT4_FC_REASON_MIGRATE,		"MIGRATE"},	\
+		{ EXT4_FC_REASON_VERITY,		"VERITY"})
 
 TRACE_DEFINE_ENUM(CR_POWER2_ALIGNED);
 TRACE_DEFINE_ENUM(CR_GOAL_LEN_FAST);
-- 
2.51.0


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

* [RFC 3/5] ext4: mark move extents fast-commit ineligible
  2025-12-11 11:51 [RFC 0/5] ext4: mark more ops fast-commit ineligible Li Chen
  2025-12-11 11:51 ` [RFC 1/5] ext4: mark inode format migration " Li Chen
  2025-12-11 11:51 ` [RFC 2/5] ext4: mark fs-verity enable " Li Chen
@ 2025-12-11 11:51 ` Li Chen
  2025-12-11 11:51 ` [RFC 4/5] ext4: mark group add " Li Chen
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Li Chen @ 2025-12-11 11:51 UTC (permalink / raw)
  To: Theodore Ts'o, Andreas Dilger, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-ext4, linux-kernel,
	linux-trace-kernel
  Cc: Li Chen

Fast commits only log operations that have dedicated replay support.
EXT4_IOC_MOVE_EXT swaps extents between regular files and may copy
data, rewriting the affected inodes' block mapping layout 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 for the
journal transactions used by move_extent_per_page() when
EXT4_IOC_MOVE_EXT runs.
This forces those transactions to fall back to a full commit,
ensuring that these multi-inode extent swaps are captured by the
normal journal rather than partially encoded in fast commit TLVs.
This change should not affect common workloads but makes online
defragmentation safer and easier to reason about under fast commit.

Testing:
1. prepare:
        dd if=/dev/zero of=/root/fc_move.img bs=1M count=0 seek=256
        mkfs.ext4 -O fast_commit -F /root/fc_move.img
        mkdir -p /mnt/fc_move && mount -t ext4 -o loop \
/root/fc_move.img /mnt/fc_move
2. Created two files, ran EXT4_IOC_MOVE_EXT via e4defrag, and checked
   the ineligible reason statistics:
        fallocate -l 64M /mnt/fc_move/file1
        cp /mnt/fc_move/file1 /mnt/fc_move/file2
        e4defrag /mnt/fc_move/file1
        cat /proc/fs/ext4/loop0/fc_info
   shows "Move extents": > 0 and fc stats ineligible > 0.

Signed-off-by: Li Chen <me@linux.beauty>
---
 fs/ext4/fast_commit.c       | 1 +
 fs/ext4/fast_commit.h       | 1 +
 fs/ext4/move_extent.c       | 1 +
 include/trace/events/ext4.h | 4 +++-
 4 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
index 242b69e5fe13..0ef2154a2b1f 100644
--- a/fs/ext4/fast_commit.c
+++ b/fs/ext4/fast_commit.c
@@ -2304,6 +2304,7 @@ static const char * const fc_ineligible_reasons[] = {
 	[EXT4_FC_REASON_ENCRYPTED_FILENAME] = "Encrypted filename",
 	[EXT4_FC_REASON_MIGRATE] = "Inode format migration",
 	[EXT4_FC_REASON_VERITY] = "fs-verity enable",
+	[EXT4_FC_REASON_MOVE_EXT] = "Move extents",
 };
 
 int ext4_fc_info_show(struct seq_file *seq, void *v)
diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h
index 20f65135208f..2f77a37fb101 100644
--- a/fs/ext4/fast_commit.h
+++ b/fs/ext4/fast_commit.h
@@ -99,6 +99,7 @@ enum {
 	EXT4_FC_REASON_ENCRYPTED_FILENAME,
 	EXT4_FC_REASON_MIGRATE,
 	EXT4_FC_REASON_VERITY,
+	EXT4_FC_REASON_MOVE_EXT,
 	EXT4_FC_REASON_MAX
 };
 
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 4b091c21908f..5a5e91078528 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -287,6 +287,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
 		*err = PTR_ERR(handle);
 		return 0;
 	}
+	ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_MOVE_EXT, handle);
 
 	orig_blk_offset = orig_page_offset * blocks_per_page +
 		data_offset_in_page;
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 224ab12ee83f..56e60080e759 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -104,6 +104,7 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_INODE_JOURNAL_DATA);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_ENCRYPTED_FILENAME);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_MIGRATE);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_VERITY);
+TRACE_DEFINE_ENUM(EXT4_FC_REASON_MOVE_EXT);
 TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
 
 #define show_fc_reason(reason)						\
@@ -119,7 +120,8 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
 		{ EXT4_FC_REASON_INODE_JOURNAL_DATA,	"INODE_JOURNAL_DATA"}, \
 		{ EXT4_FC_REASON_ENCRYPTED_FILENAME,	"ENCRYPTED_FILENAME"}, \
 		{ EXT4_FC_REASON_MIGRATE,		"MIGRATE"},	\
-		{ EXT4_FC_REASON_VERITY,		"VERITY"})
+		{ EXT4_FC_REASON_VERITY,		"VERITY"},	\
+		{ EXT4_FC_REASON_MOVE_EXT,		"MOVE_EXT"})
 
 TRACE_DEFINE_ENUM(CR_POWER2_ALIGNED);
 TRACE_DEFINE_ENUM(CR_GOAL_LEN_FAST);
-- 
2.51.0


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

* [RFC 4/5] ext4: mark group add fast-commit ineligible
  2025-12-11 11:51 [RFC 0/5] ext4: mark more ops fast-commit ineligible Li Chen
                   ` (2 preceding siblings ...)
  2025-12-11 11:51 ` [RFC 3/5] ext4: mark move extents " Li Chen
@ 2025-12-11 11:51 ` Li Chen
  2025-12-11 11:51 ` [RFC 5/5] ext4: mark group extend " Li Chen
  2026-01-28 18:05 ` [RFC 0/5] ext4: mark more ops " Theodore Ts'o
  5 siblings, 0 replies; 10+ messages in thread
From: Li Chen @ 2025-12-11 11:51 UTC (permalink / raw)
  To: Theodore Ts'o, Andreas Dilger, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-ext4, linux-kernel,
	linux-trace-kernel
  Cc: Li Chen

Fast commits only log operations that have dedicated replay support.
Online resize via EXT4_IOC_GROUP_ADD updates the superblock and group
descriptor 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_ioctl_group_add() adds new block groups.
This forces those transactions to fall back to a full commit,
ensuring that the filesystem geometry updates 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_ADD 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. Ran a helper that issues EXT4_IOC_GROUP_ADD on the mounted
   filesystem and checked the resize ineligible reason:
    ./group_add_helper /mnt/fc_resize
    cat /proc/fs/ext4/loop0/fc_info
   shows "Resize": > 0.
3. Fsynced a file on the resized filesystem and verified that the fast
   commit stats report at least one ineligible commit:
    touch /mnt/fc_resize/file
    /root/fsync_file /mnt/fc_resize/file
    sync
    cat /proc/fs/ext4/loop0/fc_info
   shows fc stats ineligible > 0.

Signed-off-by: Li Chen <me@linux.beauty>
---
 fs/ext4/ioctl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index a93a7baae990..57b47b9843f3 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -966,6 +966,7 @@ static long ext4_ioctl_group_add(struct file *file,
 
 	err = ext4_group_add(sb, input);
 	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


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

* [RFC 5/5] ext4: mark group extend fast-commit ineligible
  2025-12-11 11:51 [RFC 0/5] ext4: mark more ops fast-commit ineligible Li Chen
                   ` (3 preceding siblings ...)
  2025-12-11 11:51 ` [RFC 4/5] ext4: mark group add " Li Chen
@ 2025-12-11 11:51 ` Li Chen
  2026-01-19  2:58   ` Theodore Tso
  2026-01-28 18:05 ` [RFC 0/5] ext4: mark more ops " Theodore Ts'o
  5 siblings, 1 reply; 10+ messages in thread
From: Li Chen @ 2025-12-11 11:51 UTC (permalink / raw)
  To: Theodore Ts'o, Andreas Dilger, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-ext4, linux-kernel,
	linux-trace-kernel
  Cc: Li Chen

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


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

* Re: [RFC 5/5] ext4: mark group extend fast-commit ineligible
  2025-12-11 11:51 ` [RFC 5/5] ext4: mark group extend " Li Chen
@ 2026-01-19  2:58   ` Theodore Tso
  2026-01-19  3:03     ` Theodore Tso
  2026-01-19 12:37     ` Li Chen
  0 siblings, 2 replies; 10+ messages in thread
From: Theodore Tso @ 2026-01-19  2:58 UTC (permalink / raw)
  To: Li Chen
  Cc: Andreas Dilger, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, linux-ext4, linux-kernel, linux-trace-kernel

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

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

* Re: [RFC 5/5] ext4: mark group extend fast-commit ineligible
  2026-01-19  2:58   ` Theodore Tso
@ 2026-01-19  3:03     ` Theodore Tso
  2026-01-19 12:37     ` Li Chen
  1 sibling, 0 replies; 10+ messages in thread
From: Theodore Tso @ 2026-01-19  3:03 UTC (permalink / raw)
  To: Li Chen
  Cc: Andreas Dilger, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, linux-ext4, linux-kernel, linux-trace-kernel

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
				 

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

* Re: [RFC 5/5] ext4: mark group extend fast-commit ineligible
  2026-01-19  2:58   ` Theodore Tso
  2026-01-19  3:03     ` Theodore Tso
@ 2026-01-19 12:37     ` Li Chen
  1 sibling, 0 replies; 10+ messages in thread
From: Li Chen @ 2026-01-19 12:37 UTC (permalink / raw)
  To: Theodore Tso
  Cc: Andreas Dilger, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, linux-ext4, linux-kernel, linux-trace-kernel

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
 > 


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

* Re: [RFC 0/5] ext4: mark more ops fast-commit ineligible
  2025-12-11 11:51 [RFC 0/5] ext4: mark more ops fast-commit ineligible Li Chen
                   ` (4 preceding siblings ...)
  2025-12-11 11:51 ` [RFC 5/5] ext4: mark group extend " Li Chen
@ 2026-01-28 18:05 ` Theodore Ts'o
  5 siblings, 0 replies; 10+ messages in thread
From: Theodore Ts'o @ 2026-01-28 18:05 UTC (permalink / raw)
  To: Andreas Dilger, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, linux-ext4, linux-kernel, linux-trace-kernel,
	Li Chen
  Cc: Theodore Ts'o


On Thu, 11 Dec 2025 19:51:37 +0800, Li Chen wrote:
> ext4 fast commit only logs operations with replay support. This series
> marks a few more operations as fast-commit ineligible and accounts
> them via fc_info so behaviour under fast commit is easier to reason
> about.
> 
> Testing was done in a QEMU guest on loopback ext4 filesystems created
> with -O fast_commit[/,verity] by exercising each operation and checking
> /proc/fs/ext4/*/fc_info for the corresponding ineligible reason and
> ineligible commit counters. Detailed steps are in each commit's message.
> 
> [...]

Applied, thanks!

[1/5] ext4: mark inode format migration fast-commit ineligible
      commit: 87e79fa122bc9a6576f1690ee264fcbd77d3ab58
[2/5] ext4: mark fs-verity enable fast-commit ineligible
      commit: 16d43b9748c655b36a675cc55789f40fd827e9b1
[3/5] ext4: mark move extents fast-commit ineligible
      commit: 690558921d9f9388c6bc83610451d8cb393e4d88
[4/5] ext4: mark group add fast-commit ineligible
      commit: 89b4336fd5ec78f51f9d3a1d100f3ffa3228e604
[5/5] ext4: mark group extend fast-commit ineligible
      commit: 1f8dd813a1c771b13c303f73d876164bc9b327cc

Best regards,
-- 
Theodore Ts'o <tytso@mit.edu>

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

end of thread, other threads:[~2026-01-28 18:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-11 11:51 [RFC 0/5] ext4: mark more ops fast-commit ineligible Li Chen
2025-12-11 11:51 ` [RFC 1/5] ext4: mark inode format migration " Li Chen
2025-12-11 11:51 ` [RFC 2/5] ext4: mark fs-verity enable " Li Chen
2025-12-11 11:51 ` [RFC 3/5] ext4: mark move extents " Li Chen
2025-12-11 11:51 ` [RFC 4/5] ext4: mark group add " Li Chen
2025-12-11 11:51 ` [RFC 5/5] ext4: mark group extend " Li Chen
2026-01-19  2:58   ` Theodore Tso
2026-01-19  3:03     ` Theodore Tso
2026-01-19 12:37     ` Li Chen
2026-01-28 18:05 ` [RFC 0/5] ext4: mark more ops " Theodore Ts'o

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