From: Simon Glass <simon.glass@canonical.com> Add a new Kconfig option to control fast commit replay support. Fast commit replay is needed to recover filesystems that were not cleanly unmounted and have pending fast commit records. However, this adds to code size (~8K). Enable it by default, since filesystems are likely to need this. When disabled: - Filesystems with pending fast commits cannot be recovered - Only safe if filesystems are created with -O ^fast_commit or always cleanly unmounted Guard the replay functions in fast_commit.c and provide inline stubs in ext4.h. Update firefly-rk3288_defconfig to disable this feature for space savings. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- fs/ext4l/Kconfig | 17 +++++++++++++++++ fs/ext4l/ext4.h | 27 ++++++++++++++++++++++----- fs/ext4l/fast_commit.c | 4 ++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/fs/ext4l/Kconfig b/fs/ext4l/Kconfig index 3d7578f5073..22b290778b7 100644 --- a/fs/ext4l/Kconfig +++ b/fs/ext4l/Kconfig @@ -125,3 +125,20 @@ config EXT4_MBALLOC_PREFETCH reduced during lazy initialization. If unsure, say Y. + +config EXT4_FAST_COMMIT_REPLAY + bool "Enable ext4 fast commit replay support" + depends on FS_EXT4L + default y + help + Enable support for replaying fast commit records during mount. + Fast commit is a journal optimization that records fine-grained + changes. If a filesystem was not cleanly unmounted and has + pending fast commit records, this option is needed to recover. + + Disabling this saves space (~8K) but means filesystems with + pending fast commits cannot be recovered. Only disable if you're + certain your filesystems won't have fast commit records (e.g., + created with -O ^fast_commit). + + If unsure, say Y. diff --git a/fs/ext4l/ext4.h b/fs/ext4l/ext4.h index d01955bf59a..b8e9f2d8c95 100644 --- a/fs/ext4l/ext4.h +++ b/fs/ext4l/ext4.h @@ -2946,6 +2946,28 @@ extern void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate); int ext4_fc_info_show(struct seq_file *seq, void *v); void ext4_fc_init(struct super_block *sb, journal_t *journal); void ext4_fc_init_inode(struct inode *inode); + +#ifdef CONFIG_EXT4_FAST_COMMIT_REPLAY +bool ext4_fc_replay_check_excluded(struct super_block *sb, ext4_fsblk_t block); +void ext4_fc_replay_cleanup(struct super_block *sb); +int ext4_fc_record_regions(struct super_block *sb, int ino, + ext4_lblk_t lblk, ext4_fsblk_t pblk, + int len, int replay); +#else +static inline bool ext4_fc_replay_check_excluded(struct super_block *sb, + ext4_fsblk_t block) +{ + return false; +} +static inline void ext4_fc_replay_cleanup(struct super_block *sb) {} +static inline int ext4_fc_record_regions(struct super_block *sb, int ino, + ext4_lblk_t lblk, ext4_fsblk_t pblk, + int len, int replay) +{ + return 0; +} +#endif + void ext4_fc_track_range(handle_t *handle, struct inode *inode, ext4_lblk_t start, ext4_lblk_t end); void __ext4_fc_track_unlink(handle_t *handle, struct inode *inode, @@ -2960,14 +2982,9 @@ void ext4_fc_track_create(handle_t *handle, struct dentry *dentry); void ext4_fc_track_inode(handle_t *handle, struct inode *inode); void ext4_fc_mark_ineligible(struct super_block *sb, int reason, handle_t *handle); void ext4_fc_del(struct inode *inode); -bool ext4_fc_replay_check_excluded(struct super_block *sb, ext4_fsblk_t block); -void ext4_fc_replay_cleanup(struct super_block *sb); int ext4_fc_commit(journal_t *journal, tid_t commit_tid); int __init ext4_fc_init_dentry_cache(void); void ext4_fc_destroy_dentry_cache(void); -int ext4_fc_record_regions(struct super_block *sb, int ino, - ext4_lblk_t lblk, ext4_fsblk_t pblk, - int len, int replay); /* mballoc.c */ extern const struct seq_operations ext4_mb_seq_groups_ops; diff --git a/fs/ext4l/fast_commit.c b/fs/ext4l/fast_commit.c index ea5be3a079c..4383579ccb1 100644 --- a/fs/ext4l/fast_commit.c +++ b/fs/ext4l/fast_commit.c @@ -1360,6 +1360,7 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid) trace_ext4_fc_stats(sb); } +#ifdef CONFIG_EXT4_FAST_COMMIT_REPLAY /* Ext4 Replay Path Routines */ /* Helper struct for dentry replay routines */ @@ -2277,6 +2278,7 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh, } return ret; } +#endif /* CONFIG_EXT4_FAST_COMMIT_REPLAY */ void ext4_fc_init(struct super_block *sb, journal_t *journal) { @@ -2285,7 +2287,9 @@ void ext4_fc_init(struct super_block *sb, journal_t *journal) * could still have fast commit blocks that need to be replayed even if * fast commit has now been turned off. */ +#ifdef CONFIG_EXT4_FAST_COMMIT_REPLAY journal->j_fc_replay_callback = ext4_fc_replay; +#endif if (!test_opt2(sb, JOURNAL_FAST_COMMIT)) return; journal->j_fc_cleanup_callback = ext4_fc_cleanup; -- 2.43.0