Hi all! It occurs that nothing prevents discarding and reallocating host cluster during data writing. This way data writing will pollute another newly allocated cluster of data or metadata.
OK, v2 is a try to solve the problem with CoRwlock.. And it is marked RFC, because of a lot of iotest failures.. Some of problems with v2: 1. It's a more complicated to make a test, as everything is blocking and I can't just break write and do discard.. I have to implement aio_discard in qemu-io and rewrite test into several portions of io commands splitted by "sleep 1".. OK, it's not a big problem, and I've solved it. 2. iotest 7 fails with several leaked clusters. Seems, that it depend on the fact that discard may be done in parallel with writes. Iotest 7 does snapshots, so I think l1 table is updated to the moment when discard is finally unlocked.. But I didn't dig into it, it's all my assumptions. 3. iotest 13 (and I think a lot more iotests) crashes on assert(!to->locks_held); .. So with this assertion we can't keep rwlock locked during data writing... #3 in __assert_fail () from /lib64/libc.so.6 #4 in qemu_aio_coroutine_enter (ctx=0x55762120b700, co=0x55762121d700) at ../util/qemu-coroutine.c:158 #5 in aio_co_enter (ctx=0x55762120b700, co=0x55762121d700) at ../util/async.c:628 #6 in aio_co_wake (co=0x55762121d700) at ../util/async.c:612 #7 in thread_pool_co_cb (opaque=0x7f17950daab0, ret=0) at ../util/thread-pool.c:279 #8 in thread_pool_completion_bh (opaque=0x5576211e5070) at ../util/thread-pool.c:188 #9 in aio_bh_call (bh=0x557621205df0) at ../util/async.c:136 #10 in aio_bh_poll (ctx=0x55762120b700) at ../util/async.c:164 #11 in aio_poll (ctx=0x55762120b700, blocking=true) at ../util/aio-posix.c:659 #12 in blk_prw (blk=0x557621205790, offset=4303351808, buf=0x55762123e000 '\364' <repeats 199 times>, <incomplete sequence \364>..., bytes=12288, co_entry=0x557620d9dc97 <blk_write_entry>, flags=0) at ../block/block-backend.c:1335 #13 in blk_pwrite (blk=0x557621205790, offset=4303351808, buf=0x55762123e000, count=12288, flags=0) at ../block/block-backend.c:1501 So now I think that v1 is simpler.. It's more complicated (but not too much) in code. But it keeps discards and data writes non-blocking each other and avoids yields in critical sections. Vladimir Sementsov-Ogievskiy (3): qemu-io: add aio_discard iotests: add qcow2-discard-during-rewrite block/qcow2: introduce inflight writes counters: fix discard block/qcow2.h | 2 + block/qcow2-cluster.c | 4 + block/qcow2.c | 18 ++- qemu-io-cmds.c | 117 ++++++++++++++++++ .../tests/qcow2-discard-during-rewrite | 99 +++++++++++++++ .../tests/qcow2-discard-during-rewrite.out | 17 +++ 6 files changed, 256 insertions(+), 1 deletion(-) create mode 100755 tests/qemu-iotests/tests/qcow2-discard-during-rewrite create mode 100644 tests/qemu-iotests/tests/qcow2-discard-during-rewrite.out -- 2.29.2