aboutsummaryrefslogtreecommitdiffstats
path: root/module/os/linux
diff options
context:
space:
mode:
authorRob Norris <[email protected]>2024-04-04 09:17:07 +1100
committerBrian Behlendorf <[email protected]>2024-04-08 10:13:55 -0700
commit28520cad2500b60ce8653e431990e33f77ff08f7 (patch)
treecaa3616d19bb3519e6edcc05d53579f6c3161f88 /module/os/linux
parentdeb7a84231aff8d772bb4ce9fa486d1886f1a2b6 (diff)
vdev_disk: don't touch vbio after its handed off to the kernel
After IO is unplugged, it may complete immediately and vbio_completion be called on interrupt context. That may interrupt or deschedule our task. If its the last bio, the vbio will be freed. Then, we get rescheduled, and try to write to freed memory through vbio->. This patch just removes the the cleanup, and the corresponding assert. These were leftovers from a previous iteration of vbio_submit() and were always "belt and suspenders" ops anyway, never strictly required. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc Reported-by: Rich Ercolani <[email protected]> Signed-off-by: Rob Norris <[email protected]> (cherry picked from commit 917ff75e9510d19968ef3cc5c80b1cd0ef48f84d)
Diffstat (limited to 'module/os/linux')
-rw-r--r--module/os/linux/zfs/vdev_disk.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c
index e1c19a085..62c7aa14f 100644
--- a/module/os/linux/zfs/vdev_disk.c
+++ b/module/os/linux/zfs/vdev_disk.c
@@ -758,8 +758,6 @@ vbio_fill_cb(struct page *page, size_t off, size_t len, void *priv)
static void
vbio_submit(vbio_t *vbio, abd_t *abd, uint64_t size)
{
- ASSERT(vbio->vbio_bdev);
-
/*
* We plug so we can submit the BIOs as we go and only unplug them when
* they are fully created and submitted. This is important; if we don't
@@ -777,12 +775,15 @@ vbio_submit(vbio_t *vbio, abd_t *abd, uint64_t size)
vbio->vbio_bio->bi_end_io = vbio_completion;
vbio->vbio_bio->bi_private = vbio;
+ /*
+ * Once submitted, vbio_bio now owns vbio (through bi_private) and we
+ * can't touch it again. The bio may complete and vbio_completion() be
+ * called and free the vbio before this task is run again, so we must
+ * consider it invalid from this point.
+ */
vdev_submit_bio(vbio->vbio_bio);
blk_finish_plug(&plug);
-
- vbio->vbio_bio = NULL;
- vbio->vbio_bdev = NULL;
}
/* IO completion callback */