From 307bf2e9b6a95372d033e68a99871353867f0c50 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 13 Oct 2025 11:17:04 +0200 Subject: [PATCH] 5.15-stable patches added patches: ext4-fix-checks-for-orphan-inodes.patch --- .../ext4-fix-checks-for-orphan-inodes.patch | 106 ++++++++++++++++++ queue-5.15/series | 1 + 2 files changed, 107 insertions(+) create mode 100644 queue-5.15/ext4-fix-checks-for-orphan-inodes.patch diff --git a/queue-5.15/ext4-fix-checks-for-orphan-inodes.patch b/queue-5.15/ext4-fix-checks-for-orphan-inodes.patch new file mode 100644 index 0000000000..8a82e0090e --- /dev/null +++ b/queue-5.15/ext4-fix-checks-for-orphan-inodes.patch @@ -0,0 +1,106 @@ +From acf943e9768ec9d9be80982ca0ebc4bfd6b7631e Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 25 Sep 2025 14:30:39 +0200 +Subject: ext4: fix checks for orphan inodes + +From: Jan Kara + +commit acf943e9768ec9d9be80982ca0ebc4bfd6b7631e upstream. + +When orphan file feature is enabled, inode can be tracked as orphan +either in the standard orphan list or in the orphan file. The first can +be tested by checking ei->i_orphan list head, the second is recorded by +EXT4_STATE_ORPHAN_FILE inode state flag. There are several places where +we want to check whether inode is tracked as orphan and only some of +them properly check for both possibilities. Luckily the consequences are +mostly minor, the worst that can happen is that we track an inode as +orphan although we don't need to and e2fsck then complains (resulting in +occasional ext4/307 xfstest failures). Fix the problem by introducing a +helper for checking whether an inode is tracked as orphan and use it in +appropriate places. + +Fixes: 4a79a98c7b19 ("ext4: Improve scalability of ext4 orphan file handling") +Cc: stable@kernel.org +Signed-off-by: Jan Kara +Reviewed-by: Zhang Yi +Message-ID: <20250925123038.20264-2-jack@suse.cz> +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/ext4.h | 10 ++++++++++ + fs/ext4/file.c | 2 +- + fs/ext4/inode.c | 2 +- + fs/ext4/orphan.c | 6 +----- + fs/ext4/super.c | 4 ++-- + 5 files changed, 15 insertions(+), 9 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1944,6 +1944,16 @@ static inline bool ext4_verity_in_progre + #define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime + + /* ++ * Check whether the inode is tracked as orphan (either in orphan file or ++ * orphan list). ++ */ ++static inline bool ext4_inode_orphan_tracked(struct inode *inode) ++{ ++ return ext4_test_inode_state(inode, EXT4_STATE_ORPHAN_FILE) || ++ !list_empty(&EXT4_I(inode)->i_orphan); ++} ++ ++/* + * Codes for operating systems + */ + #define EXT4_OS_LINUX 0 +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -327,7 +327,7 @@ static void ext4_inode_extension_cleanup + * to cleanup the orphan list in ext4_handle_inode_extension(). Do it + * now. + */ +- if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) { ++ if (ext4_inode_orphan_tracked(inode) && inode->i_nlink) { + handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); + + if (IS_ERR(handle)) { +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5122,7 +5122,7 @@ static int ext4_do_update_inode(handle_t + * old inodes get re-used with the upper 16 bits of the + * uid/gid intact. + */ +- if (ei->i_dtime && list_empty(&ei->i_orphan)) { ++ if (ei->i_dtime && !ext4_inode_orphan_tracked(inode)) { + raw_inode->i_uid_high = 0; + raw_inode->i_gid_high = 0; + } else { +--- a/fs/ext4/orphan.c ++++ b/fs/ext4/orphan.c +@@ -109,11 +109,7 @@ int ext4_orphan_add(handle_t *handle, st + + WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) && + !inode_is_locked(inode)); +- /* +- * Inode orphaned in orphan file or in orphan list? +- */ +- if (ext4_test_inode_state(inode, EXT4_STATE_ORPHAN_FILE) || +- !list_empty(&EXT4_I(inode)->i_orphan)) ++ if (ext4_inode_orphan_tracked(inode)) + return 0; + + /* +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1352,9 +1352,9 @@ static void ext4_free_in_core_inode(stru + + static void ext4_destroy_inode(struct inode *inode) + { +- if (!list_empty(&(EXT4_I(inode)->i_orphan))) { ++ if (ext4_inode_orphan_tracked(inode)) { + ext4_msg(inode->i_sb, KERN_ERR, +- "Inode %lu (%p): orphan list check failed!", ++ "Inode %lu (%p): inode tracked as orphan!", + inode->i_ino, EXT4_I(inode)); + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4, + EXT4_I(inode), sizeof(struct ext4_inode_info), diff --git a/queue-5.15/series b/queue-5.15/series index d8b3af2390..80907edc56 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -110,3 +110,4 @@ uio_hv_generic-let-userspace-take-care-of-interrupt-mask.patch fs-udf-fix-oob-read-in-lengthallocdescs-handling.patch net-nfc-nci-add-parameter-validation-for-packet-data.patch mfd-vexpress-sysreg-check-the-return-value-of-devm_gpiochip_add_data.patch +ext4-fix-checks-for-orphan-inodes.patch -- 2.47.3