]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jan 2023 15:13:01 +0000 (16:13 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jan 2023 15:13:01 +0000 (16:13 +0100)
added patches:
ext4-allocate-extended-attribute-value-in-vmalloc-area.patch
ext4-avoid-bug_on-when-creating-xattrs.patch
ext4-avoid-unaccounted-block-allocation-when-expanding-inode.patch
ext4-don-t-fail-getfsuuid-when-the-caller-provides-a-long-buffer.patch
ext4-dont-return-einval-from-getfsuuid-when-reporting-uuid-length.patch
ext4-fix-bad-checksum-after-online-resize.patch
ext4-fix-corrupt-backup-group-descriptors-after-online-resize.patch
ext4-fix-corruption-when-online-resizing-a-1k-bigalloc-fs.patch
ext4-fix-deadlock-due-to-mbcache-entry-corruption.patch
ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-for-bigalloc-inline.patch
ext4-fix-error-code-return-to-user-space-in-ext4_get_branch.patch
ext4-fix-inode-leak-in-ext4_xattr_inode_create-on-an-error-path.patch
ext4-fix-kernel-bug-in-ext4_write_inline_data_end.patch
ext4-init-quota-for-old.inode-in-ext4_rename.patch
ext4-initialize-quota-before-expanding-inode-in-setproject-ioctl.patch

16 files changed:
queue-6.1/ext4-allocate-extended-attribute-value-in-vmalloc-area.patch [new file with mode: 0644]
queue-6.1/ext4-avoid-bug_on-when-creating-xattrs.patch [new file with mode: 0644]
queue-6.1/ext4-avoid-unaccounted-block-allocation-when-expanding-inode.patch [new file with mode: 0644]
queue-6.1/ext4-don-t-fail-getfsuuid-when-the-caller-provides-a-long-buffer.patch [new file with mode: 0644]
queue-6.1/ext4-dont-return-einval-from-getfsuuid-when-reporting-uuid-length.patch [new file with mode: 0644]
queue-6.1/ext4-fix-bad-checksum-after-online-resize.patch [new file with mode: 0644]
queue-6.1/ext4-fix-corrupt-backup-group-descriptors-after-online-resize.patch [new file with mode: 0644]
queue-6.1/ext4-fix-corruption-when-online-resizing-a-1k-bigalloc-fs.patch [new file with mode: 0644]
queue-6.1/ext4-fix-deadlock-due-to-mbcache-entry-corruption.patch [new file with mode: 0644]
queue-6.1/ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-for-bigalloc-inline.patch [new file with mode: 0644]
queue-6.1/ext4-fix-error-code-return-to-user-space-in-ext4_get_branch.patch [new file with mode: 0644]
queue-6.1/ext4-fix-inode-leak-in-ext4_xattr_inode_create-on-an-error-path.patch [new file with mode: 0644]
queue-6.1/ext4-fix-kernel-bug-in-ext4_write_inline_data_end.patch [new file with mode: 0644]
queue-6.1/ext4-init-quota-for-old.inode-in-ext4_rename.patch [new file with mode: 0644]
queue-6.1/ext4-initialize-quota-before-expanding-inode-in-setproject-ioctl.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/ext4-allocate-extended-attribute-value-in-vmalloc-area.patch b/queue-6.1/ext4-allocate-extended-attribute-value-in-vmalloc-area.patch
new file mode 100644 (file)
index 0000000..380f965
--- /dev/null
@@ -0,0 +1,45 @@
+From cc12a6f25e07ed05d5825a1664b67a970842b2ca Mon Sep 17 00:00:00 2001
+From: Ye Bin <yebin10@huawei.com>
+Date: Thu, 8 Dec 2022 10:32:31 +0800
+Subject: ext4: allocate extended attribute value in vmalloc area
+
+From: Ye Bin <yebin10@huawei.com>
+
+commit cc12a6f25e07ed05d5825a1664b67a970842b2ca upstream.
+
+Now, extended attribute value maximum length is 64K. The memory
+requested here does not need continuous physical addresses, so it is
+appropriate to use kvmalloc to request memory. At the same time, it
+can also cope with the situation that the extended attribute will
+become longer in the future.
+
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20221208023233.1231330-3-yebin@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -2550,7 +2550,7 @@ static int ext4_xattr_move_to_block(hand
+       is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
+       bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS);
+-      buffer = kmalloc(value_size, GFP_NOFS);
++      buffer = kvmalloc(value_size, GFP_NOFS);
+       b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS);
+       if (!is || !bs || !buffer || !b_entry_name) {
+               error = -ENOMEM;
+@@ -2602,7 +2602,7 @@ static int ext4_xattr_move_to_block(hand
+       error = 0;
+ out:
+       kfree(b_entry_name);
+-      kfree(buffer);
++      kvfree(buffer);
+       if (is)
+               brelse(is->iloc.bh);
+       if (bs)
diff --git a/queue-6.1/ext4-avoid-bug_on-when-creating-xattrs.patch b/queue-6.1/ext4-avoid-bug_on-when-creating-xattrs.patch
new file mode 100644 (file)
index 0000000..6d9e4dc
--- /dev/null
@@ -0,0 +1,53 @@
+From b40ebaf63851b3a401b0dc9263843538f64f5ce6 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 21 Nov 2022 14:09:29 +0100
+Subject: ext4: avoid BUG_ON when creating xattrs
+
+From: Jan Kara <jack@suse.cz>
+
+commit b40ebaf63851b3a401b0dc9263843538f64f5ce6 upstream.
+
+Commit fb0a387dcdcd ("ext4: limit block allocations for indirect-block
+files to < 2^32") added code to try to allocate xattr block with 32-bit
+block number for indirect block based files on the grounds that these
+files cannot use larger block numbers. It also added BUG_ON when
+allocated block could not fit into 32 bits. This is however bogus
+reasoning because xattr block is stored in inode->i_file_acl and
+inode->i_file_acl_hi and as such even indirect block based files can
+happily use full 48 bits for xattr block number. The proper handling
+seems to be there basically since 64-bit block number support was added.
+So remove the bogus limitation and BUG_ON.
+
+Cc: Eric Sandeen <sandeen@redhat.com>
+Fixes: fb0a387dcdcd ("ext4: limit block allocations for indirect-block files to < 2^32")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20221121130929.32031-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c |    8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -2070,19 +2070,11 @@ inserted:
+                       goal = ext4_group_first_block_no(sb,
+                                               EXT4_I(inode)->i_block_group);
+-
+-                      /* non-extent files can't have physical blocks past 2^32 */
+-                      if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+-                              goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
+-
+                       block = ext4_new_meta_blocks(handle, inode, goal, 0,
+                                                    NULL, &error);
+                       if (error)
+                               goto cleanup;
+-                      if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+-                              BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS);
+-
+                       ea_idebug(inode, "creating block %llu",
+                                 (unsigned long long)block);
diff --git a/queue-6.1/ext4-avoid-unaccounted-block-allocation-when-expanding-inode.patch b/queue-6.1/ext4-avoid-unaccounted-block-allocation-when-expanding-inode.patch
new file mode 100644 (file)
index 0000000..ae0a2ff
--- /dev/null
@@ -0,0 +1,42 @@
+From 8994d11395f8165b3deca1971946f549f0822630 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 7 Dec 2022 12:59:28 +0100
+Subject: ext4: avoid unaccounted block allocation when expanding inode
+
+From: Jan Kara <jack@suse.cz>
+
+commit 8994d11395f8165b3deca1971946f549f0822630 upstream.
+
+When expanding inode space in ext4_expand_extra_isize_ea() we may need
+to allocate external xattr block. If quota is not initialized for the
+inode, the block allocation will not be accounted into quota usage. Make
+sure the quota is initialized before we try to expand inode space.
+
+Reported-by: Pengfei Xu <pengfei.xu@intel.com>
+Link: https://lore.kernel.org/all/Y5BT+k6xWqthZc1P@xpf.sh.intel.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Cc: stable@kernel.org
+Link: https://lore.kernel.org/r/20221207115937.26601-2-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/inode.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -5875,6 +5875,14 @@ static int __ext4_expand_extra_isize(str
+               return 0;
+       }
++      /*
++       * We may need to allocate external xattr block so we need quotas
++       * initialized. Here we can be called with various locks held so we
++       * cannot affort to initialize quotas ourselves. So just bail.
++       */
++      if (dquot_initialize_needed(inode))
++              return -EAGAIN;
++
+       /* try to expand with EAs present */
+       error = ext4_expand_extra_isize_ea(inode, new_extra_isize,
+                                          raw_inode, handle);
diff --git a/queue-6.1/ext4-don-t-fail-getfsuuid-when-the-caller-provides-a-long-buffer.patch b/queue-6.1/ext4-don-t-fail-getfsuuid-when-the-caller-provides-a-long-buffer.patch
new file mode 100644 (file)
index 0000000..8da420b
--- /dev/null
@@ -0,0 +1,47 @@
+From a7e9d977e031fceefe1e7cd69ebd7202d5758b56 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Thu, 10 Nov 2022 12:16:34 -0800
+Subject: ext4: don't fail GETFSUUID when the caller provides a long buffer
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit a7e9d977e031fceefe1e7cd69ebd7202d5758b56 upstream.
+
+If userspace provides a longer UUID buffer than is required, we
+shouldn't fail the call with EINVAL -- rather, we can fill the caller's
+buffer with the bytes we /can/ fill, and update the length field to
+reflect what we copied.  This doesn't break the UAPI since we're
+enabling a case that currently fails, and so far Ted hasn't released a
+version of e2fsprogs that uses the new ext4 ioctl.
+
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Catherine Hoang <catherine.hoang@oracle.com>
+Link: https://lore.kernel.org/r/166811139478.327006.13879198441587445544.stgit@magnolia
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ioctl.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -1159,14 +1159,16 @@ static int ext4_ioctl_getuuid(struct ext
+               return -EINVAL;
+       }
+-      if (fsuuid.fsu_len != UUID_SIZE || fsuuid.fsu_flags != 0)
++      if (fsuuid.fsu_len < UUID_SIZE || fsuuid.fsu_flags != 0)
+               return -EINVAL;
+       lock_buffer(sbi->s_sbh);
+       memcpy(uuid, sbi->s_es->s_uuid, UUID_SIZE);
+       unlock_buffer(sbi->s_sbh);
+-      if (copy_to_user(&ufsuuid->fsu_uuid[0], uuid, UUID_SIZE))
++      fsuuid.fsu_len = UUID_SIZE;
++      if (copy_to_user(ufsuuid, &fsuuid, sizeof(fsuuid)) ||
++          copy_to_user(&ufsuuid->fsu_uuid[0], uuid, UUID_SIZE))
+               return -EFAULT;
+       return 0;
+ }
diff --git a/queue-6.1/ext4-dont-return-einval-from-getfsuuid-when-reporting-uuid-length.patch b/queue-6.1/ext4-dont-return-einval-from-getfsuuid-when-reporting-uuid-length.patch
new file mode 100644 (file)
index 0000000..94be29c
--- /dev/null
@@ -0,0 +1,42 @@
+From b76abb5157468756163fe7e3431c9fe32cba57ca Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Thu, 10 Nov 2022 12:16:29 -0800
+Subject: ext4: dont return EINVAL from GETFSUUID when reporting UUID length
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit b76abb5157468756163fe7e3431c9fe32cba57ca upstream.
+
+If userspace calls this ioctl with fsu_length (the length of the
+fsuuid.fsu_uuid array) set to zero, ext4 copies the desired uuid length
+out to userspace.  The kernel call returned a result from a valid input,
+so the return value here should be zero, not EINVAL.
+
+While we're at it, fix the copy_to_user call to make it clear that we're
+only copying out fsu_len.
+
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Catherine Hoang <catherine.hoang@oracle.com>
+Link: https://lore.kernel.org/r/166811138914.327006.9241306894437166566.stgit@magnolia
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ioctl.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -1154,9 +1154,10 @@ static int ext4_ioctl_getuuid(struct ext
+       if (fsuuid.fsu_len == 0) {
+               fsuuid.fsu_len = UUID_SIZE;
+-              if (copy_to_user(ufsuuid, &fsuuid, sizeof(fsuuid.fsu_len)))
++              if (copy_to_user(&ufsuuid->fsu_len, &fsuuid.fsu_len,
++                                      sizeof(fsuuid.fsu_len)))
+                       return -EFAULT;
+-              return -EINVAL;
++              return 0;
+       }
+       if (fsuuid.fsu_len < UUID_SIZE || fsuuid.fsu_flags != 0)
diff --git a/queue-6.1/ext4-fix-bad-checksum-after-online-resize.patch b/queue-6.1/ext4-fix-bad-checksum-after-online-resize.patch
new file mode 100644 (file)
index 0000000..8ee1fa3
--- /dev/null
@@ -0,0 +1,54 @@
+From a408f33e895e455f16cf964cb5cd4979b658db7b Mon Sep 17 00:00:00 2001
+From: Baokun Li <libaokun1@huawei.com>
+Date: Thu, 17 Nov 2022 12:03:39 +0800
+Subject: ext4: fix bad checksum after online resize
+
+From: Baokun Li <libaokun1@huawei.com>
+
+commit a408f33e895e455f16cf964cb5cd4979b658db7b upstream.
+
+When online resizing is performed twice consecutively, the error message
+"Superblock checksum does not match superblock" is displayed for the
+second time. Here's the reproducer:
+
+       mkfs.ext4 -F /dev/sdb 100M
+       mount /dev/sdb /tmp/test
+       resize2fs /dev/sdb 5G
+       resize2fs /dev/sdb 6G
+
+To solve this issue, we moved the update of the checksum after the
+es->s_overhead_clusters is updated.
+
+Fixes: 026d0d27c488 ("ext4: reduce computation of overhead during resize")
+Fixes: de394a86658f ("ext4: update s_overhead_clusters in the superblock during an on-line resize")
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: stable@kernel.org
+Link: https://lore.kernel.org/r/20221117040341.1380702-2-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/resize.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1476,8 +1476,6 @@ static void ext4_update_super(struct sup
+        * active. */
+       ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) +
+                               reserved_blocks);
+-      ext4_superblock_csum_set(sb);
+-      unlock_buffer(sbi->s_sbh);
+       /* Update the free space counts */
+       percpu_counter_add(&sbi->s_freeclusters_counter,
+@@ -1513,6 +1511,8 @@ static void ext4_update_super(struct sup
+               ext4_calculate_overhead(sb);
+       es->s_overhead_clusters = cpu_to_le32(sbi->s_overhead);
++      ext4_superblock_csum_set(sb);
++      unlock_buffer(sbi->s_sbh);
+       if (test_opt(sb, DEBUG))
+               printk(KERN_DEBUG "EXT4-fs: added group %u:"
+                      "%llu blocks(%llu free %llu reserved)\n", flex_gd->count,
diff --git a/queue-6.1/ext4-fix-corrupt-backup-group-descriptors-after-online-resize.patch b/queue-6.1/ext4-fix-corrupt-backup-group-descriptors-after-online-resize.patch
new file mode 100644 (file)
index 0000000..f25e1b3
--- /dev/null
@@ -0,0 +1,92 @@
+From 8f49ec603ae3e213bfab2799182724e3abac55a1 Mon Sep 17 00:00:00 2001
+From: Baokun Li <libaokun1@huawei.com>
+Date: Thu, 17 Nov 2022 12:03:40 +0800
+Subject: ext4: fix corrupt backup group descriptors after online resize
+
+From: Baokun Li <libaokun1@huawei.com>
+
+commit 8f49ec603ae3e213bfab2799182724e3abac55a1 upstream.
+
+In commit 9a8c5b0d0615 ("ext4: update the backup superblock's at the end
+of the online resize"), it is assumed that update_backups() only updates
+backup superblocks, so each b_data is treated as a backupsuper block to
+update its s_block_group_nr and s_checksum. However, update_backups()
+also updates the backup group descriptors, which causes the backup group
+descriptors to be corrupted.
+
+The above commit fixes the problem of invalid checksum of the backup
+superblock. The root cause of this problem is that the checksum of
+ext4_update_super() is not set correctly. This problem has been fixed
+in the previous patch ("ext4: fix bad checksum after online resize").
+
+However, we do need to set block_group_nr for the backup superblock in
+update_backups(). When a block is in a group that contains a backup
+superblock, and the block is the first block in the group, the block is
+definitely a superblock. We add a helper function that includes setting
+s_block_group_nr and updating checksum, and then call it only when the
+above conditions are met to prevent the backup group descriptors from
+being incorrectly modified.
+
+Fixes: 9a8c5b0d0615 ("ext4: update the backup superblock's at the end of the online resize")
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: stable@kernel.org
+Link: https://lore.kernel.org/r/20221117040341.1380702-3-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/resize.c |   22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1110,6 +1110,16 @@ exit_free:
+       return err;
+ }
++static inline void ext4_set_block_group_nr(struct super_block *sb, char *data,
++                                         ext4_group_t group)
++{
++      struct ext4_super_block *es = (struct ext4_super_block *) data;
++
++      es->s_block_group_nr = cpu_to_le16(group);
++      if (ext4_has_metadata_csum(sb))
++              es->s_checksum = ext4_superblock_csum(sb, es);
++}
++
+ /*
+  * Update the backup copies of the ext4 metadata.  These don't need to be part
+  * of the main resize transaction, because e2fsck will re-write them if there
+@@ -1158,7 +1168,8 @@ static void update_backups(struct super_
+       while (group < sbi->s_groups_count) {
+               struct buffer_head *bh;
+               ext4_fsblk_t backup_block;
+-              struct ext4_super_block *es;
++              int has_super = ext4_bg_has_super(sb, group);
++              ext4_fsblk_t first_block = ext4_group_first_block_no(sb, group);
+               /* Out of journal space, and can't get more - abort - so sad */
+               err = ext4_resize_ensure_credits_batch(handle, 1);
+@@ -1168,8 +1179,7 @@ static void update_backups(struct super_
+               if (meta_bg == 0)
+                       backup_block = ((ext4_fsblk_t)group) * bpg + blk_off;
+               else
+-                      backup_block = (ext4_group_first_block_no(sb, group) +
+-                                      ext4_bg_has_super(sb, group));
++                      backup_block = first_block + has_super;
+               bh = sb_getblk(sb, backup_block);
+               if (unlikely(!bh)) {
+@@ -1187,10 +1197,8 @@ static void update_backups(struct super_
+               memcpy(bh->b_data, data, size);
+               if (rest)
+                       memset(bh->b_data + size, 0, rest);
+-              es = (struct ext4_super_block *) bh->b_data;
+-              es->s_block_group_nr = cpu_to_le16(group);
+-              if (ext4_has_metadata_csum(sb))
+-                      es->s_checksum = ext4_superblock_csum(sb, es);
++              if (has_super && (backup_block == first_block))
++                      ext4_set_block_group_nr(sb, bh->b_data, group);
+               set_buffer_uptodate(bh);
+               unlock_buffer(bh);
+               err = ext4_handle_dirty_metadata(handle, NULL, bh);
diff --git a/queue-6.1/ext4-fix-corruption-when-online-resizing-a-1k-bigalloc-fs.patch b/queue-6.1/ext4-fix-corruption-when-online-resizing-a-1k-bigalloc-fs.patch
new file mode 100644 (file)
index 0000000..6398694
--- /dev/null
@@ -0,0 +1,53 @@
+From 0aeaa2559d6d53358fca3e3fce73807367adca74 Mon Sep 17 00:00:00 2001
+From: Baokun Li <libaokun1@huawei.com>
+Date: Thu, 17 Nov 2022 12:03:41 +0800
+Subject: ext4: fix corruption when online resizing a 1K bigalloc fs
+
+From: Baokun Li <libaokun1@huawei.com>
+
+commit 0aeaa2559d6d53358fca3e3fce73807367adca74 upstream.
+
+When a backup superblock is updated in update_backups(), the primary
+superblock's offset in the group (that is, sbi->s_sbh->b_blocknr) is used
+as the backup superblock's offset in its group. However, when the block
+size is 1K and bigalloc is enabled, the two offsets are not equal. This
+causes the backup group descriptors to be overwritten by the superblock
+in update_backups(). Moreover, if meta_bg is enabled, the file system will
+be corrupted because this feature uses backup group descriptors.
+
+To solve this issue, we use a more accurate ext4_group_first_block_no() as
+the offset of the backup superblock in its group.
+
+Fixes: d77147ff443b ("ext4: add support for online resizing with bigalloc")
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: stable@kernel.org
+Link: https://lore.kernel.org/r/20221117040341.1380702-4-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/resize.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1596,8 +1596,8 @@ exit_journal:
+               int meta_bg = ext4_has_feature_meta_bg(sb);
+               sector_t old_gdb = 0;
+-              update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
+-                             sizeof(struct ext4_super_block), 0);
++              update_backups(sb, ext4_group_first_block_no(sb, 0),
++                             (char *)es, sizeof(struct ext4_super_block), 0);
+               for (; gdb_num <= gdb_num_end; gdb_num++) {
+                       struct buffer_head *gdb_bh;
+@@ -1808,7 +1808,7 @@ errout:
+               if (test_opt(sb, DEBUG))
+                       printk(KERN_DEBUG "EXT4-fs: extended group to %llu "
+                              "blocks\n", ext4_blocks_count(es));
+-              update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr,
++              update_backups(sb, ext4_group_first_block_no(sb, 0),
+                              (char *)es, sizeof(struct ext4_super_block), 0);
+       }
+       return err;
diff --git a/queue-6.1/ext4-fix-deadlock-due-to-mbcache-entry-corruption.patch b/queue-6.1/ext4-fix-deadlock-due-to-mbcache-entry-corruption.patch
new file mode 100644 (file)
index 0000000..d06f2c8
--- /dev/null
@@ -0,0 +1,134 @@
+From a44e84a9b7764c72896f7241a0ec9ac7e7ef38dd Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 23 Nov 2022 20:39:50 +0100
+Subject: ext4: fix deadlock due to mbcache entry corruption
+
+From: Jan Kara <jack@suse.cz>
+
+commit a44e84a9b7764c72896f7241a0ec9ac7e7ef38dd upstream.
+
+When manipulating xattr blocks, we can deadlock infinitely looping
+inside ext4_xattr_block_set() where we constantly keep finding xattr
+block for reuse in mbcache but we are unable to reuse it because its
+reference count is too big. This happens because cache entry for the
+xattr block is marked as reusable (e_reusable set) although its
+reference count is too big. When this inconsistency happens, this
+inconsistent state is kept indefinitely and so ext4_xattr_block_set()
+keeps retrying indefinitely.
+
+The inconsistent state is caused by non-atomic update of e_reusable bit.
+e_reusable is part of a bitfield and e_reusable update can race with
+update of e_referenced bit in the same bitfield resulting in loss of one
+of the updates. Fix the problem by using atomic bitops instead.
+
+This bug has been around for many years, but it became *much* easier
+to hit after commit 65f8b80053a1 ("ext4: fix race when reusing xattr
+blocks").
+
+Cc: stable@vger.kernel.org
+Fixes: 6048c64b2609 ("mbcache: add reusable flag to cache entries")
+Fixes: 65f8b80053a1 ("ext4: fix race when reusing xattr blocks")
+Reported-and-tested-by: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
+Reported-by: Thilo Fromm <t-lo@linux.microsoft.com>
+Link: https://lore.kernel.org/r/c77bf00f-4618-7149-56f1-b8d1664b9d07@linux.microsoft.com/
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Link: https://lore.kernel.org/r/20221123193950.16758-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c         |    4 ++--
+ fs/mbcache.c            |   14 ++++++++------
+ include/linux/mbcache.h |    9 +++++++--
+ 3 files changed, 17 insertions(+), 10 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1281,7 +1281,7 @@ retry_ref:
+                               ce = mb_cache_entry_get(ea_block_cache, hash,
+                                                       bh->b_blocknr);
+                               if (ce) {
+-                                      ce->e_reusable = 1;
++                                      set_bit(MBE_REUSABLE_B, &ce->e_flags);
+                                       mb_cache_entry_put(ea_block_cache, ce);
+                               }
+                       }
+@@ -2042,7 +2042,7 @@ inserted:
+                               }
+                               BHDR(new_bh)->h_refcount = cpu_to_le32(ref);
+                               if (ref == EXT4_XATTR_REFCOUNT_MAX)
+-                                      ce->e_reusable = 0;
++                                      clear_bit(MBE_REUSABLE_B, &ce->e_flags);
+                               ea_bdebug(new_bh, "reusing; refcount now=%d",
+                                         ref);
+                               ext4_xattr_block_csum_set(inode, new_bh);
+--- a/fs/mbcache.c
++++ b/fs/mbcache.c
+@@ -100,8 +100,9 @@ int mb_cache_entry_create(struct mb_cach
+       atomic_set(&entry->e_refcnt, 2);
+       entry->e_key = key;
+       entry->e_value = value;
+-      entry->e_reusable = reusable;
+-      entry->e_referenced = 0;
++      entry->e_flags = 0;
++      if (reusable)
++              set_bit(MBE_REUSABLE_B, &entry->e_flags);
+       head = mb_cache_entry_head(cache, key);
+       hlist_bl_lock(head);
+       hlist_bl_for_each_entry(dup, dup_node, head, e_hash_list) {
+@@ -165,7 +166,8 @@ static struct mb_cache_entry *__entry_fi
+       while (node) {
+               entry = hlist_bl_entry(node, struct mb_cache_entry,
+                                      e_hash_list);
+-              if (entry->e_key == key && entry->e_reusable &&
++              if (entry->e_key == key &&
++                  test_bit(MBE_REUSABLE_B, &entry->e_flags) &&
+                   atomic_inc_not_zero(&entry->e_refcnt))
+                       goto out;
+               node = node->next;
+@@ -284,7 +286,7 @@ EXPORT_SYMBOL(mb_cache_entry_delete_or_g
+ void mb_cache_entry_touch(struct mb_cache *cache,
+                         struct mb_cache_entry *entry)
+ {
+-      entry->e_referenced = 1;
++      set_bit(MBE_REFERENCED_B, &entry->e_flags);
+ }
+ EXPORT_SYMBOL(mb_cache_entry_touch);
+@@ -309,9 +311,9 @@ static unsigned long mb_cache_shrink(str
+               entry = list_first_entry(&cache->c_list,
+                                        struct mb_cache_entry, e_list);
+               /* Drop initial hash reference if there is no user */
+-              if (entry->e_referenced ||
++              if (test_bit(MBE_REFERENCED_B, &entry->e_flags) ||
+                   atomic_cmpxchg(&entry->e_refcnt, 1, 0) != 1) {
+-                      entry->e_referenced = 0;
++                      clear_bit(MBE_REFERENCED_B, &entry->e_flags);
+                       list_move_tail(&entry->e_list, &cache->c_list);
+                       continue;
+               }
+--- a/include/linux/mbcache.h
++++ b/include/linux/mbcache.h
+@@ -10,6 +10,12 @@
+ struct mb_cache;
++/* Cache entry flags */
++enum {
++      MBE_REFERENCED_B = 0,
++      MBE_REUSABLE_B
++};
++
+ struct mb_cache_entry {
+       /* List of entries in cache - protected by cache->c_list_lock */
+       struct list_head        e_list;
+@@ -26,8 +32,7 @@ struct mb_cache_entry {
+       atomic_t                e_refcnt;
+       /* Key in hash - stable during lifetime of the entry */
+       u32                     e_key;
+-      u32                     e_referenced:1;
+-      u32                     e_reusable:1;
++      unsigned long           e_flags;
+       /* User provided value - stable during lifetime of the entry */
+       u64                     e_value;
+ };
diff --git a/queue-6.1/ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-for-bigalloc-inline.patch b/queue-6.1/ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-for-bigalloc-inline.patch
new file mode 100644 (file)
index 0000000..0ead59c
--- /dev/null
@@ -0,0 +1,57 @@
+From 131294c35ed6f777bd4e79d42af13b5c41bf2775 Mon Sep 17 00:00:00 2001
+From: Eric Whitney <enwlinux@gmail.com>
+Date: Thu, 17 Nov 2022 10:22:07 -0500
+Subject: ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline
+
+From: Eric Whitney <enwlinux@gmail.com>
+
+commit 131294c35ed6f777bd4e79d42af13b5c41bf2775 upstream.
+
+When converting files with inline data to extents, delayed allocations
+made on a file system created with both the bigalloc and inline options
+can result in invalid extent status cache content, incorrect reserved
+cluster counts, kernel memory leaks, and potential kernel panics.
+
+With bigalloc, the code that determines whether a block must be
+delayed allocated searches the extent tree to see if that block maps
+to a previously allocated cluster.  If not, the block is delayed
+allocated, and otherwise, it isn't.  However, if the inline option is
+also used, and if the file containing the block is marked as able to
+store data inline, there isn't a valid extent tree associated with
+the file.  The current code in ext4_clu_mapped() calls
+ext4_find_extent() to search the non-existent tree for a previously
+allocated cluster anyway, which typically finds nothing, as desired.
+However, a side effect of the search can be to cache invalid content
+from the non-existent tree (garbage) in the extent status tree,
+including bogus entries in the pending reservation tree.
+
+To fix this, avoid searching the extent tree when allocating blocks
+for bigalloc + inline files that are being converted from inline to
+extent mapped.
+
+Signed-off-by: Eric Whitney <enwlinux@gmail.com>
+Link: https://lore.kernel.org/r/20221117152207.2424-1-enwlinux@gmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5799,6 +5799,14 @@ int ext4_clu_mapped(struct inode *inode,
+       struct ext4_extent *extent;
+       ext4_lblk_t first_lblk, first_lclu, last_lclu;
++      /*
++       * if data can be stored inline, the logical cluster isn't
++       * mapped - no physical clusters have been allocated, and the
++       * file has no extents
++       */
++      if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
++              return 0;
++
+       /* search for the extent closest to the first block in the cluster */
+       path = ext4_find_extent(inode, EXT4_C2B(sbi, lclu), NULL, 0);
+       if (IS_ERR(path)) {
diff --git a/queue-6.1/ext4-fix-error-code-return-to-user-space-in-ext4_get_branch.patch b/queue-6.1/ext4-fix-error-code-return-to-user-space-in-ext4_get_branch.patch
new file mode 100644 (file)
index 0000000..7edcef0
--- /dev/null
@@ -0,0 +1,51 @@
+From 26d75a16af285a70863ba6a81f85d81e7e65da50 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lu=C3=ADs=20Henriques?= <lhenriques@suse.de>
+Date: Wed, 9 Nov 2022 18:14:45 +0000
+Subject: ext4: fix error code return to user-space in ext4_get_branch()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Luís Henriques <lhenriques@suse.de>
+
+commit 26d75a16af285a70863ba6a81f85d81e7e65da50 upstream.
+
+If a block is out of range in ext4_get_branch(), -ENOMEM will be returned
+to user-space.  Obviously, this error code isn't really useful.  This
+patch fixes it by making sure the right error code (-EFSCORRUPTED) is
+propagated to user-space.  EUCLEAN is more informative than ENOMEM.
+
+Signed-off-by: Luís Henriques <lhenriques@suse.de>
+Link: https://lore.kernel.org/r/20221109181445.17843-1-lhenriques@suse.de
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/indirect.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/indirect.c
++++ b/fs/ext4/indirect.c
+@@ -148,6 +148,7 @@ static Indirect *ext4_get_branch(struct
+       struct super_block *sb = inode->i_sb;
+       Indirect *p = chain;
+       struct buffer_head *bh;
++      unsigned int key;
+       int ret = -EIO;
+       *err = 0;
+@@ -156,7 +157,13 @@ static Indirect *ext4_get_branch(struct
+       if (!p->key)
+               goto no_block;
+       while (--depth) {
+-              bh = sb_getblk(sb, le32_to_cpu(p->key));
++              key = le32_to_cpu(p->key);
++              if (key > ext4_blocks_count(EXT4_SB(sb)->s_es)) {
++                      /* the block was out of range */
++                      ret = -EFSCORRUPTED;
++                      goto failure;
++              }
++              bh = sb_getblk(sb, key);
+               if (unlikely(!bh)) {
+                       ret = -ENOMEM;
+                       goto failure;
diff --git a/queue-6.1/ext4-fix-inode-leak-in-ext4_xattr_inode_create-on-an-error-path.patch b/queue-6.1/ext4-fix-inode-leak-in-ext4_xattr_inode_create-on-an-error-path.patch
new file mode 100644 (file)
index 0000000..7110906
--- /dev/null
@@ -0,0 +1,53 @@
+From e4db04f7d3dbbe16680e0ded27ea2a65b10f766a Mon Sep 17 00:00:00 2001
+From: Ye Bin <yebin10@huawei.com>
+Date: Thu, 8 Dec 2022 10:32:33 +0800
+Subject: ext4: fix inode leak in ext4_xattr_inode_create() on an error path
+
+From: Ye Bin <yebin10@huawei.com>
+
+commit e4db04f7d3dbbe16680e0ded27ea2a65b10f766a upstream.
+
+There is issue as follows when do setxattr with inject fault:
+
+[localhost]# fsck.ext4  -fn  /dev/sda
+e2fsck 1.46.6-rc1 (12-Sep-2022)
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Unattached zero-length inode 15.  Clear? no
+
+Unattached inode 15
+Connect to /lost+found? no
+
+Pass 5: Checking group summary information
+
+/dev/sda: ********** WARNING: Filesystem still has errors **********
+
+/dev/sda: 15/655360 files (0.0% non-contiguous), 66755/2621440 blocks
+
+This occurs in 'ext4_xattr_inode_create()'. If 'ext4_mark_inode_dirty()'
+fails, dropping i_nlink of the inode is needed. Or will lead to inode leak.
+
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20221208023233.1231330-5-yebin@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1441,6 +1441,9 @@ static struct inode *ext4_xattr_inode_cr
+               if (!err)
+                       err = ext4_inode_attach_jinode(ea_inode);
+               if (err) {
++                      if (ext4_xattr_inode_dec_ref(handle, ea_inode))
++                              ext4_warning_inode(ea_inode,
++                                      "cleanup dec ref error %d", err);
+                       iput(ea_inode);
+                       return ERR_PTR(err);
+               }
diff --git a/queue-6.1/ext4-fix-kernel-bug-in-ext4_write_inline_data_end.patch b/queue-6.1/ext4-fix-kernel-bug-in-ext4_write_inline_data_end.patch
new file mode 100644 (file)
index 0000000..6255341
--- /dev/null
@@ -0,0 +1,107 @@
+From 5c099c4fdc438014d5893629e70a8ba934433ee8 Mon Sep 17 00:00:00 2001
+From: Ye Bin <yebin10@huawei.com>
+Date: Tue, 6 Dec 2022 22:41:34 +0800
+Subject: ext4: fix kernel BUG in 'ext4_write_inline_data_end()'
+
+From: Ye Bin <yebin10@huawei.com>
+
+commit 5c099c4fdc438014d5893629e70a8ba934433ee8 upstream.
+
+Syzbot report follow issue:
+------------[ cut here ]------------
+kernel BUG at fs/ext4/inline.c:227!
+invalid opcode: 0000 [#1] PREEMPT SMP KASAN
+CPU: 1 PID: 3629 Comm: syz-executor212 Not tainted 6.1.0-rc5-syzkaller-00018-g59d0d52c30d4 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
+RIP: 0010:ext4_write_inline_data+0x344/0x3e0 fs/ext4/inline.c:227
+RSP: 0018:ffffc90003b3f368 EFLAGS: 00010293
+RAX: 0000000000000000 RBX: ffff8880704e16c0 RCX: 0000000000000000
+RDX: ffff888021763a80 RSI: ffffffff821e31a4 RDI: 0000000000000006
+RBP: 000000000006818e R08: 0000000000000006 R09: 0000000000068199
+R10: 0000000000000079 R11: 0000000000000000 R12: 000000000000000b
+R13: 0000000000068199 R14: ffffc90003b3f408 R15: ffff8880704e1c82
+FS:  000055555723e3c0(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007fffe8ac9080 CR3: 0000000079f81000 CR4: 0000000000350ee0
+Call Trace:
+ <TASK>
+ ext4_write_inline_data_end+0x2a3/0x12f0 fs/ext4/inline.c:768
+ ext4_write_end+0x242/0xdd0 fs/ext4/inode.c:1313
+ ext4_da_write_end+0x3ed/0xa30 fs/ext4/inode.c:3063
+ generic_perform_write+0x316/0x570 mm/filemap.c:3764
+ ext4_buffered_write_iter+0x15b/0x460 fs/ext4/file.c:285
+ ext4_file_write_iter+0x8bc/0x16e0 fs/ext4/file.c:700
+ call_write_iter include/linux/fs.h:2191 [inline]
+ do_iter_readv_writev+0x20b/0x3b0 fs/read_write.c:735
+ do_iter_write+0x182/0x700 fs/read_write.c:861
+ vfs_iter_write+0x74/0xa0 fs/read_write.c:902
+ iter_file_splice_write+0x745/0xc90 fs/splice.c:686
+ do_splice_from fs/splice.c:764 [inline]
+ direct_splice_actor+0x114/0x180 fs/splice.c:931
+ splice_direct_to_actor+0x335/0x8a0 fs/splice.c:886
+ do_splice_direct+0x1ab/0x280 fs/splice.c:974
+ do_sendfile+0xb19/0x1270 fs/read_write.c:1255
+ __do_sys_sendfile64 fs/read_write.c:1323 [inline]
+ __se_sys_sendfile64 fs/read_write.c:1309 [inline]
+ __x64_sys_sendfile64+0x1d0/0x210 fs/read_write.c:1309
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+---[ end trace 0000000000000000 ]---
+
+Above issue may happens as follows:
+ext4_da_write_begin
+  ext4_da_write_inline_data_begin
+    ext4_da_convert_inline_data_to_extent
+      ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
+ext4_da_write_end
+
+ext4_run_li_request
+  ext4_mb_prefetch
+    ext4_read_block_bitmap_nowait
+      ext4_validate_block_bitmap
+        ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_BBITMAP_CORRUPT)
+        percpu_counter_sub(&sbi->s_freeclusters_counter,grp->bb_free);
+         -> sbi->s_freeclusters_counter become zero
+ext4_da_write_begin
+  if (ext4_nonda_switch(inode->i_sb)) -> As freeclusters_counter is zero will return true
+    *fsdata = (void *)FALL_BACK_TO_NONDELALLOC;
+    ext4_write_begin
+ext4_da_write_end
+  if (write_mode == FALL_BACK_TO_NONDELALLOC)
+    ext4_write_end
+      if (inline_data)
+        ext4_write_inline_data_end
+         ext4_write_inline_data
+           BUG_ON(pos + len > EXT4_I(inode)->i_inline_size);
+           -> As inode is already convert to extent, so 'pos + len' > inline_size
+          -> then trigger BUG.
+
+To solve this issue, instead of checking ext4_has_inline_data() which
+is only cleared after data has been written back, check the
+EXT4_STATE_MAY_INLINE_DATA flag in ext4_write_end().
+
+Fixes: f19d5870cbf7 ("ext4: add normal write support for inline data")
+Reported-by: syzbot+4faa160fa96bfba639f8@syzkaller.appspotmail.com
+Reported-by: Jun Nie <jun.nie@linaro.org>
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Link: https://lore.kernel.org/r/20221206144134.1919987-1-yebin@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/inode.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1315,7 +1315,8 @@ static int ext4_write_end(struct file *f
+       trace_ext4_write_end(inode, pos, len, copied);
+-      if (ext4_has_inline_data(inode))
++      if (ext4_has_inline_data(inode) &&
++          ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
+               return ext4_write_inline_data_end(inode, pos, len, copied, page);
+       copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
diff --git a/queue-6.1/ext4-init-quota-for-old.inode-in-ext4_rename.patch b/queue-6.1/ext4-init-quota-for-old.inode-in-ext4_rename.patch
new file mode 100644 (file)
index 0000000..921ed3d
--- /dev/null
@@ -0,0 +1,77 @@
+From fae381a3d79bb94aa2eb752170d47458d778b797 Mon Sep 17 00:00:00 2001
+From: Ye Bin <yebin10@huawei.com>
+Date: Mon, 7 Nov 2022 09:53:35 +0800
+Subject: ext4: init quota for 'old.inode' in 'ext4_rename'
+
+From: Ye Bin <yebin10@huawei.com>
+
+commit fae381a3d79bb94aa2eb752170d47458d778b797 upstream.
+
+Syzbot found the following issue:
+ext4_parse_param: s_want_extra_isize=128
+ext4_inode_info_init: s_want_extra_isize=32
+ext4_rename: old.inode=ffff88823869a2c8 old.dir=ffff888238699828 new.inode=ffff88823869d7e8 new.dir=ffff888238699828
+__ext4_mark_inode_dirty: inode=ffff888238699828 ea_isize=32 want_ea_size=128
+__ext4_mark_inode_dirty: inode=ffff88823869a2c8 ea_isize=32 want_ea_size=128
+ext4_xattr_block_set: inode=ffff88823869a2c8
+------------[ cut here ]------------
+WARNING: CPU: 13 PID: 2234 at fs/ext4/xattr.c:2070 ext4_xattr_block_set.cold+0x22/0x980
+Modules linked in:
+RIP: 0010:ext4_xattr_block_set.cold+0x22/0x980
+RSP: 0018:ffff888227d3f3b0 EFLAGS: 00010202
+RAX: 0000000000000001 RBX: ffff88823007a000 RCX: 0000000000000000
+RDX: 0000000000000a03 RSI: 0000000000000040 RDI: ffff888230078178
+RBP: 0000000000000000 R08: 000000000000002c R09: ffffed1075c7df8e
+R10: ffff8883ae3efc6b R11: ffffed1075c7df8d R12: 0000000000000000
+R13: ffff88823869a2c8 R14: ffff8881012e0460 R15: dffffc0000000000
+FS:  00007f350ac1f740(0000) GS:ffff8883ae200000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f350a6ed6a0 CR3: 0000000237456000 CR4: 00000000000006e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ ? ext4_xattr_set_entry+0x3b7/0x2320
+ ? ext4_xattr_block_set+0x0/0x2020
+ ? ext4_xattr_set_entry+0x0/0x2320
+ ? ext4_xattr_check_entries+0x77/0x310
+ ? ext4_xattr_ibody_set+0x23b/0x340
+ ext4_xattr_move_to_block+0x594/0x720
+ ext4_expand_extra_isize_ea+0x59a/0x10f0
+ __ext4_expand_extra_isize+0x278/0x3f0
+ __ext4_mark_inode_dirty.cold+0x347/0x410
+ ext4_rename+0xed3/0x174f
+ vfs_rename+0x13a7/0x2510
+ do_renameat2+0x55d/0x920
+ __x64_sys_rename+0x7d/0xb0
+ do_syscall_64+0x3b/0xa0
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+As 'ext4_rename' will modify 'old.inode' ctime and mark inode dirty,
+which may trigger expand 'extra_isize' and allocate block. If inode
+didn't init quota will lead to warning.  To solve above issue, init
+'old.inode' firstly in 'ext4_rename'.
+
+Reported-by: syzbot+98346927678ac3059c77@syzkaller.appspotmail.com
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20221107015335.2524319-1-yebin@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/namei.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -3798,6 +3798,9 @@ static int ext4_rename(struct user_names
+       retval = dquot_initialize(old.dir);
+       if (retval)
+               return retval;
++      retval = dquot_initialize(old.inode);
++      if (retval)
++              return retval;
+       retval = dquot_initialize(new.dir);
+       if (retval)
+               return retval;
diff --git a/queue-6.1/ext4-initialize-quota-before-expanding-inode-in-setproject-ioctl.patch b/queue-6.1/ext4-initialize-quota-before-expanding-inode-in-setproject-ioctl.patch
new file mode 100644 (file)
index 0000000..912b196
--- /dev/null
@@ -0,0 +1,47 @@
+From 1485f726c6dec1a1f85438f2962feaa3d585526f Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 7 Dec 2022 12:59:27 +0100
+Subject: ext4: initialize quota before expanding inode in setproject ioctl
+
+From: Jan Kara <jack@suse.cz>
+
+commit 1485f726c6dec1a1f85438f2962feaa3d585526f upstream.
+
+Make sure we initialize quotas before possibly expanding inode space
+(and thus maybe needing to allocate external xattr block) in
+ext4_ioctl_setproject(). This prevents not accounting the necessary
+block allocation.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Cc: stable@kernel.org
+Link: https://lore.kernel.org/r/20221207115937.26601-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ioctl.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -732,6 +732,10 @@ static int ext4_ioctl_setproject(struct
+       if (ext4_is_quota_file(inode))
+               return err;
++      err = dquot_initialize(inode);
++      if (err)
++              return err;
++
+       err = ext4_get_inode_loc(inode, &iloc);
+       if (err)
+               return err;
+@@ -747,10 +751,6 @@ static int ext4_ioctl_setproject(struct
+               brelse(iloc.bh);
+       }
+-      err = dquot_initialize(inode);
+-      if (err)
+-              return err;
+-
+       handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
+               EXT4_QUOTA_INIT_BLOCKS(sb) +
+               EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
index 8415f2af442dcd8a512e210346d1bd5b2409dee9..16b9ffdab7aafa4a51dade8b4d88a3fdb7ae9a0e 100644 (file)
@@ -180,3 +180,18 @@ 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
 ext4-fix-uninititialized-value-in-ext4_evict_inode.patch
+ext4-init-quota-for-old.inode-in-ext4_rename.patch
+ext4-don-t-fail-getfsuuid-when-the-caller-provides-a-long-buffer.patch
+ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-for-bigalloc-inline.patch
+ext4-fix-corruption-when-online-resizing-a-1k-bigalloc-fs.patch
+ext4-fix-error-code-return-to-user-space-in-ext4_get_branch.patch
+ext4-fix-bad-checksum-after-online-resize.patch
+ext4-dont-return-einval-from-getfsuuid-when-reporting-uuid-length.patch
+ext4-fix-corrupt-backup-group-descriptors-after-online-resize.patch
+ext4-avoid-bug_on-when-creating-xattrs.patch
+ext4-fix-deadlock-due-to-mbcache-entry-corruption.patch
+ext4-fix-kernel-bug-in-ext4_write_inline_data_end.patch
+ext4-fix-inode-leak-in-ext4_xattr_inode_create-on-an-error-path.patch
+ext4-initialize-quota-before-expanding-inode-in-setproject-ioctl.patch
+ext4-avoid-unaccounted-block-allocation-when-expanding-inode.patch
+ext4-allocate-extended-attribute-value-in-vmalloc-area.patch