]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jun 2022 10:28:07 +0000 (12:28 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jun 2022 10:28:07 +0000 (12:28 +0200)
added patches:
btrfs-add-0x-prefix-for-unsupported-optional-features.patch
btrfs-fix-the-error-handling-for-submit_extent_page-for-btrfs_do_readpage.patch
btrfs-repair-super-block-num_devices-automatically.patch
btrfs-return-correct-error-number-for-__extent_writepage_io.patch

queue-5.15/btrfs-add-0x-prefix-for-unsupported-optional-features.patch [new file with mode: 0644]
queue-5.15/btrfs-fix-the-error-handling-for-submit_extent_page-for-btrfs_do_readpage.patch [new file with mode: 0644]
queue-5.15/btrfs-repair-super-block-num_devices-automatically.patch [new file with mode: 0644]
queue-5.15/btrfs-return-correct-error-number-for-__extent_writepage_io.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/btrfs-add-0x-prefix-for-unsupported-optional-features.patch b/queue-5.15/btrfs-add-0x-prefix-for-unsupported-optional-features.patch
new file mode 100644 (file)
index 0000000..674ff9b
--- /dev/null
@@ -0,0 +1,47 @@
+From d5321a0fa8bc49f11bea0b470800962c17d92d8f Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 10 May 2022 15:10:18 +0800
+Subject: btrfs: add "0x" prefix for unsupported optional features
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit d5321a0fa8bc49f11bea0b470800962c17d92d8f upstream.
+
+The following error message lack the "0x" obviously:
+
+  cannot mount because of unsupported optional features (4000)
+
+Add the prefix to make it less confusing. This can happen on older
+kernels that try to mount a filesystem with newer features so it makes
+sense to backport to older trees.
+
+CC: stable@vger.kernel.org # 4.14+
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/disk-io.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -3370,7 +3370,7 @@ int __cold open_ctree(struct super_block
+               ~BTRFS_FEATURE_INCOMPAT_SUPP;
+       if (features) {
+               btrfs_err(fs_info,
+-                  "cannot mount because of unsupported optional features (%llx)",
++                  "cannot mount because of unsupported optional features (0x%llx)",
+                   features);
+               err = -EINVAL;
+               goto fail_alloc;
+@@ -3408,7 +3408,7 @@ int __cold open_ctree(struct super_block
+               ~BTRFS_FEATURE_COMPAT_RO_SUPP;
+       if (!sb_rdonly(sb) && features) {
+               btrfs_err(fs_info,
+-      "cannot mount read-write because of unsupported optional features (%llx)",
++      "cannot mount read-write because of unsupported optional features (0x%llx)",
+                      features);
+               err = -EINVAL;
+               goto fail_alloc;
diff --git a/queue-5.15/btrfs-fix-the-error-handling-for-submit_extent_page-for-btrfs_do_readpage.patch b/queue-5.15/btrfs-fix-the-error-handling-for-submit_extent_page-for-btrfs_do_readpage.patch
new file mode 100644 (file)
index 0000000..966593b
--- /dev/null
@@ -0,0 +1,71 @@
+From 10f7f6f879c28f8368d6516ab1ccf3517a1f5d3d Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 12 Apr 2022 20:30:14 +0800
+Subject: btrfs: fix the error handling for submit_extent_page() for btrfs_do_readpage()
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 10f7f6f879c28f8368d6516ab1ccf3517a1f5d3d upstream.
+
+[BUG]
+Test case generic/475 have a very high chance (almost 100%) to hit a fs
+hang, where a data page will never be unlocked and hang all later
+operations.
+
+[CAUSE]
+In btrfs_do_readpage(), if we hit an error from submit_extent_page() we
+will try to do the cleanup for our current io range, and exit.
+
+This works fine for PAGE_SIZE == sectorsize cases, but not for subpage.
+
+For subpage btrfs_do_readpage() will lock the full page first, which can
+contain several different sectors and extents:
+
+ btrfs_do_readpage()
+ |- begin_page_read()
+ |  |- btrfs_subpage_start_reader();
+ |     Now the page will have PAGE_SIZE / sectorsize reader pending,
+ |     and the page is locked.
+ |
+ |- end_page_read() for different branches
+ |  This function will reduce subpage readers, and when readers
+ |  reach 0, it will unlock the page.
+
+But when submit_extent_page() failed, we only cleanup the current
+io range, while the remaining io range will never be cleaned up, and the
+page remains locked forever.
+
+[FIX]
+Update the error handling of submit_extent_page() to cleanup all the
+remaining subpage range before exiting the loop.
+
+Please note that, now submit_extent_page() can only fail due to
+sanity check in alloc_new_bio().
+
+Thus regular IO errors are impossible to trigger the error path.
+
+CC: stable@vger.kernel.org # 5.15+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent_io.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -3727,8 +3727,12 @@ int btrfs_do_readpage(struct page *page,
+                                        this_bio_flag,
+                                        force_bio_submit);
+               if (ret) {
+-                      unlock_extent(tree, cur, cur + iosize - 1);
+-                      end_page_read(page, false, cur, iosize);
++                      /*
++                       * We have to unlock the remaining range, or the page
++                       * will never be unlocked.
++                       */
++                      unlock_extent(tree, cur, end);
++                      end_page_read(page, false, cur, end + 1 - cur);
+                       goto out;
+               }
+               cur = cur + iosize;
diff --git a/queue-5.15/btrfs-repair-super-block-num_devices-automatically.patch b/queue-5.15/btrfs-repair-super-block-num_devices-automatically.patch
new file mode 100644 (file)
index 0000000..f3869fb
--- /dev/null
@@ -0,0 +1,94 @@
+From d201238ccd2f30b9bfcfadaeae0972e3a486a176 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Mon, 28 Feb 2022 15:05:53 +0800
+Subject: btrfs: repair super block num_devices automatically
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit d201238ccd2f30b9bfcfadaeae0972e3a486a176 upstream.
+
+[BUG]
+There is a report that a btrfs has a bad super block num devices.
+
+This makes btrfs to reject the fs completely.
+
+  BTRFS error (device sdd3): super_num_devices 3 mismatch with num_devices 2 found here
+  BTRFS error (device sdd3): failed to read chunk tree: -22
+  BTRFS error (device sdd3): open_ctree failed
+
+[CAUSE]
+During btrfs device removal, chunk tree and super block num devs are
+updated in two different transactions:
+
+  btrfs_rm_device()
+  |- btrfs_rm_dev_item(device)
+  |  |- trans = btrfs_start_transaction()
+  |  |  Now we got transaction X
+  |  |
+  |  |- btrfs_del_item()
+  |  |  Now device item is removed from chunk tree
+  |  |
+  |  |- btrfs_commit_transaction()
+  |     Transaction X got committed, super num devs untouched,
+  |     but device item removed from chunk tree.
+  |     (AKA, super num devs is already incorrect)
+  |
+  |- cur_devices->num_devices--;
+  |- cur_devices->total_devices--;
+  |- btrfs_set_super_num_devices()
+     All those operations are not in transaction X, thus it will
+     only be written back to disk in next transaction.
+
+So after the transaction X in btrfs_rm_dev_item() committed, but before
+transaction X+1 (which can be minutes away), a power loss happen, then
+we got the super num mismatch.
+
+This has been fixed by commit bbac58698a55 ("btrfs: remove device item
+and update super block in the same transaction").
+
+[FIX]
+Make the super_num_devices check less strict, converting it from a hard
+error to a warning, and reset the value to a correct one for the current
+or next transaction commit.
+
+As the number of device items is the critical information where the
+super block num_devices is only a cached value (and also useful for
+cross checking), it's safe to automatically update it. Other device
+related problems like missing device are handled after that and may
+require other means to resolve, like degraded mount. With this fix,
+potentially affected filesystems won't fail mount and require the manual
+repair by btrfs check.
+
+Reported-by: Luca Béla Palkovics <luca.bela.palkovics@gmail.com>
+Link: https://lore.kernel.org/linux-btrfs/CA+8xDSpvdm_U0QLBAnrH=zqDq_cWCOH5TiV46CKmp3igr44okQ@mail.gmail.com/
+CC: stable@vger.kernel.org # 4.14+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/volumes.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -7596,12 +7596,12 @@ int btrfs_read_chunk_tree(struct btrfs_f
+        * do another round of validation checks.
+        */
+       if (total_dev != fs_info->fs_devices->total_devices) {
+-              btrfs_err(fs_info,
+-         "super_num_devices %llu mismatch with num_devices %llu found here",
++              btrfs_warn(fs_info,
++"super block num_devices %llu mismatch with DEV_ITEM count %llu, will be repaired on next transaction commit",
+                         btrfs_super_num_devices(fs_info->super_copy),
+                         total_dev);
+-              ret = -EINVAL;
+-              goto error;
++              fs_info->fs_devices->total_devices = total_dev;
++              btrfs_set_super_num_devices(fs_info->super_copy, total_dev);
+       }
+       if (btrfs_super_total_bytes(fs_info->super_copy) <
+           fs_info->fs_devices->total_rw_bytes) {
diff --git a/queue-5.15/btrfs-return-correct-error-number-for-__extent_writepage_io.patch b/queue-5.15/btrfs-return-correct-error-number-for-__extent_writepage_io.patch
new file mode 100644 (file)
index 0000000..76f42af
--- /dev/null
@@ -0,0 +1,88 @@
+From 44e5801fada6925d2bba1987c7b59cbcc9d0d592 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 12 Apr 2022 20:30:15 +0800
+Subject: btrfs: return correct error number for __extent_writepage_io()
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 44e5801fada6925d2bba1987c7b59cbcc9d0d592 upstream.
+
+[BUG]
+If we hit an error from submit_extent_page() inside
+__extent_writepage_io(), we could still return 0 to the caller, and
+even trigger the warning in btrfs_page_assert_not_dirty().
+
+[CAUSE]
+In __extent_writepage_io(), if we hit an error from
+submit_extent_page(), we will just clean up the range and continue.
+
+This is completely fine for regular PAGE_SIZE == sectorsize, as we can
+only hit one sector in one page, thus after the error we're ensured to
+exit and @ret will be saved.
+
+But for subpage case, we may have other dirty subpage range in the page,
+and in the next loop, we may succeeded submitting the next range.
+
+In that case, @ret will be overwritten, and we return 0 to the caller,
+while we have hit some error.
+
+[FIX]
+Introduce @has_error and @saved_ret to record the first error we hit, so
+we will never forget what error we hit.
+
+CC: stable@vger.kernel.org # 5.15+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent_io.c |   13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -3902,10 +3902,12 @@ static noinline_for_stack int __extent_w
+       u64 extent_offset;
+       u64 block_start;
+       struct extent_map *em;
++      int saved_ret = 0;
+       int ret = 0;
+       int nr = 0;
+       u32 opf = REQ_OP_WRITE;
+       const unsigned int write_flags = wbc_to_write_flags(wbc);
++      bool has_error = false;
+       bool compressed;
+       ret = btrfs_writepage_cow_fixup(page);
+@@ -3956,6 +3958,9 @@ static noinline_for_stack int __extent_w
+               if (IS_ERR_OR_NULL(em)) {
+                       btrfs_page_set_error(fs_info, page, cur, end - cur + 1);
+                       ret = PTR_ERR_OR_ZERO(em);
++                      has_error = true;
++                      if (!saved_ret)
++                              saved_ret = ret;
+                       break;
+               }
+@@ -4019,6 +4024,10 @@ static noinline_for_stack int __extent_w
+                                        end_bio_extent_writepage,
+                                        0, 0, false);
+               if (ret) {
++                      has_error = true;
++                      if (!saved_ret)
++                              saved_ret = ret;
++
+                       btrfs_page_set_error(fs_info, page, cur, iosize);
+                       if (PageWriteback(page))
+                               btrfs_page_clear_writeback(fs_info, page, cur,
+@@ -4032,8 +4041,10 @@ static noinline_for_stack int __extent_w
+        * If we finish without problem, we should not only clear page dirty,
+        * but also empty subpage dirty bits
+        */
+-      if (!ret)
++      if (!has_error)
+               btrfs_page_assert_not_dirty(fs_info, page);
++      else
++              ret = saved_ret;
+       *nr_ret = nr;
+       return ret;
+ }
index 1f4513178657e187b33b3fe9578e3ad8ec010f4b..b0cd8203ae96058ce1357664758ae6ca2fa9e6e4 100644 (file)
@@ -36,3 +36,7 @@ x86-sgx-set-active-memcg-prior-to-shmem-allocation.patch
 ptrace-um-replace-pt_dtrace-with-tif_singlestep.patch
 ptrace-xtensa-replace-pt_singlestep-with-tif_singlestep.patch
 ptrace-reimplement-ptrace_kill-by-always-sending-sigkill.patch
+btrfs-add-0x-prefix-for-unsupported-optional-features.patch
+btrfs-return-correct-error-number-for-__extent_writepage_io.patch
+btrfs-repair-super-block-num_devices-automatically.patch
+btrfs-fix-the-error-handling-for-submit_extent_page-for-btrfs_do_readpage.patch