A discard unmapping a cluster locks its L2 index, so requests coming later wait until the discard is finished. But a data write, which has resolved the index before it was locked, may still be in flight when the discard drops the cluster refcount in process_indexes_end(). If the cluster is allocated again before this write lands, the write corrupts the data or the metadata of the new owner.
Make such a discard wait for these writes before the cluster is freed: Patch 1 counts in-flight data writes per L2 page in two generations. Nobody reads the counters yet, so there is no functional change. Patch 2 is the fix. The discard switches the generation of its L2 page and waits for the previous one to drain right before the refcount is dropped. Writes submitted after the switch are counted separately, so the wait is bounded by the writes already in flight. Patch 3 is an optimisation. Discards of clusters mapped by one L2 page usually come to process_indexes_end() in one batch. Let them wait for the same generation together instead of one by one. https://virtuozzo.atlassian.net/browse/VSTOR-154659 Andrey Zhadchenko (3): dm-qcow2: count in-flight data writes per L2 page dm-qcow2: wait for in-flight writes before freeing a discarded cluster dm-qcow2: let discards of one L2 page wait for in-flight writes together drivers/md/dm-qcow2-map.c | 118 +++++++++++++++++++++++++++++++++++ drivers/md/dm-qcow2-target.c | 6 ++ drivers/md/dm-qcow2.h | 12 ++++ 3 files changed, 136 insertions(+) -- 2.43.5 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
