data_rw_complete() calls qio_endio() before complete_wbd(). qio_endio() drops the inflight ref, so qcow2_flush_deferred_activity() may return on suspend while complete_wbd() for a failed L1/L2 writeback is still running in AIO completion context. revert_l_entries_update() then marks clusters unused and dirties an R2 page after the flush.
That page sits on slow_wb_batch_list with the slow writeback timer armed. If the timer fires first, the page is written while the device is suspended, after postsuspend has cleared the dirty bit. If preresume comes first, qcow2_free_md_pages_all() frees the page without taking it off the list, and the timer later walks freed memory. Complete the wbd first, so the R2 update is in place before the inflight ref goes away and the suspend flush writes it back. The md writeback path already does it in this order. https://virtuozzo.atlassian.net/browse/VSTOR-148171 Feature: dm-qcow2: block device over QCOW2 files driver Fixes: 222b6f1291c1c ("dm-qcow2: Introduce driver to create block devices over QCOW2 files") Signed-off-by: Alexander Ivanov <[email protected]> --- drivers/md/dm-qcow2-map.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c index e8a41954c4c6..7866c791325b 100644 --- a/drivers/md/dm-qcow2-map.c +++ b/drivers/md/dm-qcow2-map.c @@ -2892,13 +2892,14 @@ static void data_rw_complete(struct qio *qio) spin_unlock_irqrestore(&qcow2->md_pages_lock, flags); } + /* qio_endio() drops the inflight ref, which suspend waits for */ + if (finalize_wbd) + complete_wbd(qcow2, wbd); if (call_endio) { if (bi_status != BLK_STS_OK) qio->bi_status = bi_status; qio_endio(qio); } - if (finalize_wbd) - complete_wbd(qcow2, wbd); } static void perform_rw_mapped(struct qcow2_map *map, struct qio *qio) -- 2.53.0 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
