]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Oct 2025 09:17:04 +0000 (11:17 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Oct 2025 09:17:04 +0000 (11:17 +0200)
added patches:
ext4-fix-checks-for-orphan-inodes.patch

queue-5.15/ext4-fix-checks-for-orphan-inodes.patch [new file with mode: 0644]
queue-5.15/series

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 (file)
index 0000000..8a82e00
--- /dev/null
@@ -0,0 +1,106 @@
+From acf943e9768ec9d9be80982ca0ebc4bfd6b7631e Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 25 Sep 2025 14:30:39 +0200
+Subject: ext4: fix checks for orphan inodes
+
+From: Jan Kara <jack@suse.cz>
+
+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 <jack@suse.cz>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Message-ID: <20250925123038.20264-2-jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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),
index d8b3af2390be5eeef60e6bbde15769267289918c..80907edc565f2736f5b427c5a1d8f694af837abd 100644 (file)
@@ -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