]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.0
authorSasha Levin <sashal@kernel.org>
Tue, 10 Jan 2023 15:19:32 +0000 (10:19 -0500)
committerSasha Levin <sashal@kernel.org>
Tue, 10 Jan 2023 15:20:11 +0000 (10:20 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.0/btrfs-handle-case-when-repair-happens-with-dev-repla.patch [new file with mode: 0644]
queue-6.0/series
queue-6.0/virtio-blk-use-a-helper-to-handle-request-queuing-er.patch [new file with mode: 0644]
queue-6.0/virtio_blk-fix-signedness-bug-in-virtblk_prep_rq.patch [new file with mode: 0644]

diff --git a/queue-6.0/btrfs-handle-case-when-repair-happens-with-dev-repla.patch b/queue-6.0/btrfs-handle-case-when-repair-happens-with-dev-repla.patch
new file mode 100644 (file)
index 0000000..7e78652
--- /dev/null
@@ -0,0 +1,115 @@
+From 7d511ebaf5a6617ee2f385a24047d01dfc3116fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Jan 2023 09:02:21 +0800
+Subject: btrfs: handle case when repair happens with dev-replace
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit d73a27b86fc722c28a26ec64002e3a7dc86d1c07 ]
+
+[BUG]
+There is a bug report that a BUG_ON() in btrfs_repair_io_failure()
+(originally repair_io_failure() in v6.0 kernel) got triggered when
+replacing a unreliable disk:
+
+  BTRFS warning (device sda1): csum failed root 257 ino 2397453 off 39624704 csum 0xb0d18c75 expected csum 0x4dae9c5e mirror 3
+  kernel BUG at fs/btrfs/extent_io.c:2380!
+  invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
+  CPU: 9 PID: 3614331 Comm: kworker/u257:2 Tainted: G           OE      6.0.0-5-amd64 #1  Debian 6.0.10-2
+  Hardware name: Micro-Star International Co., Ltd. MS-7C60/TRX40 PRO WIFI (MS-7C60), BIOS 2.70 07/01/2021
+  Workqueue: btrfs-endio btrfs_end_bio_work [btrfs]
+  RIP: 0010:repair_io_failure+0x24a/0x260 [btrfs]
+  Call Trace:
+   <TASK>
+   clean_io_failure+0x14d/0x180 [btrfs]
+   end_bio_extent_readpage+0x412/0x6e0 [btrfs]
+   ? __switch_to+0x106/0x420
+   process_one_work+0x1c7/0x380
+   worker_thread+0x4d/0x380
+   ? rescuer_thread+0x3a0/0x3a0
+   kthread+0xe9/0x110
+   ? kthread_complete_and_exit+0x20/0x20
+   ret_from_fork+0x22/0x30
+
+[CAUSE]
+
+Before the BUG_ON(), we got some read errors from the replace target
+first, note the mirror number (3, which is beyond RAID1 duplication,
+thus it's read from the replace target device).
+
+Then at the BUG_ON() location, we are trying to writeback the repaired
+sectors back the failed device.
+
+The check looks like this:
+
+               ret = btrfs_map_block(fs_info, BTRFS_MAP_WRITE, logical,
+                                     &map_length, &bioc, mirror_num);
+               if (ret)
+                       goto out_counter_dec;
+               BUG_ON(mirror_num != bioc->mirror_num);
+
+But inside btrfs_map_block(), we can modify bioc->mirror_num especially
+for dev-replace:
+
+       if (dev_replace_is_ongoing && mirror_num == map->num_stripes + 1 &&
+           !need_full_stripe(op) && dev_replace->tgtdev != NULL) {
+               ret = get_extra_mirror_from_replace(fs_info, logical, *length,
+                                                   dev_replace->srcdev->devid,
+                                                   &mirror_num,
+                                           &physical_to_patch_in_first_stripe);
+               patch_the_first_stripe_for_dev_replace = 1;
+       }
+
+Thus if we're repairing the replace target device, we're going to
+trigger that BUG_ON().
+
+But in reality, the read failure from the replace target device may be
+that, our replace hasn't reached the range we're reading, thus we're
+reading garbage, but with replace running, the range would be properly
+filled later.
+
+Thus in that case, we don't need to do anything but let the replace
+routine to handle it.
+
+[FIX]
+Instead of a BUG_ON(), just skip the repair if we're repairing the
+device replace target device.
+
+Reported-by: 小太 <nospam@kota.moe>
+Link: https://lore.kernel.org/linux-btrfs/CACsxjPYyJGQZ+yvjzxA1Nn2LuqkYqTCcUH43S=+wXhyf8S00Ag@mail.gmail.com/
+CC: stable@vger.kernel.org # 6.0+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/extent_io.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index cf4f19e80e2f..0982995177a6 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -2377,7 +2377,16 @@ static int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
+                                     &map_length, &bioc, mirror_num);
+               if (ret)
+                       goto out_counter_dec;
+-              BUG_ON(mirror_num != bioc->mirror_num);
++              /*
++               * This happens when dev-replace is also running, and the
++               * mirror_num indicates the dev-replace target.
++               *
++               * In this case, we don't need to do anything, as the read
++               * error just means the replace progress hasn't reached our
++               * read range, and later replace routine would handle it well.
++               */
++              if (mirror_num != bioc->mirror_num)
++                      goto out_counter_dec;
+       }
+       sector = bioc->stripes[bioc->mirror_num - 1].physical >> 9;
+-- 
+2.35.1
+
index 027a9ccc03d1bb0f4ef6f2904188337b9fd4f3e3..35a16499eb8996dd81657e07f7185fff049199df 100644 (file)
@@ -137,3 +137,6 @@ of-fdt-run-soc-memory-setup-when-early_init_dt_scan_memory-fails.patch
 drm-amdkfd-fix-kernel-warning-during-topology-setup.patch
 drm-i915-gvt-fix-gvt-debugfs-destroy.patch
 drm-i915-gvt-fix-vgpu-debugfs-clean-in-remove.patch
