From: Greg Kroah-Hartman Date: Mon, 6 Jun 2022 10:28:07 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v5.10.121~144 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d7c492513c7a565701a847d89d782d2a50d61ba1;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches 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 --- 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 index 00000000000..674ff9b412b --- /dev/null +++ b/queue-5.15/btrfs-add-0x-prefix-for-unsupported-optional-features.patch @@ -0,0 +1,47 @@ +From d5321a0fa8bc49f11bea0b470800962c17d92d8f Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Tue, 10 May 2022 15:10:18 +0800 +Subject: btrfs: add "0x" prefix for unsupported optional features + +From: Qu Wenruo + +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 +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..966593b3110 --- /dev/null +++ b/queue-5.15/btrfs-fix-the-error-handling-for-submit_extent_page-for-btrfs_do_readpage.patch @@ -0,0 +1,71 @@ +From 10f7f6f879c28f8368d6516ab1ccf3517a1f5d3d Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +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 + +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 +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..f3869fb58d0 --- /dev/null +++ b/queue-5.15/btrfs-repair-super-block-num_devices-automatically.patch @@ -0,0 +1,94 @@ +From d201238ccd2f30b9bfcfadaeae0972e3a486a176 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +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 + +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 +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 +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..76f42af0579 --- /dev/null +++ b/queue-5.15/btrfs-return-correct-error-number-for-__extent_writepage_io.patch @@ -0,0 +1,88 @@ +From 44e5801fada6925d2bba1987c7b59cbcc9d0d592 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Tue, 12 Apr 2022 20:30:15 +0800 +Subject: btrfs: return correct error number for __extent_writepage_io() + +From: Qu Wenruo + +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 +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } diff --git a/queue-5.15/series b/queue-5.15/series index 1f451317865..b0cd8203ae9 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -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