Commit f6d38c9
block-backend: fix edge case in bdrv_next() where BDS associated to BB changes
The old_bs variable in bdrv_next() is currently determined by looking
at the old block backend. However, if the block graph changes before
the next bdrv_next() call, it might be that the associated BDS is not
the same that was referenced previously. In that case, the wrong BDS
is unreferenced, leading to an assertion failure later:
> bdrv_unref: Assertion `bs->refcnt > 0' failed.
In particular, this can happen in the context of bdrv_flush_all(),
when polling for bdrv_co_flush() in the generated co-wrapper leads to
a graph change (for example with a stream block job [0]).
A racy reproducer:
> #!/bin/bash
> rm -f /tmp/backing.qcow2
> rm -f /tmp/top.qcow2
> ./qemu-img create /tmp/backing.qcow2 -f qcow2 64M
> ./qemu-io -c "write -P42 0x0 0x1" /tmp/backing.qcow2
> ./qemu-img create /tmp/top.qcow2 -f qcow2 64M -b /tmp/backing.qcow2 -F qcow2
> ./qemu-system-x86_64 --qmp stdio \
> --blockdev qcow2,node-name=node0,file.driver=file,file.filename=/tmp/top.qcow2 \
> <<EOF
> {"execute": "qmp_capabilities"}
> {"execute": "block-stream", "arguments": { "job-id": "stream0", "device": "node0" } }
> {"execute": "quit"}
> EOF
[0]:
> #0 bdrv_replace_child_tran (child=..., new_bs=..., tran=...)
> #1 bdrv_replace_node_noperm (from=..., to=..., auto_skip=..., tran=..., errp=...)
> qemu#2 bdrv_replace_node_common (from=..., to=..., auto_skip=..., detach_subchain=..., errp=...)
> qemu#3 bdrv_drop_filter (bs=..., errp=...)
> qemu#4 bdrv_cor_filter_drop (cor_filter_bs=...)
> qemu#5 stream_prepare (job=...)
> qemu#6 job_prepare_locked (job=...)
> qemu#7 job_txn_apply_locked (fn=..., job=...)
> qemu#8 job_do_finalize_locked (job=...)
> qemu#9 job_exit (opaque=...)
> qemu#10 aio_bh_poll (ctx=...)
> qemu#11 aio_poll (ctx=..., blocking=...)
> qemu#12 bdrv_poll_co (s=...)
> qemu#13 bdrv_flush (bs=...)
> qemu#14 bdrv_flush_all ()
> qemu#15 do_vm_stop (state=..., send_stop=...)
> qemu#16 vm_shutdown ()
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20240322095009.346989-3-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>1 parent 3f93481 commit f6d38c9
1 file changed
+3
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
599 | 599 | | |
600 | 600 | | |
601 | 601 | | |
| 602 | + | |
| 603 | + | |
602 | 604 | | |
603 | 605 | | |
604 | 606 | | |
605 | 607 | | |
606 | 608 | | |
607 | 609 | | |
608 | | - | |
609 | | - | |
610 | 610 | | |
611 | 611 | | |
612 | 612 | | |
| |||
620 | 620 | | |
621 | 621 | | |
622 | 622 | | |
| 623 | + | |
623 | 624 | | |
624 | 625 | | |
625 | 626 | | |
626 | | - | |
627 | | - | |
628 | 627 | | |
629 | 628 | | |
630 | 629 | | |
| |||
0 commit comments