[Devel] [PATCH rh7 15/38] ploop: fix race in ploop_tracker_init()
Andrey Smetanin
asmetanin at virtuozzo.com
Fri May 15 09:48:16 PDT 2015
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 <MPatlasov at 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
More information about the Devel
mailing list