From: Greg Kroah-Hartman Date: Thu, 5 Jan 2023 12:00:56 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v6.1.4~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=33e763ae1b7c6f06713786447154e2d1be954a96;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: ext4-add-missing-validation-of-fast-commit-record-lengths.patch ext4-disable-fast-commit-of-encrypted-dir-operations.patch ext4-don-t-set-up-encryption-key-during-jbd2-transaction.patch ext4-factor-out-ext4_fc_get_tl.patch ext4-fix-off-by-one-errors-in-fast-commit-block-filling.patch ext4-fix-potential-out-of-bound-read-in-ext4_fc_replay_scan.patch ext4-fix-unaligned-memory-access-in-ext4_fc_reserve_space.patch ext4-introduce-ext4_fc_tag_base_len-helper.patch ext4-remove-unused-enum-ext4_fc_commit_failed.patch ext4-use-ext4_debug-instead-of-jbd_debug.patch tracing-fix-issue-of-missing-one-synthetic-field.patch --- diff --git a/queue-5.15/ext4-add-missing-validation-of-fast-commit-record-lengths.patch b/queue-5.15/ext4-add-missing-validation-of-fast-commit-record-lengths.patch new file mode 100644 index 00000000000..47825baa3f9 --- /dev/null +++ b/queue-5.15/ext4-add-missing-validation-of-fast-commit-record-lengths.patch @@ -0,0 +1,102 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:27 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:57 -0800 +Subject: ext4: add missing validation of fast-commit record lengths +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, Theodore Ts'o +Message-ID: <20230105071359.257952-9-ebiggers@kernel.org> + +From: Eric Biggers + +From: Eric Biggers + +commit 64b4a25c3de81a69724e888ec2db3533b43816e2 upstream. + +Validate the inode and filename lengths in fast-commit journal records +so that a malicious fast-commit journal cannot cause a crash by having +invalid values for these. Also validate EXT4_FC_TAG_DEL_RANGE. + +Fixes: aa75f4d3daae ("ext4: main fast-commit commit path") +Cc: # v5.10+ +Signed-off-by: Eric Biggers +Link: https://lore.kernel.org/r/20221106224841.279231-5-ebiggers@kernel.org +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/fast_commit.c | 38 +++++++++++++++++++------------------- + fs/ext4/fast_commit.h | 2 +- + 2 files changed, 20 insertions(+), 20 deletions(-) + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -1916,32 +1916,31 @@ void ext4_fc_replay_cleanup(struct super + kfree(sbi->s_fc_replay_state.fc_modified_inodes); + } + +-static inline bool ext4_fc_tag_len_isvalid(struct ext4_fc_tl *tl, +- u8 *val, u8 *end) ++static bool ext4_fc_value_len_isvalid(struct ext4_sb_info *sbi, ++ int tag, int len) + { +- if (val + tl->fc_len > end) +- return false; +- +- /* Here only check ADD_RANGE/TAIL/HEAD which will read data when do +- * journal rescan before do CRC check. Other tags length check will +- * rely on CRC check. +- */ +- switch (tl->fc_tag) { ++ switch (tag) { + case EXT4_FC_TAG_ADD_RANGE: +- return (sizeof(struct ext4_fc_add_range) == tl->fc_len); +- case EXT4_FC_TAG_TAIL: +- return (sizeof(struct ext4_fc_tail) <= tl->fc_len); +- case EXT4_FC_TAG_HEAD: +- return (sizeof(struct ext4_fc_head) == tl->fc_len); ++ return len == sizeof(struct ext4_fc_add_range); + case EXT4_FC_TAG_DEL_RANGE: ++ return len == sizeof(struct ext4_fc_del_range); ++ case EXT4_FC_TAG_CREAT: + case EXT4_FC_TAG_LINK: + case EXT4_FC_TAG_UNLINK: +- case EXT4_FC_TAG_CREAT: ++ len -= sizeof(struct ext4_fc_dentry_info); ++ return len >= 1 && len <= EXT4_NAME_LEN; + case EXT4_FC_TAG_INODE: ++ len -= sizeof(struct ext4_fc_inode); ++ return len >= EXT4_GOOD_OLD_INODE_SIZE && ++ len <= sbi->s_inode_size; + case EXT4_FC_TAG_PAD: +- default: +- return true; ++ return true; /* padding can have any length */ ++ case EXT4_FC_TAG_TAIL: ++ return len >= sizeof(struct ext4_fc_tail); ++ case EXT4_FC_TAG_HEAD: ++ return len == sizeof(struct ext4_fc_head); + } ++ return false; + } + + /* +@@ -2004,7 +2003,8 @@ static int ext4_fc_replay_scan(journal_t + cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) { + ext4_fc_get_tl(&tl, cur); + val = cur + EXT4_FC_TAG_BASE_LEN; +- if (!ext4_fc_tag_len_isvalid(&tl, val, end)) { ++ if (tl.fc_len > end - val || ++ !ext4_fc_value_len_isvalid(sbi, tl.fc_tag, tl.fc_len)) { + ret = state->fc_replay_num_tags ? + JBD2_FC_REPLAY_STOP : -ECANCELED; + goto out_err; +--- a/fs/ext4/fast_commit.h ++++ b/fs/ext4/fast_commit.h +@@ -58,7 +58,7 @@ struct ext4_fc_dentry_info { + __u8 fc_dname[0]; + }; + +-/* Value structure for EXT4_FC_TAG_INODE and EXT4_FC_TAG_INODE_PARTIAL. */ ++/* Value structure for EXT4_FC_TAG_INODE. */ + struct ext4_fc_inode { + __le32 fc_ino; + __u8 fc_raw_inode[0]; diff --git a/queue-5.15/ext4-disable-fast-commit-of-encrypted-dir-operations.patch b/queue-5.15/ext4-disable-fast-commit-of-encrypted-dir-operations.patch new file mode 100644 index 00000000000..77dc431d4cf --- /dev/null +++ b/queue-5.15/ext4-disable-fast-commit-of-encrypted-dir-operations.patch @@ -0,0 +1,156 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:26 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:55 -0800 +Subject: ext4: disable fast-commit of encrypted dir operations +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, Theodore Ts'o +Message-ID: <20230105071359.257952-7-ebiggers@kernel.org> + +From: Eric Biggers + +From: Eric Biggers + +commit 0fbcb5251fc81b58969b272c4fb7374a7b922e3e upstream. + +fast-commit of create, link, and unlink operations in encrypted +directories is completely broken because the unencrypted filenames are +being written to the fast-commit journal instead of the encrypted +filenames. These operations can't be replayed, as encryption keys +aren't present at journal replay time. It is also an information leak. + +Until if/when we can get this working properly, make encrypted directory +operations ineligible for fast-commit. + +Note that fast-commit operations on encrypted regular files continue to +be allowed, as they seem to work. + +Fixes: aa75f4d3daae ("ext4: main fast-commit commit path") +Cc: # v5.10+ +Signed-off-by: Eric Biggers +Link: https://lore.kernel.org/r/20221106224841.279231-2-ebiggers@kernel.org +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/fast_commit.c | 41 +++++++++++++++++++++++++---------------- + fs/ext4/fast_commit.h | 1 + + include/trace/events/ext4.h | 7 +++++-- + 3 files changed, 31 insertions(+), 18 deletions(-) + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -399,25 +399,34 @@ static int __track_dentry_update(struct + struct __track_dentry_update_args *dentry_update = + (struct __track_dentry_update_args *)arg; + struct dentry *dentry = dentry_update->dentry; +- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); ++ struct inode *dir = dentry->d_parent->d_inode; ++ struct super_block *sb = inode->i_sb; ++ struct ext4_sb_info *sbi = EXT4_SB(sb); + + mutex_unlock(&ei->i_fc_lock); ++ ++ if (IS_ENCRYPTED(dir)) { ++ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_ENCRYPTED_FILENAME, ++ NULL); ++ mutex_lock(&ei->i_fc_lock); ++ return -EOPNOTSUPP; ++ } ++ + node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS); + if (!node) { +- ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM, NULL); ++ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL); + mutex_lock(&ei->i_fc_lock); + return -ENOMEM; + } + + node->fcd_op = dentry_update->op; +- node->fcd_parent = dentry->d_parent->d_inode->i_ino; ++ node->fcd_parent = dir->i_ino; + node->fcd_ino = inode->i_ino; + if (dentry->d_name.len > DNAME_INLINE_LEN) { + node->fcd_name.name = kmalloc(dentry->d_name.len, GFP_NOFS); + if (!node->fcd_name.name) { + kmem_cache_free(ext4_fc_dentry_cachep, node); +- ext4_fc_mark_ineligible(inode->i_sb, +- EXT4_FC_REASON_NOMEM, NULL); ++ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL); + mutex_lock(&ei->i_fc_lock); + return -ENOMEM; + } +@@ -2179,17 +2188,17 @@ void ext4_fc_init(struct super_block *sb + journal->j_fc_cleanup_callback = ext4_fc_cleanup; + } + +-static const char *fc_ineligible_reasons[] = { +- "Extended attributes changed", +- "Cross rename", +- "Journal flag changed", +- "Insufficient memory", +- "Swap boot", +- "Resize", +- "Dir renamed", +- "Falloc range op", +- "Data journalling", +- "FC Commit Failed" ++static const char * const fc_ineligible_reasons[] = { ++ [EXT4_FC_REASON_XATTR] = "Extended attributes changed", ++ [EXT4_FC_REASON_CROSS_RENAME] = "Cross rename", ++ [EXT4_FC_REASON_JOURNAL_FLAG_CHANGE] = "Journal flag changed", ++ [EXT4_FC_REASON_NOMEM] = "Insufficient memory", ++ [EXT4_FC_REASON_SWAP_BOOT] = "Swap boot", ++ [EXT4_FC_REASON_RESIZE] = "Resize", ++ [EXT4_FC_REASON_RENAME_DIR] = "Dir renamed", ++ [EXT4_FC_REASON_FALLOC_RANGE] = "Falloc range op", ++ [EXT4_FC_REASON_INODE_JOURNAL_DATA] = "Data journalling", ++ [EXT4_FC_REASON_ENCRYPTED_FILENAME] = "Encrypted filename", + }; + + int ext4_fc_info_show(struct seq_file *seq, void *v) +--- a/fs/ext4/fast_commit.h ++++ b/fs/ext4/fast_commit.h +@@ -96,6 +96,7 @@ enum { + EXT4_FC_REASON_RENAME_DIR, + EXT4_FC_REASON_FALLOC_RANGE, + EXT4_FC_REASON_INODE_JOURNAL_DATA, ++ EXT4_FC_REASON_ENCRYPTED_FILENAME, + EXT4_FC_REASON_MAX + }; + +--- a/include/trace/events/ext4.h ++++ b/include/trace/events/ext4.h +@@ -104,6 +104,7 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_RESIZE) + 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_MAX); + + #define show_fc_reason(reason) \ +@@ -116,7 +117,8 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX); + { EXT4_FC_REASON_RESIZE, "RESIZE"}, \ + { 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_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}, \ ++ { EXT4_FC_REASON_ENCRYPTED_FILENAME, "ENCRYPTED_FILENAME"}) + + TRACE_EVENT(ext4_other_inode_update_time, + TP_PROTO(struct inode *inode, ino_t orig_ino), +@@ -2764,7 +2766,7 @@ TRACE_EVENT(ext4_fc_stats, + ), + + TP_printk("dev %d,%d fc ineligible reasons:\n" +- "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u " ++ "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u" + "num_commits:%lu, ineligible: %lu, numblks: %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + FC_REASON_NAME_STAT(EXT4_FC_REASON_XATTR), +@@ -2776,6 +2778,7 @@ TRACE_EVENT(ext4_fc_stats, + FC_REASON_NAME_STAT(EXT4_FC_REASON_RENAME_DIR), + FC_REASON_NAME_STAT(EXT4_FC_REASON_FALLOC_RANGE), + FC_REASON_NAME_STAT(EXT4_FC_REASON_INODE_JOURNAL_DATA), ++ FC_REASON_NAME_STAT(EXT4_FC_REASON_ENCRYPTED_FILENAME), + __entry->fc_commits, __entry->fc_ineligible_commits, + __entry->fc_numblks) + ); diff --git a/queue-5.15/ext4-don-t-set-up-encryption-key-during-jbd2-transaction.patch b/queue-5.15/ext4-don-t-set-up-encryption-key-during-jbd2-transaction.patch new file mode 100644 index 00000000000..e3e47bb37d0 --- /dev/null +++ b/queue-5.15/ext4-don-t-set-up-encryption-key-during-jbd2-transaction.patch @@ -0,0 +1,163 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:27 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:56 -0800 +Subject: ext4: don't set up encryption key during jbd2 transaction +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, syzbot+1a748d0007eeac3ab079@syzkaller.appspotmail.com, Theodore Ts'o +Message-ID: <20230105071359.257952-8-ebiggers@kernel.org> + +From: Eric Biggers + +From: Eric Biggers + +commit 4c0d5778385cb3618ff26a561ce41de2b7d9de70 upstream. + +Commit a80f7fcf1867 ("ext4: fixup ext4_fc_track_* functions' signature") +extended the scope of the transaction in ext4_unlink() too far, making +it include the call to ext4_find_entry(). However, ext4_find_entry() +can deadlock when called from within a transaction because it may need +to set up the directory's encryption key. + +Fix this by restoring the transaction to its original scope. + +Reported-by: syzbot+1a748d0007eeac3ab079@syzkaller.appspotmail.com +Fixes: a80f7fcf1867 ("ext4: fixup ext4_fc_track_* functions' signature") +Cc: # v5.10+ +Signed-off-by: Eric Biggers +Link: https://lore.kernel.org/r/20221106224841.279231-3-ebiggers@kernel.org +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/ext4.h | 4 ++-- + fs/ext4/fast_commit.c | 2 +- + fs/ext4/namei.c | 44 ++++++++++++++++++++++++-------------------- + 3 files changed, 27 insertions(+), 23 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -3647,8 +3647,8 @@ extern void ext4_initialize_dirent_tail( + unsigned int blocksize); + extern int ext4_handle_dirty_dirblock(handle_t *handle, struct inode *inode, + struct buffer_head *bh); +-extern int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name, +- struct inode *inode); ++extern int __ext4_unlink(struct inode *dir, const struct qstr *d_name, ++ struct inode *inode, struct dentry *dentry); + extern int __ext4_link(struct inode *dir, struct inode *inode, + struct dentry *dentry); + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -1330,7 +1330,7 @@ static int ext4_fc_replay_unlink(struct + return 0; + } + +- ret = __ext4_unlink(NULL, old_parent, &entry, inode); ++ ret = __ext4_unlink(old_parent, &entry, inode, NULL); + /* -ENOENT ok coz it might not exist anymore. */ + if (ret == -ENOENT) + ret = 0; +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -3204,14 +3204,20 @@ end_rmdir: + return retval; + } + +-int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name, +- struct inode *inode) ++int __ext4_unlink(struct inode *dir, const struct qstr *d_name, ++ struct inode *inode, ++ struct dentry *dentry /* NULL during fast_commit recovery */) + { + int retval = -ENOENT; + struct buffer_head *bh; + struct ext4_dir_entry_2 *de; ++ handle_t *handle; + int skip_remove_dentry = 0; + ++ /* ++ * Keep this outside the transaction; it may have to set up the ++ * directory's encryption key, which isn't GFP_NOFS-safe. ++ */ + bh = ext4_find_entry(dir, d_name, &de, NULL); + if (IS_ERR(bh)) + return PTR_ERR(bh); +@@ -3228,7 +3234,14 @@ int __ext4_unlink(handle_t *handle, stru + if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) + skip_remove_dentry = 1; + else +- goto out; ++ goto out_bh; ++ } ++ ++ handle = ext4_journal_start(dir, EXT4_HT_DIR, ++ EXT4_DATA_TRANS_BLOCKS(dir->i_sb)); ++ if (IS_ERR(handle)) { ++ retval = PTR_ERR(handle); ++ goto out_bh; + } + + if (IS_DIRSYNC(dir)) +@@ -3237,12 +3250,12 @@ int __ext4_unlink(handle_t *handle, stru + if (!skip_remove_dentry) { + retval = ext4_delete_entry(handle, dir, de, bh); + if (retval) +- goto out; ++ goto out_handle; + dir->i_ctime = dir->i_mtime = current_time(dir); + ext4_update_dx_flag(dir); + retval = ext4_mark_inode_dirty(handle, dir); + if (retval) +- goto out; ++ goto out_handle; + } else { + retval = 0; + } +@@ -3255,15 +3268,17 @@ int __ext4_unlink(handle_t *handle, stru + ext4_orphan_add(handle, inode); + inode->i_ctime = current_time(inode); + retval = ext4_mark_inode_dirty(handle, inode); +- +-out: ++ if (dentry && !retval) ++ ext4_fc_track_unlink(handle, dentry); ++out_handle: ++ ext4_journal_stop(handle); ++out_bh: + brelse(bh); + return retval; + } + + static int ext4_unlink(struct inode *dir, struct dentry *dentry) + { +- handle_t *handle; + int retval; + + if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb)))) +@@ -3281,16 +3296,7 @@ static int ext4_unlink(struct inode *dir + if (retval) + goto out_trace; + +- handle = ext4_journal_start(dir, EXT4_HT_DIR, +- EXT4_DATA_TRANS_BLOCKS(dir->i_sb)); +- if (IS_ERR(handle)) { +- retval = PTR_ERR(handle); +- goto out_trace; +- } +- +- retval = __ext4_unlink(handle, dir, &dentry->d_name, d_inode(dentry)); +- if (!retval) +- ext4_fc_track_unlink(handle, dentry); ++ retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry), dentry); + #ifdef CONFIG_UNICODE + /* VFS negative dentries are incompatible with Encoding and + * Case-insensitiveness. Eventually we'll want avoid +@@ -3301,8 +3307,6 @@ static int ext4_unlink(struct inode *dir + if (IS_CASEFOLDED(dir)) + d_invalidate(dentry); + #endif +- if (handle) +- ext4_journal_stop(handle); + + out_trace: + trace_ext4_unlink_exit(dentry, retval); diff --git a/queue-5.15/ext4-factor-out-ext4_fc_get_tl.patch b/queue-5.15/ext4-factor-out-ext4_fc_get_tl.patch new file mode 100644 index 00000000000..4906502b1db --- /dev/null +++ b/queue-5.15/ext4-factor-out-ext4_fc_get_tl.patch @@ -0,0 +1,154 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:25 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:53 -0800 +Subject: ext4: factor out ext4_fc_get_tl() +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, Ye Bin , Theodore Ts'o +Message-ID: <20230105071359.257952-5-ebiggers@kernel.org> + +From: Eric Biggers + +From: Ye Bin + +commit dcc5827484d6e53ccda12334f8bbfafcc593ceda upstream. + +Factor out ext4_fc_get_tl() to fill 'tl' with host byte order. + +Signed-off-by: Ye Bin +Link: https://lore.kernel.org/r/20220924075233.2315259-3-yebin10@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/fast_commit.c | 46 +++++++++++++++++++++++++--------------------- + 1 file changed, 25 insertions(+), 21 deletions(-) + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -1271,7 +1271,7 @@ struct dentry_info_args { + }; + + static inline void tl_to_darg(struct dentry_info_args *darg, +- struct ext4_fc_tl *tl, u8 *val) ++ struct ext4_fc_tl *tl, u8 *val) + { + struct ext4_fc_dentry_info fcd; + +@@ -1280,8 +1280,14 @@ static inline void tl_to_darg(struct den + darg->parent_ino = le32_to_cpu(fcd.fc_parent_ino); + darg->ino = le32_to_cpu(fcd.fc_ino); + darg->dname = val + offsetof(struct ext4_fc_dentry_info, fc_dname); +- darg->dname_len = le16_to_cpu(tl->fc_len) - +- sizeof(struct ext4_fc_dentry_info); ++ darg->dname_len = tl->fc_len - sizeof(struct ext4_fc_dentry_info); ++} ++ ++static inline void ext4_fc_get_tl(struct ext4_fc_tl *tl, u8 *val) ++{ ++ memcpy(tl, val, EXT4_FC_TAG_BASE_LEN); ++ tl->fc_len = le16_to_cpu(tl->fc_len); ++ tl->fc_tag = le16_to_cpu(tl->fc_tag); + } + + /* Unlink replay function */ +@@ -1446,7 +1452,7 @@ static int ext4_fc_replay_inode(struct s + struct ext4_inode *raw_fc_inode; + struct inode *inode = NULL; + struct ext4_iloc iloc; +- int inode_len, ino, ret, tag = le16_to_cpu(tl->fc_tag); ++ int inode_len, ino, ret, tag = tl->fc_tag; + struct ext4_extent_header *eh; + + memcpy(&fc_inode, val, sizeof(fc_inode)); +@@ -1471,7 +1477,7 @@ static int ext4_fc_replay_inode(struct s + if (ret) + goto out; + +- inode_len = le16_to_cpu(tl->fc_len) - sizeof(struct ext4_fc_inode); ++ inode_len = tl->fc_len - sizeof(struct ext4_fc_inode); + raw_inode = ext4_raw_inode(&iloc); + + memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block)); +@@ -1958,12 +1964,12 @@ static int ext4_fc_replay_scan(journal_t + + state->fc_replay_expected_off++; + for (cur = start; cur < end; +- cur = cur + EXT4_FC_TAG_BASE_LEN + le16_to_cpu(tl.fc_len)) { +- memcpy(&tl, cur, EXT4_FC_TAG_BASE_LEN); ++ cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) { ++ ext4_fc_get_tl(&tl, cur); + val = cur + EXT4_FC_TAG_BASE_LEN; + ext4_debug("Scan phase, tag:%s, blk %lld\n", +- tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr); +- switch (le16_to_cpu(tl.fc_tag)) { ++ tag2str(tl.fc_tag), bh->b_blocknr); ++ switch (tl.fc_tag) { + case EXT4_FC_TAG_ADD_RANGE: + memcpy(&ext, val, sizeof(ext)); + ex = (struct ext4_extent *)&ext.fc_ex; +@@ -1983,7 +1989,7 @@ static int ext4_fc_replay_scan(journal_t + case EXT4_FC_TAG_PAD: + state->fc_cur_tag++; + state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur, +- EXT4_FC_TAG_BASE_LEN + le16_to_cpu(tl.fc_len)); ++ EXT4_FC_TAG_BASE_LEN + tl.fc_len); + break; + case EXT4_FC_TAG_TAIL: + state->fc_cur_tag++; +@@ -2016,7 +2022,7 @@ static int ext4_fc_replay_scan(journal_t + } + state->fc_cur_tag++; + state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur, +- EXT4_FC_TAG_BASE_LEN + le16_to_cpu(tl.fc_len)); ++ EXT4_FC_TAG_BASE_LEN + tl.fc_len); + break; + default: + ret = state->fc_replay_num_tags ? +@@ -2072,8 +2078,8 @@ static int ext4_fc_replay(journal_t *jou + end = (__u8 *)bh->b_data + journal->j_blocksize - 1; + + for (cur = start; cur < end; +- cur = cur + EXT4_FC_TAG_BASE_LEN + le16_to_cpu(tl.fc_len)) { +- memcpy(&tl, cur, EXT4_FC_TAG_BASE_LEN); ++ cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) { ++ ext4_fc_get_tl(&tl, cur); + val = cur + EXT4_FC_TAG_BASE_LEN; + + if (state->fc_replay_num_tags == 0) { +@@ -2081,10 +2087,9 @@ static int ext4_fc_replay(journal_t *jou + ext4_fc_set_bitmaps_and_counters(sb); + break; + } +- ext4_debug("Replay phase, tag:%s\n", +- tag2str(le16_to_cpu(tl.fc_tag))); ++ ext4_debug("Replay phase, tag:%s\n", tag2str(tl.fc_tag)); + state->fc_replay_num_tags--; +- switch (le16_to_cpu(tl.fc_tag)) { ++ switch (tl.fc_tag) { + case EXT4_FC_TAG_LINK: + ret = ext4_fc_replay_link(sb, &tl, val); + break; +@@ -2105,19 +2110,18 @@ static int ext4_fc_replay(journal_t *jou + break; + case EXT4_FC_TAG_PAD: + trace_ext4_fc_replay(sb, EXT4_FC_TAG_PAD, 0, +- le16_to_cpu(tl.fc_len), 0); ++ tl.fc_len, 0); + break; + case EXT4_FC_TAG_TAIL: +- trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, 0, +- le16_to_cpu(tl.fc_len), 0); ++ trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, ++ 0, tl.fc_len, 0); + memcpy(&tail, val, sizeof(tail)); + WARN_ON(le32_to_cpu(tail.fc_tid) != expected_tid); + break; + case EXT4_FC_TAG_HEAD: + break; + default: +- trace_ext4_fc_replay(sb, le16_to_cpu(tl.fc_tag), 0, +- le16_to_cpu(tl.fc_len), 0); ++ trace_ext4_fc_replay(sb, tl.fc_tag, 0, tl.fc_len, 0); + ret = -ECANCELED; + break; + } diff --git a/queue-5.15/ext4-fix-off-by-one-errors-in-fast-commit-block-filling.patch b/queue-5.15/ext4-fix-off-by-one-errors-in-fast-commit-block-filling.patch new file mode 100644 index 00000000000..f8af6fdf760 --- /dev/null +++ b/queue-5.15/ext4-fix-off-by-one-errors-in-fast-commit-block-filling.patch @@ -0,0 +1,171 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:27 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:59 -0800 +Subject: ext4: fix off-by-one errors in fast-commit block filling +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, Theodore Ts'o +Message-ID: <20230105071359.257952-11-ebiggers@kernel.org> + +From: Eric Biggers + +From: Eric Biggers + +commit 48a6a66db82b8043d298a630f22c62d43550cae5 upstream. + +Due to several different off-by-one errors, or perhaps due to a late +change in design that wasn't fully reflected in the code that was +actually merged, there are several very strange constraints on how +fast-commit blocks are filled with tlv entries: + +- tlvs must start at least 10 bytes before the end of the block, even + though the minimum tlv length is 8. Otherwise, the replay code will + ignore them. (BUG: ext4_fc_reserve_space() could violate this + requirement if called with a len of blocksize - 9 or blocksize - 8. + Fortunately, this doesn't seem to happen currently.) + +- tlvs must end at least 1 byte before the end of the block. Otherwise + the replay code will consider them to be invalid. This quirk + contributed to a bug (fixed by an earlier commit) where uninitialized + memory was being leaked to disk in the last byte of blocks. + +Also, strangely these constraints don't apply to the replay code in +e2fsprogs, which will accept any tlvs in the blocks (with no bounds +checks at all, but that is a separate issue...). + +Given that this all seems to be a bug, let's fix it by just filling +blocks with tlv entries in the natural way. + +Note that old kernels will be unable to replay fast-commit journals +created by kernels that have this commit. + +Fixes: aa75f4d3daae ("ext4: main fast-commit commit path") +Cc: # v5.10+ +Signed-off-by: Eric Biggers +Link: https://lore.kernel.org/r/20221106224841.279231-7-ebiggers@kernel.org +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/fast_commit.c | 66 +++++++++++++++++++++++++------------------------- + 1 file changed, 33 insertions(+), 33 deletions(-) + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -643,43 +643,43 @@ static u8 *ext4_fc_reserve_space(struct + struct buffer_head *bh; + int bsize = sbi->s_journal->j_blocksize; + int ret, off = sbi->s_fc_bytes % bsize; +- int pad_len; ++ int remaining; + u8 *dst; + + /* +- * After allocating len, we should have space at least for a 0 byte +- * padding. ++ * If 'len' is too long to fit in any block alongside a PAD tlv, then we ++ * cannot fulfill the request. + */ +- if (len + EXT4_FC_TAG_BASE_LEN > bsize) ++ if (len > bsize - EXT4_FC_TAG_BASE_LEN) + return NULL; + +- if (bsize - off - 1 > len + EXT4_FC_TAG_BASE_LEN) { +- /* +- * Only allocate from current buffer if we have enough space for +- * this request AND we have space to add a zero byte padding. +- */ +- if (!sbi->s_fc_bh) { +- ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh); +- if (ret) +- return NULL; +- sbi->s_fc_bh = bh; +- } +- sbi->s_fc_bytes += len; +- return sbi->s_fc_bh->b_data + off; ++ if (!sbi->s_fc_bh) { ++ ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh); ++ if (ret) ++ return NULL; ++ sbi->s_fc_bh = bh; + } +- /* Need to add PAD tag */ + dst = sbi->s_fc_bh->b_data + off; ++ ++ /* ++ * Allocate the bytes in the current block if we can do so while still ++ * leaving enough space for a PAD tlv. ++ */ ++ remaining = bsize - EXT4_FC_TAG_BASE_LEN - off; ++ if (len <= remaining) { ++ sbi->s_fc_bytes += len; ++ return dst; ++ } ++ ++ /* ++ * Else, terminate the current block with a PAD tlv, then allocate a new ++ * block and allocate the bytes at the start of that new block. ++ */ ++ + tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD); +- pad_len = bsize - off - 1 - EXT4_FC_TAG_BASE_LEN; +- tl.fc_len = cpu_to_le16(pad_len); ++ tl.fc_len = cpu_to_le16(remaining); + ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc); +- dst += EXT4_FC_TAG_BASE_LEN; +- if (pad_len > 0) { +- ext4_fc_memzero(sb, dst, pad_len, crc); +- dst += pad_len; +- } +- /* Don't leak uninitialized memory in the unused last byte. */ +- *dst = 0; ++ ext4_fc_memzero(sb, dst + EXT4_FC_TAG_BASE_LEN, remaining, crc); + + ext4_fc_submit_bh(sb, false); + +@@ -687,7 +687,7 @@ static u8 *ext4_fc_reserve_space(struct + if (ret) + return NULL; + sbi->s_fc_bh = bh; +- sbi->s_fc_bytes = (sbi->s_fc_bytes / bsize + 1) * bsize + len; ++ sbi->s_fc_bytes += bsize - off + len; + return sbi->s_fc_bh->b_data; + } + +@@ -718,7 +718,7 @@ static int ext4_fc_write_tail(struct sup + off = sbi->s_fc_bytes % bsize; + + tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_TAIL); +- tl.fc_len = cpu_to_le16(bsize - off - 1 + sizeof(struct ext4_fc_tail)); ++ tl.fc_len = cpu_to_le16(bsize - off + sizeof(struct ext4_fc_tail)); + sbi->s_fc_bytes = round_up(sbi->s_fc_bytes, bsize); + + ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, &crc); +@@ -1981,7 +1981,7 @@ static int ext4_fc_replay_scan(journal_t + state = &sbi->s_fc_replay_state; + + start = (u8 *)bh->b_data; +- end = (__u8 *)bh->b_data + journal->j_blocksize - 1; ++ end = start + journal->j_blocksize; + + if (state->fc_replay_expected_off == 0) { + state->fc_cur_tag = 0; +@@ -2002,7 +2002,7 @@ static int ext4_fc_replay_scan(journal_t + } + + state->fc_replay_expected_off++; +- for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN; ++ for (cur = start; cur <= end - EXT4_FC_TAG_BASE_LEN; + cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) { + ext4_fc_get_tl(&tl, cur); + val = cur + EXT4_FC_TAG_BASE_LEN; +@@ -2120,9 +2120,9 @@ static int ext4_fc_replay(journal_t *jou + #endif + + start = (u8 *)bh->b_data; +- end = (__u8 *)bh->b_data + journal->j_blocksize - 1; ++ end = start + journal->j_blocksize; + +- for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN; ++ for (cur = start; cur <= end - EXT4_FC_TAG_BASE_LEN; + cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) { + ext4_fc_get_tl(&tl, cur); + val = cur + EXT4_FC_TAG_BASE_LEN; diff --git a/queue-5.15/ext4-fix-potential-out-of-bound-read-in-ext4_fc_replay_scan.patch b/queue-5.15/ext4-fix-potential-out-of-bound-read-in-ext4_fc_replay_scan.patch new file mode 100644 index 00000000000..08633d37ef5 --- /dev/null +++ b/queue-5.15/ext4-fix-potential-out-of-bound-read-in-ext4_fc_replay_scan.patch @@ -0,0 +1,102 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:15 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:54 -0800 +Subject: ext4: fix potential out of bound read in ext4_fc_replay_scan() +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, stable@kernel.org, Ye Bin , Theodore Ts'o +Message-ID: <20230105071359.257952-6-ebiggers@kernel.org> + +From: Eric Biggers + +From: Ye Bin + +commit 1b45cc5c7b920fd8bf72e5a888ec7abeadf41e09 upstream. + +For scan loop must ensure that at least EXT4_FC_TAG_BASE_LEN space. If remain +space less than EXT4_FC_TAG_BASE_LEN which will lead to out of bound read +when mounting corrupt file system image. +ADD_RANGE/HEAD/TAIL is needed to add extra check when do journal scan, as this +three tags will read data during scan, tag length couldn't less than data length +which will read. + +Cc: stable@kernel.org +Signed-off-by: Ye Bin +Link: https://lore.kernel.org/r/20220924075233.2315259-4-yebin10@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/fast_commit.c | 38 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 36 insertions(+), 2 deletions(-) + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -1907,6 +1907,34 @@ void ext4_fc_replay_cleanup(struct super + kfree(sbi->s_fc_replay_state.fc_modified_inodes); + } + ++static inline bool ext4_fc_tag_len_isvalid(struct ext4_fc_tl *tl, ++ u8 *val, u8 *end) ++{ ++ if (val + tl->fc_len > end) ++ return false; ++ ++ /* Here only check ADD_RANGE/TAIL/HEAD which will read data when do ++ * journal rescan before do CRC check. Other tags length check will ++ * rely on CRC check. ++ */ ++ switch (tl->fc_tag) { ++ case EXT4_FC_TAG_ADD_RANGE: ++ return (sizeof(struct ext4_fc_add_range) == tl->fc_len); ++ case EXT4_FC_TAG_TAIL: ++ return (sizeof(struct ext4_fc_tail) <= tl->fc_len); ++ case EXT4_FC_TAG_HEAD: ++ return (sizeof(struct ext4_fc_head) == tl->fc_len); ++ case EXT4_FC_TAG_DEL_RANGE: ++ case EXT4_FC_TAG_LINK: ++ case EXT4_FC_TAG_UNLINK: ++ case EXT4_FC_TAG_CREAT: ++ case EXT4_FC_TAG_INODE: ++ case EXT4_FC_TAG_PAD: ++ default: ++ return true; ++ } ++} ++ + /* + * Recovery Scan phase handler + * +@@ -1963,10 +1991,15 @@ static int ext4_fc_replay_scan(journal_t + } + + state->fc_replay_expected_off++; +- for (cur = start; cur < end; ++ for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN; + cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) { + ext4_fc_get_tl(&tl, cur); + val = cur + EXT4_FC_TAG_BASE_LEN; ++ if (!ext4_fc_tag_len_isvalid(&tl, val, end)) { ++ ret = state->fc_replay_num_tags ? ++ JBD2_FC_REPLAY_STOP : -ECANCELED; ++ goto out_err; ++ } + ext4_debug("Scan phase, tag:%s, blk %lld\n", + tag2str(tl.fc_tag), bh->b_blocknr); + switch (tl.fc_tag) { +@@ -2077,7 +2110,7 @@ static int ext4_fc_replay(journal_t *jou + start = (u8 *)bh->b_data; + end = (__u8 *)bh->b_data + journal->j_blocksize - 1; + +- for (cur = start; cur < end; ++ for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN; + cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) { + ext4_fc_get_tl(&tl, cur); + val = cur + EXT4_FC_TAG_BASE_LEN; +@@ -2087,6 +2120,7 @@ static int ext4_fc_replay(journal_t *jou + ext4_fc_set_bitmaps_and_counters(sb); + break; + } ++ + ext4_debug("Replay phase, tag:%s\n", tag2str(tl.fc_tag)); + state->fc_replay_num_tags--; + switch (tl.fc_tag) { diff --git a/queue-5.15/ext4-fix-unaligned-memory-access-in-ext4_fc_reserve_space.patch b/queue-5.15/ext4-fix-unaligned-memory-access-in-ext4_fc_reserve_space.patch new file mode 100644 index 00000000000..5538c00f1bc --- /dev/null +++ b/queue-5.15/ext4-fix-unaligned-memory-access-in-ext4_fc_reserve_space.patch @@ -0,0 +1,104 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:26 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:58 -0800 +Subject: ext4: fix unaligned memory access in ext4_fc_reserve_space() +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, Theodore Ts'o +Message-ID: <20230105071359.257952-10-ebiggers@kernel.org> + +From: Eric Biggers + +From: Eric Biggers + +commit 8415ce07ecf0cc25efdd5db264a7133716e503cf upstream. + +As is done elsewhere in the file, build the struct ext4_fc_tl on the +stack and memcpy() it into the buffer, rather than directly writing it +to a potentially-unaligned location in the buffer. + +Fixes: aa75f4d3daae ("ext4: main fast-commit commit path") +Cc: # v5.10+ +Signed-off-by: Eric Biggers +Link: https://lore.kernel.org/r/20221106224841.279231-6-ebiggers@kernel.org +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/fast_commit.c | 39 +++++++++++++++++++++------------------ + 1 file changed, 21 insertions(+), 18 deletions(-) + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -604,6 +604,15 @@ static void ext4_fc_submit_bh(struct sup + + /* Ext4 commit path routines */ + ++/* memcpy to fc reserved space and update CRC */ ++static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src, ++ int len, u32 *crc) ++{ ++ if (crc) ++ *crc = ext4_chksum(EXT4_SB(sb), *crc, src, len); ++ return memcpy(dst, src, len); ++} ++ + /* memzero and update CRC */ + static void *ext4_fc_memzero(struct super_block *sb, void *dst, int len, + u32 *crc) +@@ -629,12 +638,13 @@ static void *ext4_fc_memzero(struct supe + */ + static u8 *ext4_fc_reserve_space(struct super_block *sb, int len, u32 *crc) + { +- struct ext4_fc_tl *tl; ++ struct ext4_fc_tl tl; + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct buffer_head *bh; + int bsize = sbi->s_journal->j_blocksize; + int ret, off = sbi->s_fc_bytes % bsize; + int pad_len; ++ u8 *dst; + + /* + * After allocating len, we should have space at least for a 0 byte +@@ -658,16 +668,18 @@ static u8 *ext4_fc_reserve_space(struct + return sbi->s_fc_bh->b_data + off; + } + /* Need to add PAD tag */ +- tl = (struct ext4_fc_tl *)(sbi->s_fc_bh->b_data + off); +- tl->fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD); ++ dst = sbi->s_fc_bh->b_data + off; ++ tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD); + pad_len = bsize - off - 1 - EXT4_FC_TAG_BASE_LEN; +- tl->fc_len = cpu_to_le16(pad_len); +- if (crc) +- *crc = ext4_chksum(sbi, *crc, tl, EXT4_FC_TAG_BASE_LEN); +- if (pad_len > 0) +- ext4_fc_memzero(sb, tl + 1, pad_len, crc); ++ tl.fc_len = cpu_to_le16(pad_len); ++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc); ++ dst += EXT4_FC_TAG_BASE_LEN; ++ if (pad_len > 0) { ++ ext4_fc_memzero(sb, dst, pad_len, crc); ++ dst += pad_len; ++ } + /* Don't leak uninitialized memory in the unused last byte. */ +- *((u8 *)(tl + 1) + pad_len) = 0; ++ *dst = 0; + + ext4_fc_submit_bh(sb, false); + +@@ -679,15 +691,6 @@ static u8 *ext4_fc_reserve_space(struct + return sbi->s_fc_bh->b_data; + } + +-/* memcpy to fc reserved space and update CRC */ +-static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src, +- int len, u32 *crc) +-{ +- if (crc) +- *crc = ext4_chksum(EXT4_SB(sb), *crc, src, len); +- return memcpy(dst, src, len); +-} +- + /* + * Complete a fast commit by writing tail tag. + * diff --git a/queue-5.15/ext4-introduce-ext4_fc_tag_base_len-helper.patch b/queue-5.15/ext4-introduce-ext4_fc_tag_base_len-helper.patch new file mode 100644 index 00000000000..b954fed92b2 --- /dev/null +++ b/queue-5.15/ext4-introduce-ext4_fc_tag_base_len-helper.patch @@ -0,0 +1,198 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:26 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:52 -0800 +Subject: ext4: introduce EXT4_FC_TAG_BASE_LEN helper +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, Ye Bin , Theodore Ts'o +Message-ID: <20230105071359.257952-4-ebiggers@kernel.org> + +From: Eric Biggers + +From: Ye Bin + +commit fdc2a3c75dd8345c5b48718af90bad1a7811bedb upstream. + +Introduce EXT4_FC_TAG_BASE_LEN helper for calculate length of +struct ext4_fc_tl. + +Signed-off-by: Ye Bin +Link: https://lore.kernel.org/r/20220924075233.2315259-2-yebin10@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/fast_commit.c | 54 +++++++++++++++++++++++++------------------------- + fs/ext4/fast_commit.h | 3 ++ + 2 files changed, 31 insertions(+), 26 deletions(-) + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -631,10 +631,10 @@ static u8 *ext4_fc_reserve_space(struct + * After allocating len, we should have space at least for a 0 byte + * padding. + */ +- if (len + sizeof(struct ext4_fc_tl) > bsize) ++ if (len + EXT4_FC_TAG_BASE_LEN > bsize) + return NULL; + +- if (bsize - off - 1 > len + sizeof(struct ext4_fc_tl)) { ++ if (bsize - off - 1 > len + EXT4_FC_TAG_BASE_LEN) { + /* + * Only allocate from current buffer if we have enough space for + * this request AND we have space to add a zero byte padding. +@@ -651,10 +651,10 @@ static u8 *ext4_fc_reserve_space(struct + /* Need to add PAD tag */ + tl = (struct ext4_fc_tl *)(sbi->s_fc_bh->b_data + off); + tl->fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD); +- pad_len = bsize - off - 1 - sizeof(struct ext4_fc_tl); ++ pad_len = bsize - off - 1 - EXT4_FC_TAG_BASE_LEN; + tl->fc_len = cpu_to_le16(pad_len); + if (crc) +- *crc = ext4_chksum(sbi, *crc, tl, sizeof(*tl)); ++ *crc = ext4_chksum(sbi, *crc, tl, EXT4_FC_TAG_BASE_LEN); + if (pad_len > 0) + ext4_fc_memzero(sb, tl + 1, pad_len, crc); + /* Don't leak uninitialized memory in the unused last byte. */ +@@ -699,7 +699,7 @@ static int ext4_fc_write_tail(struct sup + * ext4_fc_reserve_space takes care of allocating an extra block if + * there's no enough space on this block for accommodating this tail. + */ +- dst = ext4_fc_reserve_space(sb, sizeof(tl) + sizeof(tail), &crc); ++ dst = ext4_fc_reserve_space(sb, EXT4_FC_TAG_BASE_LEN + sizeof(tail), &crc); + if (!dst) + return -ENOSPC; + +@@ -709,8 +709,8 @@ static int ext4_fc_write_tail(struct sup + tl.fc_len = cpu_to_le16(bsize - off - 1 + sizeof(struct ext4_fc_tail)); + sbi->s_fc_bytes = round_up(sbi->s_fc_bytes, bsize); + +- ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), &crc); +- dst += sizeof(tl); ++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, &crc); ++ dst += EXT4_FC_TAG_BASE_LEN; + tail.fc_tid = cpu_to_le32(sbi->s_journal->j_running_transaction->t_tid); + ext4_fc_memcpy(sb, dst, &tail.fc_tid, sizeof(tail.fc_tid), &crc); + dst += sizeof(tail.fc_tid); +@@ -734,15 +734,15 @@ static bool ext4_fc_add_tlv(struct super + struct ext4_fc_tl tl; + u8 *dst; + +- dst = ext4_fc_reserve_space(sb, sizeof(tl) + len, crc); ++ dst = ext4_fc_reserve_space(sb, EXT4_FC_TAG_BASE_LEN + len, crc); + if (!dst) + return false; + + tl.fc_tag = cpu_to_le16(tag); + tl.fc_len = cpu_to_le16(len); + +- ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), crc); +- ext4_fc_memcpy(sb, dst + sizeof(tl), val, len, crc); ++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc); ++ ext4_fc_memcpy(sb, dst + EXT4_FC_TAG_BASE_LEN, val, len, crc); + + return true; + } +@@ -754,8 +754,8 @@ static bool ext4_fc_add_dentry_tlv(struc + struct ext4_fc_dentry_info fcd; + struct ext4_fc_tl tl; + int dlen = fc_dentry->fcd_name.len; +- u8 *dst = ext4_fc_reserve_space(sb, sizeof(tl) + sizeof(fcd) + dlen, +- crc); ++ u8 *dst = ext4_fc_reserve_space(sb, ++ EXT4_FC_TAG_BASE_LEN + sizeof(fcd) + dlen, crc); + + if (!dst) + return false; +@@ -764,8 +764,8 @@ static bool ext4_fc_add_dentry_tlv(struc + fcd.fc_ino = cpu_to_le32(fc_dentry->fcd_ino); + tl.fc_tag = cpu_to_le16(fc_dentry->fcd_op); + tl.fc_len = cpu_to_le16(sizeof(fcd) + dlen); +- ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), crc); +- dst += sizeof(tl); ++ ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc); ++ dst += EXT4_FC_TAG_BASE_LEN; + ext4_fc_memcpy(sb, dst, &fcd, sizeof(fcd), crc); + dst += sizeof(fcd); + ext4_fc_memcpy(sb, dst, fc_dentry->fcd_name.name, dlen, crc); +@@ -801,13 +801,13 @@ static int ext4_fc_write_inode(struct in + + ret = -ECANCELED; + dst = ext4_fc_reserve_space(inode->i_sb, +- sizeof(tl) + inode_len + sizeof(fc_inode.fc_ino), crc); ++ EXT4_FC_TAG_BASE_LEN + inode_len + sizeof(fc_inode.fc_ino), crc); + if (!dst) + goto err; + +- if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, sizeof(tl), crc)) ++ if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc)) + goto err; +- dst += sizeof(tl); ++ dst += EXT4_FC_TAG_BASE_LEN; + if (!ext4_fc_memcpy(inode->i_sb, dst, &fc_inode, sizeof(fc_inode), crc)) + goto err; + dst += sizeof(fc_inode); +@@ -1957,9 +1957,10 @@ static int ext4_fc_replay_scan(journal_t + } + + state->fc_replay_expected_off++; +- for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) { +- memcpy(&tl, cur, sizeof(tl)); +- val = cur + sizeof(tl); ++ for (cur = start; cur < end; ++ cur = cur + EXT4_FC_TAG_BASE_LEN + le16_to_cpu(tl.fc_len)) { ++ memcpy(&tl, cur, EXT4_FC_TAG_BASE_LEN); ++ val = cur + EXT4_FC_TAG_BASE_LEN; + ext4_debug("Scan phase, tag:%s, blk %lld\n", + tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr); + switch (le16_to_cpu(tl.fc_tag)) { +@@ -1982,13 +1983,13 @@ static int ext4_fc_replay_scan(journal_t + case EXT4_FC_TAG_PAD: + state->fc_cur_tag++; + state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur, +- sizeof(tl) + le16_to_cpu(tl.fc_len)); ++ EXT4_FC_TAG_BASE_LEN + le16_to_cpu(tl.fc_len)); + break; + case EXT4_FC_TAG_TAIL: + state->fc_cur_tag++; + memcpy(&tail, val, sizeof(tail)); + state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur, +- sizeof(tl) + ++ EXT4_FC_TAG_BASE_LEN + + offsetof(struct ext4_fc_tail, + fc_crc)); + if (le32_to_cpu(tail.fc_tid) == expected_tid && +@@ -2015,7 +2016,7 @@ static int ext4_fc_replay_scan(journal_t + } + state->fc_cur_tag++; + state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur, +- sizeof(tl) + le16_to_cpu(tl.fc_len)); ++ EXT4_FC_TAG_BASE_LEN + le16_to_cpu(tl.fc_len)); + break; + default: + ret = state->fc_replay_num_tags ? +@@ -2070,9 +2071,10 @@ static int ext4_fc_replay(journal_t *jou + start = (u8 *)bh->b_data; + end = (__u8 *)bh->b_data + journal->j_blocksize - 1; + +- for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) { +- memcpy(&tl, cur, sizeof(tl)); +- val = cur + sizeof(tl); ++ for (cur = start; cur < end; ++ cur = cur + EXT4_FC_TAG_BASE_LEN + le16_to_cpu(tl.fc_len)) { ++ memcpy(&tl, cur, EXT4_FC_TAG_BASE_LEN); ++ val = cur + EXT4_FC_TAG_BASE_LEN; + + if (state->fc_replay_num_tags == 0) { + ret = JBD2_FC_REPLAY_STOP; +--- a/fs/ext4/fast_commit.h ++++ b/fs/ext4/fast_commit.h +@@ -70,6 +70,9 @@ struct ext4_fc_tail { + __le32 fc_crc; + }; + ++/* Tag base length */ ++#define EXT4_FC_TAG_BASE_LEN (sizeof(struct ext4_fc_tl)) ++ + /* + * Fast commit status codes + */ diff --git a/queue-5.15/ext4-remove-unused-enum-ext4_fc_commit_failed.patch b/queue-5.15/ext4-remove-unused-enum-ext4_fc_commit_failed.patch new file mode 100644 index 00000000000..1f3a5d1e921 --- /dev/null +++ b/queue-5.15/ext4-remove-unused-enum-ext4_fc_commit_failed.patch @@ -0,0 +1,40 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:13 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:50 -0800 +Subject: ext4: remove unused enum EXT4_FC_COMMIT_FAILED +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, Ritesh Harjani , Jan Kara , Harshad Shirwadkar , Theodore Ts'o +Message-ID: <20230105071359.257952-2-ebiggers@kernel.org> + +From: Eric Biggers + +From: Ritesh Harjani + +commit c864ccd182d6ff2730a0f5b636c6b7c48f6f4f7f upstream. + +Below commit removed all references of EXT4_FC_COMMIT_FAILED. +commit 0915e464cb274 ("ext4: simplify updating of fast commit stats") + +Just remove it since it is not used anymore. + +Signed-off-by: Ritesh Harjani +Reviewed-by: Jan Kara +Reviewed-by: Harshad Shirwadkar +Link: https://lore.kernel.org/r/c941357e476be07a1138c7319ca5faab7fb80fc6.1647057583.git.riteshh@linux.ibm.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/fast_commit.h | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/ext4/fast_commit.h ++++ b/fs/ext4/fast_commit.h +@@ -93,7 +93,6 @@ enum { + EXT4_FC_REASON_RENAME_DIR, + EXT4_FC_REASON_FALLOC_RANGE, + EXT4_FC_REASON_INODE_JOURNAL_DATA, +- EXT4_FC_COMMIT_FAILED, + EXT4_FC_REASON_MAX + }; + diff --git a/queue-5.15/ext4-use-ext4_debug-instead-of-jbd_debug.patch b/queue-5.15/ext4-use-ext4_debug-instead-of-jbd_debug.patch new file mode 100644 index 00000000000..aba33297ce8 --- /dev/null +++ b/queue-5.15/ext4-use-ext4_debug-instead-of-jbd_debug.patch @@ -0,0 +1,381 @@ +From stable-owner@vger.kernel.org Thu Jan 5 08:17:15 2023 +From: Eric Biggers +Date: Wed, 4 Jan 2023 23:13:51 -0800 +Subject: ext4: use ext4_debug() instead of jbd_debug() +To: stable@vger.kernel.org +Cc: linux-ext4@vger.kernel.org, Jan Kara , Lukas Czerner , Theodore Ts'o +Message-ID: <20230105071359.257952-3-ebiggers@kernel.org> + +From: Eric Biggers + +From: Jan Kara + +commit 4978c659e7b5c1926cdb4b556e4ca1fd2de8ad42 upstream. + +We use jbd_debug() in some places in ext4. It seems a bit strange to use +jbd2 debugging output function for ext4 code. Also these days +ext4_debug() uses dynamic printk so each debug message can be enabled / +disabled on its own so the time when it made some sense to have these +combined (to allow easier common selecting of messages to report) has +passed. Just convert all jbd_debug() uses in ext4 to ext4_debug(). + +Signed-off-by: Jan Kara +Reviewed-by: Lukas Czerner +Link: https://lore.kernel.org/r/20220608112355.4397-1-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/balloc.c | 2 +- + fs/ext4/ext4_jbd2.c | 3 +-- + fs/ext4/fast_commit.c | 44 ++++++++++++++++++++++---------------------- + fs/ext4/indirect.c | 4 ++-- + fs/ext4/inode.c | 2 +- + fs/ext4/orphan.c | 24 ++++++++++++------------ + fs/ext4/super.c | 2 +- + 7 files changed, 40 insertions(+), 41 deletions(-) + +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -665,7 +665,7 @@ int ext4_should_retry_alloc(struct super + * it's possible we've just missed a transaction commit here, + * so ignore the returned status + */ +- jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); ++ ext4_debug("%s: retrying operation after ENOSPC\n", sb->s_id); + (void) jbd2_journal_force_commit_nested(sbi->s_journal); + return 1; + } +--- a/fs/ext4/ext4_jbd2.c ++++ b/fs/ext4/ext4_jbd2.c +@@ -267,8 +267,7 @@ int __ext4_forget(const char *where, uns + trace_ext4_forget(inode, is_metadata, blocknr); + BUFFER_TRACE(bh, "enter"); + +- jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, " +- "data mode %x\n", ++ ext4_debug("forgetting bh %p: is_metadata=%d, mode %o, data mode %x\n", + bh, is_metadata, inode->i_mode, + test_opt(inode->i_sb, DATA_FLAGS)); + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -845,8 +845,8 @@ static int ext4_fc_write_inode_data(stru + mutex_unlock(&ei->i_fc_lock); + + cur_lblk_off = old_blk_size; +- jbd_debug(1, "%s: will try writing %d to %d for inode %ld\n", +- __func__, cur_lblk_off, new_blk_size, inode->i_ino); ++ ext4_debug("will try writing %d to %d for inode %ld\n", ++ cur_lblk_off, new_blk_size, inode->i_ino); + + while (cur_lblk_off <= new_blk_size) { + map.m_lblk = cur_lblk_off; +@@ -1101,7 +1101,7 @@ static void ext4_fc_update_stats(struct + { + struct ext4_fc_stats *stats = &EXT4_SB(sb)->s_fc_stats; + +- jbd_debug(1, "Fast commit ended with status = %d", status); ++ ext4_debug("Fast commit ended with status = %d", status); + if (status == EXT4_FC_STATUS_OK) { + stats->fc_num_commits++; + stats->fc_numblks += nblks; +@@ -1303,14 +1303,14 @@ static int ext4_fc_replay_unlink(struct + inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL); + + if (IS_ERR(inode)) { +- jbd_debug(1, "Inode %d not found", darg.ino); ++ ext4_debug("Inode %d not found", darg.ino); + return 0; + } + + old_parent = ext4_iget(sb, darg.parent_ino, + EXT4_IGET_NORMAL); + if (IS_ERR(old_parent)) { +- jbd_debug(1, "Dir with inode %d not found", darg.parent_ino); ++ ext4_debug("Dir with inode %d not found", darg.parent_ino); + iput(inode); + return 0; + } +@@ -1335,21 +1335,21 @@ static int ext4_fc_replay_link_internal( + + dir = ext4_iget(sb, darg->parent_ino, EXT4_IGET_NORMAL); + if (IS_ERR(dir)) { +- jbd_debug(1, "Dir with inode %d not found.", darg->parent_ino); ++ ext4_debug("Dir with inode %d not found.", darg->parent_ino); + dir = NULL; + goto out; + } + + dentry_dir = d_obtain_alias(dir); + if (IS_ERR(dentry_dir)) { +- jbd_debug(1, "Failed to obtain dentry"); ++ ext4_debug("Failed to obtain dentry"); + dentry_dir = NULL; + goto out; + } + + dentry_inode = d_alloc(dentry_dir, &qstr_dname); + if (!dentry_inode) { +- jbd_debug(1, "Inode dentry not created."); ++ ext4_debug("Inode dentry not created."); + ret = -ENOMEM; + goto out; + } +@@ -1362,7 +1362,7 @@ static int ext4_fc_replay_link_internal( + * could complete. + */ + if (ret && ret != -EEXIST) { +- jbd_debug(1, "Failed to link\n"); ++ ext4_debug("Failed to link\n"); + goto out; + } + +@@ -1396,7 +1396,7 @@ static int ext4_fc_replay_link(struct su + + inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL); + if (IS_ERR(inode)) { +- jbd_debug(1, "Inode not found."); ++ ext4_debug("Inode not found."); + return 0; + } + +@@ -1506,7 +1506,7 @@ static int ext4_fc_replay_inode(struct s + /* Given that we just wrote the inode on disk, this SHOULD succeed. */ + inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); + if (IS_ERR(inode)) { +- jbd_debug(1, "Inode not found."); ++ ext4_debug("Inode not found."); + return -EFSCORRUPTED; + } + +@@ -1559,7 +1559,7 @@ static int ext4_fc_replay_create(struct + + inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL); + if (IS_ERR(inode)) { +- jbd_debug(1, "inode %d not found.", darg.ino); ++ ext4_debug("inode %d not found.", darg.ino); + inode = NULL; + ret = -EINVAL; + goto out; +@@ -1572,7 +1572,7 @@ static int ext4_fc_replay_create(struct + */ + dir = ext4_iget(sb, darg.parent_ino, EXT4_IGET_NORMAL); + if (IS_ERR(dir)) { +- jbd_debug(1, "Dir %d not found.", darg.ino); ++ ext4_debug("Dir %d not found.", darg.ino); + goto out; + } + ret = ext4_init_new_dir(NULL, dir, inode); +@@ -1660,7 +1660,7 @@ static int ext4_fc_replay_add_range(stru + + inode = ext4_iget(sb, le32_to_cpu(fc_add_ex.fc_ino), EXT4_IGET_NORMAL); + if (IS_ERR(inode)) { +- jbd_debug(1, "Inode not found."); ++ ext4_debug("Inode not found."); + return 0; + } + +@@ -1674,7 +1674,7 @@ static int ext4_fc_replay_add_range(stru + + cur = start; + remaining = len; +- jbd_debug(1, "ADD_RANGE, lblk %d, pblk %lld, len %d, unwritten %d, inode %ld\n", ++ ext4_debug("ADD_RANGE, lblk %d, pblk %lld, len %d, unwritten %d, inode %ld\n", + start, start_pblk, len, ext4_ext_is_unwritten(ex), + inode->i_ino); + +@@ -1735,7 +1735,7 @@ static int ext4_fc_replay_add_range(stru + } + + /* Range is mapped and needs a state change */ +- jbd_debug(1, "Converting from %ld to %d %lld", ++ ext4_debug("Converting from %ld to %d %lld", + map.m_flags & EXT4_MAP_UNWRITTEN, + ext4_ext_is_unwritten(ex), map.m_pblk); + ret = ext4_ext_replay_update_ex(inode, cur, map.m_len, +@@ -1778,7 +1778,7 @@ ext4_fc_replay_del_range(struct super_bl + + inode = ext4_iget(sb, le32_to_cpu(lrange.fc_ino), EXT4_IGET_NORMAL); + if (IS_ERR(inode)) { +- jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange.fc_ino)); ++ ext4_debug("Inode %d not found", le32_to_cpu(lrange.fc_ino)); + return 0; + } + +@@ -1786,7 +1786,7 @@ ext4_fc_replay_del_range(struct super_bl + if (ret) + goto out; + +- jbd_debug(1, "DEL_RANGE, inode %ld, lblk %d, len %d\n", ++ ext4_debug("DEL_RANGE, inode %ld, lblk %d, len %d\n", + inode->i_ino, le32_to_cpu(lrange.fc_lblk), + le32_to_cpu(lrange.fc_len)); + while (remaining > 0) { +@@ -1835,7 +1835,7 @@ static void ext4_fc_set_bitmaps_and_coun + inode = ext4_iget(sb, state->fc_modified_inodes[i], + EXT4_IGET_NORMAL); + if (IS_ERR(inode)) { +- jbd_debug(1, "Inode %d not found.", ++ ext4_debug("Inode %d not found.", + state->fc_modified_inodes[i]); + continue; + } +@@ -1960,7 +1960,7 @@ static int ext4_fc_replay_scan(journal_t + for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) { + memcpy(&tl, cur, sizeof(tl)); + val = cur + sizeof(tl); +- jbd_debug(3, "Scan phase, tag:%s, blk %lld\n", ++ ext4_debug("Scan phase, tag:%s, blk %lld\n", + tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr); + switch (le16_to_cpu(tl.fc_tag)) { + case EXT4_FC_TAG_ADD_RANGE: +@@ -2055,7 +2055,7 @@ static int ext4_fc_replay(journal_t *jou + sbi->s_mount_state |= EXT4_FC_REPLAY; + } + if (!sbi->s_fc_replay_state.fc_replay_num_tags) { +- jbd_debug(1, "Replay stops\n"); ++ ext4_debug("Replay stops\n"); + ext4_fc_set_bitmaps_and_counters(sb); + return 0; + } +@@ -2079,7 +2079,7 @@ static int ext4_fc_replay(journal_t *jou + ext4_fc_set_bitmaps_and_counters(sb); + break; + } +- jbd_debug(3, "Replay phase, tag:%s\n", ++ ext4_debug("Replay phase, tag:%s\n", + tag2str(le16_to_cpu(tl.fc_tag))); + state->fc_replay_num_tags--; + switch (le16_to_cpu(tl.fc_tag)) { +--- a/fs/ext4/indirect.c ++++ b/fs/ext4/indirect.c +@@ -467,7 +467,7 @@ static int ext4_splice_branch(handle_t * + * the new i_size. But that is not done here - it is done in + * generic_commit_write->__mark_inode_dirty->ext4_dirty_inode. + */ +- jbd_debug(5, "splicing indirect only\n"); ++ ext4_debug("splicing indirect only\n"); + BUFFER_TRACE(where->bh, "call ext4_handle_dirty_metadata"); + err = ext4_handle_dirty_metadata(handle, ar->inode, where->bh); + if (err) +@@ -479,7 +479,7 @@ static int ext4_splice_branch(handle_t * + err = ext4_mark_inode_dirty(handle, ar->inode); + if (unlikely(err)) + goto err_out; +- jbd_debug(5, "splicing direct\n"); ++ ext4_debug("splicing direct\n"); + } + return err; + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5220,7 +5220,7 @@ int ext4_write_inode(struct inode *inode + + if (EXT4_SB(inode->i_sb)->s_journal) { + if (ext4_journal_current_handle()) { +- jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n"); ++ ext4_debug("called recursively, non-PF_MEMALLOC!\n"); + dump_stack(); + return -EIO; + } +--- a/fs/ext4/orphan.c ++++ b/fs/ext4/orphan.c +@@ -181,8 +181,8 @@ int ext4_orphan_add(handle_t *handle, st + } else + brelse(iloc.bh); + +- jbd_debug(4, "superblock will point to %lu\n", inode->i_ino); +- jbd_debug(4, "orphan inode %lu will point to %d\n", ++ ext4_debug("superblock will point to %lu\n", inode->i_ino); ++ ext4_debug("orphan inode %lu will point to %d\n", + inode->i_ino, NEXT_ORPHAN(inode)); + out: + ext4_std_error(sb, err); +@@ -251,7 +251,7 @@ int ext4_orphan_del(handle_t *handle, st + } + + mutex_lock(&sbi->s_orphan_lock); +- jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); ++ ext4_debug("remove inode %lu from orphan list\n", inode->i_ino); + + prev = ei->i_orphan.prev; + list_del_init(&ei->i_orphan); +@@ -267,7 +267,7 @@ int ext4_orphan_del(handle_t *handle, st + + ino_next = NEXT_ORPHAN(inode); + if (prev == &sbi->s_orphan) { +- jbd_debug(4, "superblock will point to %u\n", ino_next); ++ ext4_debug("superblock will point to %u\n", ino_next); + BUFFER_TRACE(sbi->s_sbh, "get_write_access"); + err = ext4_journal_get_write_access(handle, inode->i_sb, + sbi->s_sbh, EXT4_JTR_NONE); +@@ -286,7 +286,7 @@ int ext4_orphan_del(handle_t *handle, st + struct inode *i_prev = + &list_entry(prev, struct ext4_inode_info, i_orphan)->vfs_inode; + +- jbd_debug(4, "orphan inode %lu will point to %u\n", ++ ext4_debug("orphan inode %lu will point to %u\n", + i_prev->i_ino, ino_next); + err = ext4_reserve_inode_write(handle, i_prev, &iloc2); + if (err) { +@@ -332,8 +332,8 @@ static void ext4_process_orphan(struct i + ext4_msg(sb, KERN_DEBUG, + "%s: truncating inode %lu to %lld bytes", + __func__, inode->i_ino, inode->i_size); +- jbd_debug(2, "truncating inode %lu to %lld bytes\n", +- inode->i_ino, inode->i_size); ++ ext4_debug("truncating inode %lu to %lld bytes\n", ++ inode->i_ino, inode->i_size); + inode_lock(inode); + truncate_inode_pages(inode->i_mapping, inode->i_size); + ret = ext4_truncate(inode); +@@ -353,8 +353,8 @@ static void ext4_process_orphan(struct i + ext4_msg(sb, KERN_DEBUG, + "%s: deleting unreferenced inode %lu", + __func__, inode->i_ino); +- jbd_debug(2, "deleting unreferenced inode %lu\n", +- inode->i_ino); ++ ext4_debug("deleting unreferenced inode %lu\n", ++ inode->i_ino); + (*nr_orphans)++; + } + iput(inode); /* The delete magic happens here! */ +@@ -391,7 +391,7 @@ void ext4_orphan_cleanup(struct super_bl + int inodes_per_ob = ext4_inodes_per_orphan_block(sb); + + if (!es->s_last_orphan && !oi->of_blocks) { +- jbd_debug(4, "no orphan inodes to clean up\n"); ++ ext4_debug("no orphan inodes to clean up\n"); + return; + } + +@@ -415,7 +415,7 @@ void ext4_orphan_cleanup(struct super_bl + "clearing orphan list."); + es->s_last_orphan = 0; + } +- jbd_debug(1, "Skipping orphan recovery on fs with errors.\n"); ++ ext4_debug("Skipping orphan recovery on fs with errors.\n"); + return; + } + +@@ -459,7 +459,7 @@ void ext4_orphan_cleanup(struct super_bl + * so, skip the rest. + */ + if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) { +- jbd_debug(1, "Skipping orphan recovery on fs with errors.\n"); ++ ext4_debug("Skipping orphan recovery on fs with errors.\n"); + es->s_last_orphan = 0; + break; + } +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5154,7 +5154,7 @@ static struct inode *ext4_get_journal_in + return NULL; + } + +- jbd_debug(2, "Journal inode found at %p: %lld bytes\n", ++ ext4_debug("Journal inode found at %p: %lld bytes\n", + journal_inode, journal_inode->i_size); + if (!S_ISREG(journal_inode->i_mode)) { + ext4_msg(sb, KERN_ERR, "invalid journal inode"); diff --git a/queue-5.15/series b/queue-5.15/series index 9b47cb47d2f..d8f81d57bcf 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -163,3 +163,14 @@ ext4-allocate-extended-attribute-value-in-vmalloc-area.patch drm-amdgpu-handle-polaris10-11-overlap-asics-v2.patch drm-amdgpu-make-display-pinning-more-flexible-v2.patch block-mq-deadline-fix-dd_finish_request-for-zoned-devices.patch +tracing-fix-issue-of-missing-one-synthetic-field.patch +ext4-remove-unused-enum-ext4_fc_commit_failed.patch +ext4-use-ext4_debug-instead-of-jbd_debug.patch +ext4-introduce-ext4_fc_tag_base_len-helper.patch +ext4-factor-out-ext4_fc_get_tl.patch +ext4-fix-potential-out-of-bound-read-in-ext4_fc_replay_scan.patch +ext4-disable-fast-commit-of-encrypted-dir-operations.patch +ext4-don-t-set-up-encryption-key-during-jbd2-transaction.patch +ext4-add-missing-validation-of-fast-commit-record-lengths.patch +ext4-fix-unaligned-memory-access-in-ext4_fc_reserve_space.patch +ext4-fix-off-by-one-errors-in-fast-commit-block-filling.patch diff --git a/queue-5.15/tracing-fix-issue-of-missing-one-synthetic-field.patch b/queue-5.15/tracing-fix-issue-of-missing-one-synthetic-field.patch new file mode 100644 index 00000000000..030f4f45e90 --- /dev/null +++ b/queue-5.15/tracing-fix-issue-of-missing-one-synthetic-field.patch @@ -0,0 +1,56 @@ +From ff4837f7fe59ff018eca4705a70eca5e0b486b97 Mon Sep 17 00:00:00 2001 +From: Zheng Yejian +Date: Wed, 7 Dec 2022 17:15:57 +0800 +Subject: tracing: Fix issue of missing one synthetic field + +From: Zheng Yejian + +commit ff4837f7fe59ff018eca4705a70eca5e0b486b97 upstream. + +The maximum number of synthetic fields supported is defined as +SYNTH_FIELDS_MAX which value currently is 64, but it actually fails +when try to generate a synthetic event with 64 fields by executing like: + + # echo "my_synth_event int v1; int v2; int v3; int v4; int v5; int v6;\ + int v7; int v8; int v9; int v10; int v11; int v12; int v13; int v14;\ + int v15; int v16; int v17; int v18; int v19; int v20; int v21; int v22;\ + int v23; int v24; int v25; int v26; int v27; int v28; int v29; int v30;\ + int v31; int v32; int v33; int v34; int v35; int v36; int v37; int v38;\ + int v39; int v40; int v41; int v42; int v43; int v44; int v45; int v46;\ + int v47; int v48; int v49; int v50; int v51; int v52; int v53; int v54;\ + int v55; int v56; int v57; int v58; int v59; int v60; int v61; int v62;\ + int v63; int v64" >> /sys/kernel/tracing/synthetic_events + +Correct the field counting to fix it. + +Link: https://lore.kernel.org/linux-trace-kernel/20221207091557.3137904-1-zhengyejian1@huawei.com + +Cc: +Cc: +Cc: stable@vger.kernel.org +Fixes: c9e759b1e845 ("tracing: Rework synthetic event command parsing") +Signed-off-by: Zheng Yejian +Signed-off-by: Steven Rostedt (Google) +[Fix conflict due to lack of c24be24aed405d64ebcf04526614c13b2adfb1d2] +Signed-off-by: Zheng Yejian +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace_events_synth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/trace/trace_events_synth.c ++++ b/kernel/trace/trace_events_synth.c +@@ -1275,12 +1275,12 @@ static int __create_synth_event(const ch + goto err; + } + +- fields[n_fields++] = field; + if (n_fields == SYNTH_FIELDS_MAX) { + synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0); + ret = -EINVAL; + goto err; + } ++ fields[n_fields++] = field; + + n_fields_this_loop++; + }