ploop_tracker_init() may acquire current alloc_head only after quiescing ploop. Otherwise a race is possible:
1) we acuire an alloc_head: e.end = (u64)ploop_top_delta(plo)->io.alloc_head << (plo->cluster_log + 9); 2) then the alloc_head is advanced due to submit_alloc writes 3) we turn write tracker ON: set_bit(PLOOP_S_TRACK, &plo->state). The result is disastrous: the 1st iteration of userspace vzmigrate won't copy blocks allocated on "2)" because we reported old e.end; and then vzmigrate also won't copy the blocks because they were allocated when write tracker was off. https://jira.sw.ru/browse/PSBM-22993 Signed-off-by: Maxim Patlasov <mpatla...@parallels.com> --- drivers/block/ploop/tracker.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/block/ploop/tracker.c b/drivers/block/ploop/tracker.c index 5dbb7c9..3210006 100644 --- a/drivers/block/ploop/tracker.c +++ b/drivers/block/ploop/tracker.c @@ -101,12 +101,15 @@ int ploop_tracker_init(struct ploop_device * plo, unsigned long arg) if (list_empty(&plo->map.delta_list)) return -ENOENT; + ploop_quiesce(plo); + e.start = 0; e.end = (u64)ploop_top_delta(plo)->io.alloc_head << (plo->cluster_log + 9); - if (copy_to_user((void*)arg, &e, sizeof(struct ploop_track_extent))) + if (copy_to_user((void*)arg, &e, sizeof(struct ploop_track_extent))) { + ploop_relax(plo); return -EFAULT; + } - ploop_quiesce(plo); set_bit(PLOOP_S_TRACK, &plo->state); plo->maintenance_type = PLOOP_MNTN_TRACK; plo->track_end = 0; -- 1.9.3 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel