qemu/block
Alberto Garcia 184581fa4d qcow2: Fix removal of list members from BDRVQcow2State.cluster_allocs
When a write request needs to allocate new clusters (or change the L2
bitmap of existing ones) a QCowL2Meta structure is created so the L2
metadata can be later updated and any copy-on-write can be performed
if necessary.

A write request can span a region consisting of an arbitrary
combination of previously unallocated and allocated clusters, and if
the unallocated ones can be put contiguous to the existing ones then
QEMU will do so in order to minimize the number of write operations.

In practice this means that a write request has not just one but a
number of QCowL2Meta structures. All of them are added to the
cluster_allocs list that is stored in BDRVQcow2State and is used to
detect overlapping requests. After the write request finishes all its
associated QCowL2Meta are removed from that list. calculate_l2_meta()
takes care of creating and putting those structures in the list, and
qcow2_handle_l2meta() takes care of removing them.

The problem is that the error path in handle_alloc() also tries to
remove an item in that list, a remnant from the time when this was
handled there (that code would not even be correct anymore because
it only removes one struct and not all the ones from the same write
request).

This can trigger a double removal of the same item from the list,
causing a crash. This is not easy to reproduce in practice because
it requires that do_alloc_cluster_offset() fails after a successful
previous allocation during the same write request, but it can be
reproduced with the included test case.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Message-Id: <3440a1c4d53c4fe48312b478c96accb338cbef7c.1599150873.git.berto@igalia.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2020-09-15 11:05:13 +02:00
..
monitor commit: Deal with filters 2020-09-07 12:31:31 +02:00
accounting.c block: add empty account cookie type 2019-10-10 10:56:18 +02:00
aio_task.c block: introduce aio task pool 2019-10-10 10:56:17 +02:00
amend.c block/amend: Check whether the node exists 2020-07-27 12:37:25 +02:00
backup-top.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
backup-top.h block: introduce backup-top filter driver 2019-10-10 10:56:18 +02:00
backup.c backup: Deal with filters 2020-09-07 12:31:31 +02:00
blkdebug.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
blklogwrites.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
blkreplay.c block: Use bdrv_default_perms() 2020-05-18 19:05:25 +02:00
blkverify.c error: Eliminate error_propagate() with Coccinelle, part 2 2020-07-10 15:18:08 +02:00
block-backend.c commit: Deal with filters 2020-09-07 12:31:31 +02:00
block-copy.c block-copy: Use CAF to find sync=top base 2020-09-07 12:31:31 +02:00
bochs.c block: Use bdrv_default_perms() 2020-05-18 19:05:25 +02:00
cloop.c block: Use bdrv_default_perms() 2020-05-18 19:05:25 +02:00
commit.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
copy-on-read.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
create.c block/create: Do not abort if a block driver is not available 2019-09-13 12:18:37 +02:00
crypto.c block/crypto: disallow write sharing by default 2020-07-21 10:49:02 +02:00
crypto.h block/crypto: implement the encryption key management 2020-07-06 08:49:28 +02:00
curl.c error: Eliminate error_propagate() with Coccinelle, part 1 2020-07-10 15:18:08 +02:00
dirty-bitmap.c block/dirty-bitmap: add bdrv_has_named_bitmaps helper 2020-05-28 13:15:22 -05:00
dmg-bz2.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
dmg-lzfse.c
dmg.c block: Use bdrv_default_perms() 2020-05-18 19:05:25 +02:00
dmg.h Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
file-posix.c file-posix: Handle EINVAL fallocate return value 2020-07-21 16:28:57 +02:00
file-win32.c file-win32: Fix "locking" option 2020-09-10 11:11:12 +02:00
filter-compress.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
gluster.c error: Reduce unnecessary error propagation 2020-07-10 15:18:08 +02:00
io_uring.c io_uring: use io_uring_cq_ready() to check for ready cqes 2020-06-05 09:54:48 +01:00
io.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
iscsi-opts.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
iscsi.c iscsi: return -EIO when sense fields are meaningless 2020-07-10 18:02:23 -04:00
linux-aio.c misc: Replace zero-length arrays with flexible array member (automatic) 2020-03-16 22:07:42 +01:00
meson.build block: always link with zlib 2020-09-01 01:51:51 -04:00
mirror.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
nbd.c block/nbd: use non-blocking connect: fix vm hang on connect() 2020-09-02 16:47:23 -05:00
nfs.c qapi: Smooth another visitor error checking pattern 2020-07-10 15:18:08 +02:00
null.c block/null: Implement bdrv_get_allocated_file_size 2020-09-07 12:31:31 +02:00
nvme.c block/nvme: Pair doorbell registers 2020-09-10 11:11:13 +02:00
parallels.c error: Avoid error_propagate() after migrate_add_blocker() 2020-07-10 15:18:08 +02:00
parallels.h
qapi-sysemu.c block: Move system emulator QMP commands to block/qapi-sysemu.c 2020-03-06 17:15:38 +01:00
qapi.c block: Leave BDS.backing_{file,format} constant 2020-09-07 12:31:31 +02:00
qcow2-bitmap.c qcow2: Use macros for the L1, refcount and bitmap table entry sizes 2020-09-15 11:05:12 +02:00
qcow2-cache.c core: replace getpagesize() with qemu_real_host_page_size 2019-10-26 15:38:06 +02:00
qcow2-cluster.c qcow2: Fix removal of list members from BDRVQcow2State.cluster_allocs 2020-09-15 11:05:13 +02:00
qcow2-refcount.c qcow2: Use macros for the L1, refcount and bitmap table entry sizes 2020-09-15 11:05:12 +02:00
qcow2-snapshot.c qcow2: Use macros for the L1, refcount and bitmap table entry sizes 2020-09-15 11:05:12 +02:00
qcow2-threads.c qcow2: add zstd cluster compression 2020-05-13 14:20:31 +02:00
qcow2.c qcow2: Use macros for the L1, refcount and bitmap table entry sizes 2020-09-15 11:05:12 +02:00
qcow2.h qcow2: Use macros for the L1, refcount and bitmap table entry sizes 2020-09-15 11:05:12 +02:00
qcow.c qcow: Tolerate backing_fmt= 2020-07-14 15:18:59 +02:00
qed-check.c block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
qed-cluster.c
qed-l2-cache.c
qed-table.c block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
qed.c qapi: Smooth another visitor error checking pattern 2020-07-10 15:18:08 +02:00
qed.h qed: Simplify backing reads 2020-07-06 10:34:14 +02:00
quorum.c block/quorum.c: stable children names 2020-09-15 11:05:12 +02:00
raw-format.c error: Eliminate error_propagate() with Coccinelle, part 2 2020-07-10 15:18:08 +02:00
rbd.c qapi: Smooth another visitor error checking pattern 2020-07-10 15:18:08 +02:00
replication.c error: Reduce unnecessary error propagation 2020-07-10 15:18:08 +02:00
sheepdog.c sheepdog: Add trivial backing_fmt support 2020-07-14 15:18:59 +02:00
snapshot.c block/snapshot: Fix fallback 2020-09-07 12:31:31 +02:00
ssh.c qapi: Smooth another visitor error checking pattern 2020-07-10 15:18:08 +02:00
stream.c stream: Deal with filters 2020-09-07 12:31:31 +02:00
throttle-groups.c throttle-groups: Move ThrottleGroup typedef to header 2020-08-27 14:04:54 -04:00
throttle.c block: Inline bdrv_co_block_status_from_*() 2020-09-07 12:31:31 +02:00
trace-events trace-events: Fix attribution of trace points to source 2020-09-09 17:17:58 +01:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
vdi.c error: Avoid error_propagate() after migrate_add_blocker() 2020-07-10 15:18:08 +02:00
vhdx-endian.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
vhdx-log.c block: Add flags to bdrv(_co)_truncate() 2020-04-30 17:51:07 +02:00
vhdx.c error: Avoid error_propagate() after migrate_add_blocker() 2020-07-10 15:18:08 +02:00
vhdx.h
vmdk.c vmdk: Drop vmdk_co_flush() 2020-09-07 12:31:31 +02:00
vpc.c error: Avoid error_propagate() after migrate_add_blocker() 2020-07-10 15:18:08 +02:00
vvfat.c error: Avoid error_propagate() after migrate_add_blocker() 2020-07-10 15:18:08 +02:00
win32-aio.c Include qemu/module.h where needed, drop it from qemu-common.h 2019-06-12 13:18:33 +02:00
write-threshold.c