+virtio-blk-use-a-helper-to-handle-request-queuing-er.patch
+virtio_blk-fix-signedness-bug-in-virtblk_prep_rq.patch
+btrfs-handle-case-when-repair-happens-with-dev-repla.patch
diff --git a/queue-6.0/virtio-blk-use-a-helper-to-handle-request-queuing-er.patch b/queue-6.0/virtio-blk-use-a-helper-to-handle-request-queuing-er.patch
new file mode 100644 (file)
index 0000000..22bef43
--- /dev/null
@@ -0,0 +1,78 @@
+From 48d43a447997d6abccf7fcb125251a8047c1a1ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Oct 2022 23:41:26 -0400
+Subject: virtio-blk: use a helper to handle request queuing errors
+
+From: Dmitry Fomichev <dmitry.fomichev@wdc.com>
+
+[ Upstream commit 258896fcc786b4e7db238eba26f6dd080e0ff41e ]
+
+Define a new helper function, virtblk_fail_to_queue(), to
+clean up the error handling code in virtio_queue_rq().
+
+Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
+Message-Id: <20221016034127.330942-2-dmitry.fomichev@wdc.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Stable-dep-of: a26116c1e740 ("virtio_blk: Fix signedness bug in virtblk_prep_rq()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/virtio_blk.c | 29 ++++++++++++++++-------------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index dd9a05174726..b3b1191281ea 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -311,6 +311,19 @@ static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx)
+               virtqueue_notify(vq->vq);
+ }
++static blk_status_t virtblk_fail_to_queue(struct request *req, int rc)
++{
++      virtblk_cleanup_cmd(req);
++      switch (rc) {
++      case -ENOSPC:
++              return BLK_STS_DEV_RESOURCE;
++      case -ENOMEM:
++              return BLK_STS_RESOURCE;
++      default:
++              return BLK_STS_IOERR;
++      }
++}
++
+ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx,
+                                       struct virtio_blk *vblk,
+                                       struct request *req,
+@@ -323,10 +336,8 @@ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx,
+               return status;
+       vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr);
+-      if (unlikely(vbr->sg_table.nents < 0)) {
+-              virtblk_cleanup_cmd(req);
+-              return BLK_STS_RESOURCE;
+-      }
++      if (unlikely(vbr->sg_table.nents < 0))
++              return virtblk_fail_to_queue(req, -ENOMEM);
+       blk_mq_start_request(req);
+@@ -360,15 +371,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
+                       blk_mq_stop_hw_queue(hctx);
+               spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
+               virtblk_unmap_data(req, vbr);
+-              virtblk_cleanup_cmd(req);
+-              switch (err) {
+-              case -ENOSPC:
+-                      return BLK_STS_DEV_RESOURCE;
+-              case -ENOMEM:
+-                      return BLK_STS_RESOURCE;
+-              default:
+-                      return BLK_STS_IOERR;
+-              }
++              return virtblk_fail_to_queue(req, err);
+       }
+       if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq))
+-- 
+2.35.1
+
diff --git a/queue-6.0/virtio_blk-fix-signedness-bug-in-virtblk_prep_rq.patch b/queue-6.0/virtio_blk-fix-signedness-bug-in-virtblk_prep_rq.patch
new file mode 100644 (file)
index 0000000..8deaca4
--- /dev/null
@@ -0,0 +1,53 @@
+From 4a3a0722635d5147d04a5906a6e993cd23799f42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 17:41:26 -0300
+Subject: virtio_blk: Fix signedness bug in virtblk_prep_rq()
+
+From: Rafael Mendonca <rafaelmendsr@gmail.com>
+
+[ Upstream commit a26116c1e74028914f281851488546c91cbae57d ]
+
+The virtblk_map_data() function returns negative error codes, however, the
+'nents' field of vbr->sg_table is an unsigned int, which causes the error
+handling not to work correctly.
+
+Cc: stable@vger.kernel.org
+Fixes: 0e9911fa768f ("virtio-blk: support mq_ops->queue_rqs()")
+Signed-off-by: Rafael Mendonca <rafaelmendsr@gmail.com>
+Message-Id: <20221021204126.927603-1-rafaelmendsr@gmail.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Reviewed-by: Suwan Kim <suwan.kim027@gmail.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/virtio_blk.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index b3b1191281ea..53931fcef0d5 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -330,14 +330,16 @@ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx,
+                                       struct virtblk_req *vbr)
+ {
+       blk_status_t status;
++      int num;
+       status = virtblk_setup_cmd(vblk->vdev, req, vbr);
+       if (unlikely(status))
+               return status;
+-      vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr);
+-      if (unlikely(vbr->sg_table.nents < 0))
++      num = virtblk_map_data(hctx, req, vbr);
++      if (unlikely(num < 0))
+               return virtblk_fail_to_queue(req, -ENOMEM);
++      vbr->sg_table.nents = num;
+       blk_mq_start_request(req);
+-- 
+2.35.1
+