]>
Commit | Line | Data |
---|---|---|
68be554e TL |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Rob Norris <rob.norris@klarasystems.com> | |
3 | Date: Tue, 2 Apr 2024 15:14:54 +1100 | |
4 | Subject: [PATCH] vdev_disk: don't touch vbio after its handed off to the | |
5 | kernel | |
6 | ||
7 | After IO is unplugged, it may complete immediately and vbio_completion | |
8 | be called on interrupt context. That may interrupt or deschedule our | |
9 | task. If its the last bio, the vbio will be freed. Then, we get | |
10 | rescheduled, and try to write to freed memory through vbio->. | |
11 | ||
12 | This patch just removes the the cleanup, and the corresponding assert. | |
13 | These were leftovers from a previous iteration of vbio_submit() and were | |
14 | always "belt and suspenders" ops anyway, never strictly required. | |
15 | ||
16 | Reported-by: Rich Ercolani <rincebrain@gmail.com> | |
17 | Signed-off-by: Rob Norris <rob.norris@klarasystems.com> | |
18 | Sponsored-by: Klara, Inc. | |
19 | Sponsored-by: Wasabi Technology, Inc. | |
20 | (cherry picked from commit 34f662ad22206af6852020fd923ceccd836a855f) | |
21 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> | |
22 | --- | |
23 | module/os/linux/zfs/vdev_disk.c | 11 ++++++----- | |
24 | 1 file changed, 6 insertions(+), 5 deletions(-) | |
25 | ||
26 | diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c | |
27 | index e1c19a085..62c7aa14f 100644 | |
28 | --- a/module/os/linux/zfs/vdev_disk.c | |
29 | +++ b/module/os/linux/zfs/vdev_disk.c | |
30 | @@ -758,8 +758,6 @@ vbio_fill_cb(struct page *page, size_t off, size_t len, void *priv) | |
31 | static void | |
32 | vbio_submit(vbio_t *vbio, abd_t *abd, uint64_t size) | |
33 | { | |
34 | - ASSERT(vbio->vbio_bdev); | |
35 | - | |
36 | /* | |
37 | * We plug so we can submit the BIOs as we go and only unplug them when | |
38 | * they are fully created and submitted. This is important; if we don't | |
39 | @@ -777,12 +775,15 @@ vbio_submit(vbio_t *vbio, abd_t *abd, uint64_t size) | |
40 | vbio->vbio_bio->bi_end_io = vbio_completion; | |
41 | vbio->vbio_bio->bi_private = vbio; | |
42 | ||
43 | + /* | |
44 | + * Once submitted, vbio_bio now owns vbio (through bi_private) and we | |
45 | + * can't touch it again. The bio may complete and vbio_completion() be | |
46 | + * called and free the vbio before this task is run again, so we must | |
47 | + * consider it invalid from this point. | |
48 | + */ | |
49 | vdev_submit_bio(vbio->vbio_bio); | |
50 | ||
51 | blk_finish_plug(&plug); | |
52 | - | |
53 | - vbio->vbio_bio = NULL; | |
54 | - vbio->vbio_bdev = NULL; | |
55 | } | |
56 | ||
57 | /* IO completion callback */ |