]> git.proxmox.com Git - mirror_zfs.git/commitdiff
vdev_disk: don't touch vbio after its handed off to the kernel
authorRob N <robn@despairlabs.com>
Wed, 3 Apr 2024 22:17:07 +0000 (09:17 +1100)
committerGitHub <noreply@github.com>
Wed, 3 Apr 2024 22:17:07 +0000 (15:17 -0700)
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 <rincebrain@gmail.com>
Reviewed-by: Laurențiu Nicola <lnicola@dend.ro>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: George Wilson <george.wilson@delphix.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #16045
Closes #16050
Closes #16049

module/os/linux/zfs/vdev_disk.c

index ac8fe6cb1bf9066c1b388d0b96a1332c87978fb4..df5fa067797a9b807c3fcc92a07586f1695b3d63 100644 (file)
@@ -755,8 +755,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
@@ -774,12 +772,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 */