]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 24 Nov 2023 14:09:12 +0000 (14:09 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 24 Nov 2023 14:09:12 +0000 (14:09 +0000)
added patches:
drm-amd-pm-handle-non-terminated-overdrive-commands.patch
ext4-add-missed-brelse-in-update_backups.patch
ext4-apply-umask-if-acl-support-is-disabled.patch
ext4-correct-offset-of-gdb-backup-in-non-meta_bg-group-to-update_backups.patch
ext4-correct-return-value-of-ext4_convert_meta_bg.patch
ext4-correct-the-start-block-of-counting-reserved-clusters.patch
ext4-mark-buffer-new-if-it-is-unwritten-to-avoid-stale-data-exposure.patch
ext4-properly-sync-file-size-update-after-o_sync-direct-io.patch
ext4-remove-gdb-backup-copy-for-meta-bg-in-setup_new_flex_group_blocks.patch
revert-net-r8169-disable-multicast-filter-for-rtl8168h-and-rtl8107e.patch

12 files changed:
queue-6.1/drm-amd-pm-handle-non-terminated-overdrive-commands.patch [new file with mode: 0644]
queue-6.1/ext4-add-missed-brelse-in-update_backups.patch [new file with mode: 0644]
queue-6.1/ext4-apply-umask-if-acl-support-is-disabled.patch [new file with mode: 0644]
queue-6.1/ext4-correct-offset-of-gdb-backup-in-non-meta_bg-group-to-update_backups.patch [new file with mode: 0644]
queue-6.1/ext4-correct-return-value-of-ext4_convert_meta_bg.patch [new file with mode: 0644]
queue-6.1/ext4-correct-the-start-block-of-counting-reserved-clusters.patch [new file with mode: 0644]
queue-6.1/ext4-mark-buffer-new-if-it-is-unwritten-to-avoid-stale-data-exposure.patch [new file with mode: 0644]
queue-6.1/ext4-properly-sync-file-size-update-after-o_sync-direct-io.patch [new file with mode: 0644]
queue-6.1/ext4-remove-gdb-backup-copy-for-meta-bg-in-setup_new_flex_group_blocks.patch [new file with mode: 0644]
queue-6.1/media-qcom-camss-fix-set-csi2_rx_cfg1_vc_mode-when-vc-is-greater-than-3.patch [deleted file]
queue-6.1/revert-net-r8169-disable-multicast-filter-for-rtl8168h-and-rtl8107e.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/drm-amd-pm-handle-non-terminated-overdrive-commands.patch b/queue-6.1/drm-amd-pm-handle-non-terminated-overdrive-commands.patch
new file mode 100644 (file)
index 0000000..0d815f2
--- /dev/null
@@ -0,0 +1,55 @@
+From 08e9ebc75b5bcfec9d226f9e16bab2ab7b25a39a Mon Sep 17 00:00:00 2001
+From: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
+Date: Tue, 17 Oct 2023 16:01:35 +0200
+Subject: drm/amd/pm: Handle non-terminated overdrive commands.
+
+From: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
+
+commit 08e9ebc75b5bcfec9d226f9e16bab2ab7b25a39a upstream.
+
+The incoming strings might not be terminated by a newline
+or a 0.
+
+(found while testing a program that just wrote the string
+ itself, causing a crash)
+
+Cc: stable@vger.kernel.org
+Fixes: e3933f26b657 ("drm/amd/pp: Add edit/commit/show OD clock/voltage support in sysfs")
+Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/amdgpu_pm.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
++++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+@@ -758,7 +758,7 @@ static ssize_t amdgpu_set_pp_od_clk_volt
+       if (adev->in_suspend && !adev->in_runpm)
+               return -EPERM;
+-      if (count > 127)
++      if (count > 127 || count == 0)
+               return -EINVAL;
+       if (*buf == 's')
+@@ -778,7 +778,8 @@ static ssize_t amdgpu_set_pp_od_clk_volt
+       else
+               return -EINVAL;
+-      memcpy(buf_cpy, buf, count+1);
++      memcpy(buf_cpy, buf, count);
++      buf_cpy[count] = 0;
+       tmp_str = buf_cpy;
+@@ -795,6 +796,9 @@ static ssize_t amdgpu_set_pp_od_clk_volt
+                       return -EINVAL;
+               parameter_size++;
++              if (!tmp_str)
++                      break;
++
+               while (isspace(*tmp_str))
+                       tmp_str++;
+       }
diff --git a/queue-6.1/ext4-add-missed-brelse-in-update_backups.patch b/queue-6.1/ext4-add-missed-brelse-in-update_backups.patch
new file mode 100644 (file)
index 0000000..ee82289
--- /dev/null
@@ -0,0 +1,35 @@
+From 9adac8b01f4be28acd5838aade42b8daa4f0b642 Mon Sep 17 00:00:00 2001
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+Date: Sun, 27 Aug 2023 01:47:01 +0800
+Subject: ext4: add missed brelse in update_backups
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+commit 9adac8b01f4be28acd5838aade42b8daa4f0b642 upstream.
+
+add missed brelse in update_backups
+
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Theodore Ts'o <tytso@mit.edu>
+Link: https://lore.kernel.org/r/20230826174712.4059355-3-shikemeng@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/resize.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1186,8 +1186,10 @@ static void update_backups(struct super_
+                          ext4_group_first_block_no(sb, group));
+               BUFFER_TRACE(bh, "get_write_access");
+               if ((err = ext4_journal_get_write_access(handle, sb, bh,
+-                                                       EXT4_JTR_NONE)))
++                                                       EXT4_JTR_NONE))) {
++                      brelse(bh);
+                       break;
++              }
+               lock_buffer(bh);
+               memcpy(bh->b_data, data, size);
+               if (rest)
diff --git a/queue-6.1/ext4-apply-umask-if-acl-support-is-disabled.patch b/queue-6.1/ext4-apply-umask-if-acl-support-is-disabled.patch
new file mode 100644 (file)
index 0000000..2fdda0c
--- /dev/null
@@ -0,0 +1,45 @@
+From 484fd6c1de13b336806a967908a927cc0356e312 Mon Sep 17 00:00:00 2001
+From: Max Kellermann <max.kellermann@ionos.com>
+Date: Tue, 19 Sep 2023 10:18:23 +0200
+Subject: ext4: apply umask if ACL support is disabled
+
+From: Max Kellermann <max.kellermann@ionos.com>
+
+commit 484fd6c1de13b336806a967908a927cc0356e312 upstream.
+
+The function ext4_init_acl() calls posix_acl_create() which is
+responsible for applying the umask.  But without
+CONFIG_EXT4_FS_POSIX_ACL, ext4_init_acl() is an empty inline function,
+and nobody applies the umask.
+
+This fixes a bug which causes the umask to be ignored with O_TMPFILE
+on ext4:
+
+ https://github.com/MusicPlayerDaemon/MPD/issues/558
+ https://bugs.gentoo.org/show_bug.cgi?id=686142#c3
+ https://bugzilla.kernel.org/show_bug.cgi?id=203625
+
+Reviewed-by: "J. Bruce Fields" <bfields@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
+Link: https://lore.kernel.org/r/20230919081824.1096619-1-max.kellermann@ionos.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/acl.h |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/fs/ext4/acl.h
++++ b/fs/ext4/acl.h
+@@ -68,6 +68,11 @@ extern int ext4_init_acl(handle_t *, str
+ static inline int
+ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
+ {
++      /* usually, the umask is applied by posix_acl_create(), but if
++         ext4 ACL support is disabled at compile time, we need to do
++         it here, because posix_acl_create() will never be called */
++      inode->i_mode &= ~current_umask();
++
+       return 0;
+ }
+ #endif  /* CONFIG_EXT4_FS_POSIX_ACL */
diff --git a/queue-6.1/ext4-correct-offset-of-gdb-backup-in-non-meta_bg-group-to-update_backups.patch b/queue-6.1/ext4-correct-offset-of-gdb-backup-in-non-meta_bg-group-to-update_backups.patch
new file mode 100644 (file)
index 0000000..7aeed9f
--- /dev/null
@@ -0,0 +1,57 @@
+From 31f13421c004a420c0e9d288859c9ea9259ea0cc Mon Sep 17 00:00:00 2001
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+Date: Sun, 27 Aug 2023 01:47:00 +0800
+Subject: ext4: correct offset of gdb backup in non meta_bg group to update_backups
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+commit 31f13421c004a420c0e9d288859c9ea9259ea0cc upstream.
+
+Commit 0aeaa2559d6d5 ("ext4: fix corruption when online resizing a 1K
+bigalloc fs") found that primary superblock's offset in its group is
+not equal to offset of backup superblock in its group when block size
+is 1K and bigalloc is enabled. As group descriptor blocks are right
+after superblock, we can't pass block number of gdb to update_backups
+for the same reason.
+
+The root casue of the issue above is that leading 1K padding block is
+count as data block offset for primary block while backup block has no
+padding block offset in its group.
+
+Remove padding data block count to fix the issue for gdb backups.
+
+For meta_bg case, update_backups treat blk_off as block number, do no
+conversion in this case.
+
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Theodore Ts'o <tytso@mit.edu>
+Link: https://lore.kernel.org/r/20230826174712.4059355-2-shikemeng@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/resize.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1602,6 +1602,8 @@ exit_journal:
+               int gdb_num_end = ((group + flex_gd->count - 1) /
+                                  EXT4_DESC_PER_BLOCK(sb));
+               int meta_bg = ext4_has_feature_meta_bg(sb);
++              sector_t padding_blocks = meta_bg ? 0 : sbi->s_sbh->b_blocknr -
++                                       ext4_group_first_block_no(sb, 0);
+               sector_t old_gdb = 0;
+               update_backups(sb, ext4_group_first_block_no(sb, 0),
+@@ -1613,8 +1615,8 @@ exit_journal:
+                                                    gdb_num);
+                       if (old_gdb == gdb_bh->b_blocknr)
+                               continue;
+-                      update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data,
+-                                     gdb_bh->b_size, meta_bg);
++                      update_backups(sb, gdb_bh->b_blocknr - padding_blocks,
++                                     gdb_bh->b_data, gdb_bh->b_size, meta_bg);
+                       old_gdb = gdb_bh->b_blocknr;
+               }
+       }
diff --git a/queue-6.1/ext4-correct-return-value-of-ext4_convert_meta_bg.patch b/queue-6.1/ext4-correct-return-value-of-ext4_convert_meta_bg.patch
new file mode 100644 (file)
index 0000000..75313df
--- /dev/null
@@ -0,0 +1,33 @@
+From 48f1551592c54f7d8e2befc72a99ff4e47f7dca0 Mon Sep 17 00:00:00 2001
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+Date: Sun, 27 Aug 2023 01:47:02 +0800
+Subject: ext4: correct return value of ext4_convert_meta_bg
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+commit 48f1551592c54f7d8e2befc72a99ff4e47f7dca0 upstream.
+
+Avoid to ignore error in "err".
+
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Link: https://lore.kernel.org/r/20230826174712.4059355-4-shikemeng@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/resize.c |    4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1985,9 +1985,7 @@ static int ext4_convert_meta_bg(struct s
+ errout:
+       ret = ext4_journal_stop(handle);
+-      if (!err)
+-              err = ret;
+-      return ret;
++      return err ? err : ret;
+ invalid_resize_inode:
+       ext4_error(sb, "corrupted/inconsistent resize inode");
diff --git a/queue-6.1/ext4-correct-the-start-block-of-counting-reserved-clusters.patch b/queue-6.1/ext4-correct-the-start-block-of-counting-reserved-clusters.patch
new file mode 100644 (file)
index 0000000..6df6837
--- /dev/null
@@ -0,0 +1,51 @@
+From 40ea98396a3659062267d1fe5f99af4f7e4f05e3 Mon Sep 17 00:00:00 2001
+From: Zhang Yi <yi.zhang@huawei.com>
+Date: Thu, 24 Aug 2023 17:26:04 +0800
+Subject: ext4: correct the start block of counting reserved clusters
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+commit 40ea98396a3659062267d1fe5f99af4f7e4f05e3 upstream.
+
+When big allocate feature is enabled, we need to count and update
+reserved clusters before removing a delayed only extent_status entry.
+{init|count|get}_rsvd() have already done this, but the start block
+number of this counting isn't correct in the following case.
+
+  lblk            end
+   |               |
+   v               v
+          -------------------------
+          |                       | orig_es
+          -------------------------
+                   ^              ^
+      len1 is 0    |     len2     |
+
+If the start block of the orig_es entry founded is bigger than lblk, we
+passed lblk as start block to count_rsvd(), but the length is correct,
+finally, the range to be counted is offset. This patch fix this by
+passing the start blocks to 'orig_es->lblk + len1'.
+
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Cc: stable@kernel.org
+Link: https://lore.kernel.org/r/20230824092619.1327976-2-yi.zhang@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents_status.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/extents_status.c
++++ b/fs/ext4/extents_status.c
+@@ -1365,8 +1365,8 @@ retry:
+                       }
+               }
+               if (count_reserved)
+-                      count_rsvd(inode, lblk, orig_es.es_len - len1 - len2,
+-                                 &orig_es, &rc);
++                      count_rsvd(inode, orig_es.es_lblk + len1,
++                                 orig_es.es_len - len1 - len2, &orig_es, &rc);
+               goto out_get_reserved;
+       }
diff --git a/queue-6.1/ext4-mark-buffer-new-if-it-is-unwritten-to-avoid-stale-data-exposure.patch b/queue-6.1/ext4-mark-buffer-new-if-it-is-unwritten-to-avoid-stale-data-exposure.patch
new file mode 100644 (file)
index 0000000..a2b46f7
--- /dev/null
@@ -0,0 +1,140 @@
+From 2cd8bdb5efc1e0d5b11a4b7ba6b922fd2736a87f Mon Sep 17 00:00:00 2001
+From: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Date: Mon, 18 Sep 2023 16:15:50 +0530
+Subject: ext4: mark buffer new if it is unwritten to avoid stale data exposure
+
+From: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+
+commit 2cd8bdb5efc1e0d5b11a4b7ba6b922fd2736a87f upstream.
+
+** Short Version **
+
+In ext4 with dioread_nolock, we could have a scenario where the bh returned by
+get_blocks (ext4_get_block_unwritten()) in __block_write_begin_int() has
+UNWRITTEN and MAPPED flag set. Since such a bh does not have NEW flag set we
+never zero out the range of bh that is not under write, causing whatever stale
+data is present in the folio at that time to be written out to disk. To fix this
+mark the buffer as new, in case it is unwritten, in ext4_get_block_unwritten().
+
+** Long Version **
+
+The issue mentioned above was resulting in two different bugs:
+
+1. On block size < page size case in ext4, generic/269 was reliably
+failing with dioread_nolock. The state of the write was as follows:
+
+  * The write was extending i_size.
+  * The last block of the file was fallocated and had an unwritten extent
+  * We were near ENOSPC and hence we were switching to non-delayed alloc
+    allocation.
+
+In this case, the back trace that triggers the bug is as follows:
+
+  ext4_da_write_begin()
+    /* switch to nodelalloc due to low space */
+    ext4_write_begin()
+      ext4_should_dioread_nolock() // true since mount flags still have delalloc
+      __block_write_begin(..., ext4_get_block_unwritten)
+        __block_write_begin_int()
+          for(each buffer head in page) {
+            /* first iteration, this is bh1 which contains i_size */
+            if (!buffer_mapped)
+              get_block() /* returns bh with only UNWRITTEN and MAPPED */
+            /* second iteration, bh2 */
+              if (!buffer_mapped)
+                get_block() /* we fail here, could be ENOSPC */
+          }
+          if (err)
+            /*
+             * this would zero out all new buffers and mark them uptodate.
+             * Since bh1 was never marked new, we skip it here which causes
+             * the bug later.
+             */
+            folio_zero_new_buffers();
+      /* ext4_wrte_begin() error handling */
+      ext4_truncate_failed_write()
+        ext4_truncate()
+          ext4_block_truncate_page()
+            __ext4_block_zero_page_range()
+              if(!buffer_uptodate())
+                ext4_read_bh_lock()
+                  ext4_read_bh() -> ... ext4_submit_bh_wbc()
+                    BUG_ON(buffer_unwritten(bh)); /* !!! */
+
+2. The second issue is stale data exposure with page size >= blocksize
+with dioread_nolock. The conditions needed for it to happen are same as
+the previous issue ie dioread_nolock around ENOSPC condition. The issue
+is also similar where in __block_write_begin_int() when we call
+ext4_get_block_unwritten() on the buffer_head and the underlying extent
+is unwritten, we get an unwritten and mapped buffer head. Since it is
+not new, we never zero out the partial range which is not under write,
+thus writing stale data to disk. This can be easily observed with the
+following reproducer:
+
+ fallocate -l 4k testfile
+ xfs_io -c "pwrite 2k 2k" testfile
+ # hexdump output will have stale data in from byte 0 to 2k in testfile
+ hexdump -C testfile
+
+NOTE: To trigger this, we need dioread_nolock enabled and write happening via
+ext4_write_begin(), which is usually used when we have -o nodealloc. Since
+dioread_nolock is disabled with nodelalloc, the only alternate way to call
+ext4_write_begin() is to ensure that delayed alloc switches to nodelalloc ie
+ext4_da_write_begin() calls ext4_write_begin(). This will usually happen when
+ext4 is almost full like the way generic/269 was triggering it in Issue 1 above.
+This might make the issue harder to hit. Hence, for reliable replication, I used
+the below patch to temporarily allow dioread_nolock with nodelalloc and then
+mount the disk with -o nodealloc,dioread_nolock. With this you can hit the stale
+data issue 100% of times:
+
+@@ -508,8 +508,8 @@ static inline int ext4_should_dioread_nolock(struct inode *inode)
+  if (ext4_should_journal_data(inode))
+    return 0;
+  /* temporary fix to prevent generic/422 test failures */
+- if (!test_opt(inode->i_sb, DELALLOC))
+-   return 0;
++ // if (!test_opt(inode->i_sb, DELALLOC))
++ //  return 0;
+  return 1;
+ }
+
+After applying this patch to mark buffer as NEW, both the above issues are
+fixed.
+
+Signed-off-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Cc: stable@kernel.org
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
+Link: https://lore.kernel.org/r/d0ed09d70a9733fbb5349c5c7b125caac186ecdf.1695033645.git.ojaswin@linux.ibm.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/inode.c |   14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -824,10 +824,22 @@ int ext4_get_block(struct inode *inode,
+ int ext4_get_block_unwritten(struct inode *inode, sector_t iblock,
+                            struct buffer_head *bh_result, int create)
+ {
++      int ret = 0;
++
+       ext4_debug("ext4_get_block_unwritten: inode %lu, create flag %d\n",
+                  inode->i_ino, create);
+-      return _ext4_get_block(inode, iblock, bh_result,
++      ret = _ext4_get_block(inode, iblock, bh_result,
+                              EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT);
++
++      /*
++       * If the buffer is marked unwritten, mark it as new to make sure it is
++       * zeroed out correctly in case of partial writes. Otherwise, there is
++       * a chance of stale data getting exposed.
++       */
++      if (ret == 0 && buffer_unwritten(bh_result))
++              set_buffer_new(bh_result);
++
++      return ret;
+ }
+ /* Maximum number of blocks we map for direct IO at once. */
diff --git a/queue-6.1/ext4-properly-sync-file-size-update-after-o_sync-direct-io.patch b/queue-6.1/ext4-properly-sync-file-size-update-after-o_sync-direct-io.patch
new file mode 100644 (file)
index 0000000..43a382c
--- /dev/null
@@ -0,0 +1,241 @@
+From 91562895f8030cb9a0470b1db49de79346a69f91 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 13 Oct 2023 14:13:50 +0200
+Subject: ext4: properly sync file size update after O_SYNC direct IO
+
+From: Jan Kara <jack@suse.cz>
+
+commit 91562895f8030cb9a0470b1db49de79346a69f91 upstream.
+
+Gao Xiang has reported that on ext4 O_SYNC direct IO does not properly
+sync file size update and thus if we crash at unfortunate moment, the
+file can have smaller size although O_SYNC IO has reported successful
+completion. The problem happens because update of on-disk inode size is
+handled in ext4_dio_write_iter() *after* iomap_dio_rw() (and thus
+dio_complete() in particular) has returned and generic_file_sync() gets
+called by dio_complete(). Fix the problem by handling on-disk inode size
+update directly in our ->end_io completion handler.
+
+References: https://lore.kernel.org/all/02d18236-26ef-09b0-90ad-030c4fe3ee20@linux.alibaba.com
+Reported-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+CC: stable@vger.kernel.org
+Fixes: 378f32bab371 ("ext4: introduce direct I/O write using iomap infrastructure")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Tested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Reviewed-by: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
+Link: https://lore.kernel.org/r/20231013121350.26872-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/file.c |  153 ++++++++++++++++++++++++---------------------------------
+ 1 file changed, 65 insertions(+), 88 deletions(-)
+
+--- a/fs/ext4/file.c
++++ b/fs/ext4/file.c
+@@ -296,80 +296,38 @@ out:
+ }
+ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
+-                                         ssize_t written, size_t count)
++                                         ssize_t count)
+ {
+       handle_t *handle;
+-      bool truncate = false;
+-      u8 blkbits = inode->i_blkbits;
+-      ext4_lblk_t written_blk, end_blk;
+-      int ret;
+-
+-      /*
+-       * Note that EXT4_I(inode)->i_disksize can get extended up to
+-       * inode->i_size while the I/O was running due to writeback of delalloc
+-       * blocks. But, the code in ext4_iomap_alloc() is careful to use
+-       * zeroed/unwritten extents if this is possible; thus we won't leave
+-       * uninitialized blocks in a file even if we didn't succeed in writing
+-       * as much as we intended.
+-       */
+-      WARN_ON_ONCE(i_size_read(inode) < EXT4_I(inode)->i_disksize);
+-      if (offset + count <= EXT4_I(inode)->i_disksize) {
+-              /*
+-               * We need to ensure that the inode is removed from the orphan
+-               * list if it has been added prematurely, due to writeback of
+-               * delalloc blocks.
+-               */
+-              if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
+-                      handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+-
+-                      if (IS_ERR(handle)) {
+-                              ext4_orphan_del(NULL, inode);
+-                              return PTR_ERR(handle);
+-                      }
+-
+-                      ext4_orphan_del(handle, inode);
+-                      ext4_journal_stop(handle);
+-              }
+-
+-              return written;
+-      }
+-
+-      if (written < 0)
+-              goto truncate;
++      lockdep_assert_held_write(&inode->i_rwsem);
+       handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+-      if (IS_ERR(handle)) {
+-              written = PTR_ERR(handle);
+-              goto truncate;
+-      }
++      if (IS_ERR(handle))
++              return PTR_ERR(handle);
+-      if (ext4_update_inode_size(inode, offset + written)) {
+-              ret = ext4_mark_inode_dirty(handle, inode);
++      if (ext4_update_inode_size(inode, offset + count)) {
++              int ret = ext4_mark_inode_dirty(handle, inode);
+               if (unlikely(ret)) {
+-                      written = ret;
+                       ext4_journal_stop(handle);
+-                      goto truncate;
++                      return ret;
+               }
+       }
+-      /*
+-       * We may need to truncate allocated but not written blocks beyond EOF.
+-       */
+-      written_blk = ALIGN(offset + written, 1 << blkbits);
+-      end_blk = ALIGN(offset + count, 1 << blkbits);
+-      if (written_blk < end_blk && ext4_can_truncate(inode))
+-              truncate = true;
+-
+-      /*
+-       * Remove the inode from the orphan list if it has been extended and
+-       * everything went OK.
+-       */
+-      if (!truncate && inode->i_nlink)
++      if (inode->i_nlink)
+               ext4_orphan_del(handle, inode);
+       ext4_journal_stop(handle);
+-      if (truncate) {
+-truncate:
++      return count;
++}
++
++/*
++ * Clean up the inode after DIO or DAX extending write has completed and the
++ * inode size has been updated using ext4_handle_inode_extension().
++ */
++static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count)
++{
++      lockdep_assert_held_write(&inode->i_rwsem);
++      if (count < 0) {
+               ext4_truncate_failed_write(inode);
+               /*
+                * If the truncate operation failed early, then the inode may
+@@ -378,9 +336,28 @@ truncate:
+                */
+               if (inode->i_nlink)
+                       ext4_orphan_del(NULL, inode);
++              return;
+       }
++      /*
++       * If i_disksize got extended due to writeback of delalloc blocks while
++       * the DIO was running we could fail to cleanup the orphan list in
++       * ext4_handle_inode_extension(). Do it now.
++       */
++      if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
++              handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
+-      return written;
++              if (IS_ERR(handle)) {
++                      /*
++                       * The write has successfully completed. Not much to
++                       * do with the error here so just cleanup the orphan
++                       * list and hope for the best.
++                       */
++                      ext4_orphan_del(NULL, inode);
++                      return;
++              }
++              ext4_orphan_del(handle, inode);
++              ext4_journal_stop(handle);
++      }
+ }
+ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
+@@ -389,31 +366,22 @@ static int ext4_dio_write_end_io(struct
+       loff_t pos = iocb->ki_pos;
+       struct inode *inode = file_inode(iocb->ki_filp);
++      if (!error && size && flags & IOMAP_DIO_UNWRITTEN)
++              error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
+       if (error)
+               return error;
+-
+-      if (size && flags & IOMAP_DIO_UNWRITTEN) {
+-              error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
+-              if (error < 0)
+-                      return error;
+-      }
+       /*
+-       * If we are extending the file, we have to update i_size here before
+-       * page cache gets invalidated in iomap_dio_rw(). Otherwise racing
+-       * buffered reads could zero out too much from page cache pages. Update
+-       * of on-disk size will happen later in ext4_dio_write_iter() where
+-       * we have enough information to also perform orphan list handling etc.
+-       * Note that we perform all extending writes synchronously under
+-       * i_rwsem held exclusively so i_size update is safe here in that case.
+-       * If the write was not extending, we cannot see pos > i_size here
+-       * because operations reducing i_size like truncate wait for all
+-       * outstanding DIO before updating i_size.
++       * Note that EXT4_I(inode)->i_disksize can get extended up to
++       * inode->i_size while the I/O was running due to writeback of delalloc
++       * blocks. But the code in ext4_iomap_alloc() is careful to use
++       * zeroed/unwritten extents if this is possible; thus we won't leave
++       * uninitialized blocks in a file even if we didn't succeed in writing
++       * as much as we intended.
+        */
+-      pos += size;
+-      if (pos > i_size_read(inode))
+-              i_size_write(inode, pos);
+-
+-      return 0;
++      WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize));
++      if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize))
++              return size;
++      return ext4_handle_inode_extension(inode, pos, size);
+ }
+ static const struct iomap_dio_ops ext4_dio_write_ops = {
+@@ -589,9 +557,16 @@ static ssize_t ext4_dio_write_iter(struc
+                          NULL, 0);
+       if (ret == -ENOTBLK)
+               ret = 0;
+-
+-      if (extend)
+-              ret = ext4_handle_inode_extension(inode, offset, ret, count);
++      if (extend) {
++              /*
++               * We always perform extending DIO write synchronously so by
++               * now the IO is completed and ext4_handle_inode_extension()
++               * was called. Cleanup the inode in case of error or race with
++               * writeback of delalloc blocks.
++               */
++              WARN_ON_ONCE(ret == -EIOCBQUEUED);
++              ext4_inode_extension_cleanup(inode, ret);
++      }
+ out:
+       if (ilock_shared)
+@@ -672,8 +647,10 @@ ext4_dax_write_iter(struct kiocb *iocb,
+       ret = dax_iomap_rw(iocb, from, &ext4_iomap_ops);
+-      if (extend)
+-              ret = ext4_handle_inode_extension(inode, offset, ret, count);
++      if (extend) {
++              ret = ext4_handle_inode_extension(inode, offset, ret);
++              ext4_inode_extension_cleanup(inode, ret);
++      }
+ out:
+       inode_unlock(inode);
+       if (ret > 0)
diff --git a/queue-6.1/ext4-remove-gdb-backup-copy-for-meta-bg-in-setup_new_flex_group_blocks.patch b/queue-6.1/ext4-remove-gdb-backup-copy-for-meta-bg-in-setup_new_flex_group_blocks.patch
new file mode 100644 (file)
index 0000000..4e96e64
--- /dev/null
@@ -0,0 +1,67 @@
+From 40dd7953f4d606c280074f10d23046b6812708ce Mon Sep 17 00:00:00 2001
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+Date: Sun, 27 Aug 2023 01:47:03 +0800
+Subject: ext4: remove gdb backup copy for meta bg in setup_new_flex_group_blocks
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+commit 40dd7953f4d606c280074f10d23046b6812708ce upstream.
+
+Wrong check of gdb backup in meta bg as following:
+first_group is the first group of meta_bg which contains target group, so
+target group is always >= first_group. We check if target group has gdb
+backup by comparing first_group with [group + 1] and [group +
+EXT4_DESC_PER_BLOCK(sb) - 1]. As group >= first_group, then [group + N] is
+> first_group. So no copy of gdb backup in meta bg is done in
+setup_new_flex_group_blocks.
+
+No need to do gdb backup copy in meta bg from setup_new_flex_group_blocks
+as we always copy updated gdb block to backups at end of
+ext4_flex_group_add as following:
+
+ext4_flex_group_add
+  /* no gdb backup copy for meta bg any more */
+  setup_new_flex_group_blocks
+
+  /* update current group number */
+  ext4_update_super
+    sbi->s_groups_count += flex_gd->count;
+
+  /*
+   * if group in meta bg contains backup is added, the primary gdb block
+   * of the meta bg will be copy to backup in new added group here.
+   */
+  for (; gdb_num <= gdb_num_end; gdb_num++)
+    update_backups(...)
+
+In summary, we can remove wrong gdb backup copy code in
+setup_new_flex_group_blocks.
+
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Theodore Ts'o <tytso@mit.edu>
+Link: https://lore.kernel.org/r/20230826174712.4059355-5-shikemeng@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/resize.c |    9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -560,13 +560,8 @@ static int setup_new_flex_group_blocks(s
+               if (meta_bg == 0 && !ext4_bg_has_super(sb, group))
+                       goto handle_itb;
+-              if (meta_bg == 1) {
+-                      ext4_group_t first_group;
+-                      first_group = ext4_meta_bg_first_group(sb, group);
+-                      if (first_group != group + 1 &&
+-                          first_group != group + EXT4_DESC_PER_BLOCK(sb) - 1)
+-                              goto handle_itb;
+-              }
++              if (meta_bg == 1)
++                      goto handle_itb;
+               block = start + ext4_bg_has_super(sb, group);
+               /* Copy all of the GDT blocks into the backup in this group */
diff --git a/queue-6.1/media-qcom-camss-fix-set-csi2_rx_cfg1_vc_mode-when-vc-is-greater-than-3.patch b/queue-6.1/media-qcom-camss-fix-set-csi2_rx_cfg1_vc_mode-when-vc-is-greater-than-3.patch
deleted file mode 100644 (file)
index 443dac9..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From e655d1ae9703286cef7fda8675cad62f649dc183 Mon Sep 17 00:00:00 2001
-From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
-Date: Wed, 30 Aug 2023 16:16:14 +0100
-Subject: media: qcom: camss: Fix set CSI2_RX_CFG1_VC_MODE when VC is greater than 3
-
-From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
-
-commit e655d1ae9703286cef7fda8675cad62f649dc183 upstream.
-
-VC_MODE = 0 implies a two bit VC address.
-VC_MODE = 1 is required for VCs with a larger address than two bits.
-
-Fixes: eebe6d00e9bf ("media: camss: Add support for CSID hardware version Titan 170")
-Cc: stable@vger.kernel.org
-Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/media/platform/qcom/camss/camss-csid-gen2.c |    2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c
-+++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
-@@ -449,6 +449,8 @@ static void csid_configure_stream(struct
-       writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0);
-       val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN;
-+      if (vc > 3)
-+              val |= 1 << CSI2_RX_CFG1_VC_MODE;
-       val |= 1 << CSI2_RX_CFG1_MISR_EN;
-       writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1);
diff --git a/queue-6.1/revert-net-r8169-disable-multicast-filter-for-rtl8168h-and-rtl8107e.patch b/queue-6.1/revert-net-r8169-disable-multicast-filter-for-rtl8168h-and-rtl8107e.patch
new file mode 100644 (file)
index 0000000..a626c17
--- /dev/null
@@ -0,0 +1,45 @@
+From 6a26310273c323380da21eb23fcfd50e31140913 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Tue, 21 Nov 2023 09:09:33 +0100
+Subject: Revert "net: r8169: Disable multicast filter for RTL8168H and RTL8107E"
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+commit 6a26310273c323380da21eb23fcfd50e31140913 upstream.
+
+This reverts commit efa5f1311c4998e9e6317c52bc5ee93b3a0f36df.
+
+I couldn't reproduce the reported issue. What I did, based on a pcap
+packet log provided by the reporter:
+- Used same chip version (RTL8168h)
+- Set MAC address to the one used on the reporters system
+- Replayed the EAPOL unicast packet that, according to the reporter,
+  was filtered out by the mc filter.
+The packet was properly received.
+
+Therefore the root cause of the reported issue seems to be somewhere
+else. Disabling mc filtering completely for the most common chip
+version is a quite big hammer. Therefore revert the change and wait
+for further analysis results from the reporter.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c |    4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2529,9 +2529,7 @@ static void rtl_set_rx_mode(struct net_d
+               rx_mode &= ~AcceptMulticast;
+       } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT ||
+                  dev->flags & IFF_ALLMULTI ||
+-                 tp->mac_version == RTL_GIGA_MAC_VER_35 ||
+-                 tp->mac_version == RTL_GIGA_MAC_VER_46 ||
+-                 tp->mac_version == RTL_GIGA_MAC_VER_48) {
++                 tp->mac_version == RTL_GIGA_MAC_VER_35) {
+               /* accept all multicasts */
+       } else if (netdev_mc_empty(dev)) {
+               rx_mode &= ~AcceptMulticast;
index 3c31377ab9a6704c0a92a1f4ede936c5aa736700..d19866ea512c027f81380a846fc8e07ac6c7d30c 100644 (file)
@@ -343,6 +343,15 @@ media-qcom-camss-fix-vfe_get-error-jump.patch
 media-qcom-camss-fix-vfe-17x-vfe_disable_output.patch
 media-qcom-camss-fix-vfe-480-vfe_disable_output.patch
 media-qcom-camss-fix-missing-vfe_lite-clocks-check.patch
-media-qcom-camss-fix-set-csi2_rx_cfg1_vc_mode-when-vc-is-greater-than-3.patch
 media-qcom-camss-fix-invalid-clock-enable-bit-disjunction.patch
 media-qcom-camss-fix-csid-gen2-for-test-pattern-generator.patch
+revert-net-r8169-disable-multicast-filter-for-rtl8168h-and-rtl8107e.patch
+ext4-apply-umask-if-acl-support-is-disabled.patch
+ext4-correct-offset-of-gdb-backup-in-non-meta_bg-group-to-update_backups.patch
+ext4-mark-buffer-new-if-it-is-unwritten-to-avoid-stale-data-exposure.patch
+ext4-correct-return-value-of-ext4_convert_meta_bg.patch
+ext4-correct-the-start-block-of-counting-reserved-clusters.patch
+ext4-remove-gdb-backup-copy-for-meta-bg-in-setup_new_flex_group_blocks.patch
+ext4-add-missed-brelse-in-update_backups.patch
+ext4-properly-sync-file-size-update-after-o_sync-direct-io.patch
+drm-amd-pm-handle-non-terminated-overdrive-commands.patch