--- /dev/null
+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
+
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
--- /dev/null
+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
+
--- /dev/null
+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
+