[Devel] [PATCH rh7 13/38] ploop: fix a race condition on relocation of blocks

Andrey Smetanin asmetanin at virtuozzo.com
Fri May 15 09:48:14 PDT 2015


map_release() are not atomic, because it calls atomic_read
and atomic_dec_and_test. Looks like it was designed to be
called under plo->lock.

https://jira.sw.ru/browse/PSBM-23905

Signed-off-by: Andrey Vagin <avagin at openvz.org>
Acked-by: Maxim Patlasov <mpatlasov at parallels.com>
---
 drivers/block/ploop/dev.c | 6 ++++++
 drivers/block/ploop/map.c | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 353fb35..e3422d8 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -1471,12 +1471,14 @@ static int prepare_merge_req(struct ploop_request * preq)
 	return res;
 
 drop_map:
+	spin_lock_irq(&plo->lock);
 	map_release(preq->trans_map);
 	preq->trans_map = NULL;
 	if (preq->map) {
 		map_release(preq->map);
 		preq->map = NULL;
 	}
+	spin_unlock_irq(&plo->lock);
 	return 1;
 }
 
@@ -1688,8 +1690,10 @@ ploop_entry_reloc_a_req(struct ploop_request *preq, iblock_t *iblk)
 		if (*clu <= MAP_MAX_IND(preq))
 			break;
 
+		spin_lock_irq(&plo->lock);
 		map_release(preq->map);
 		preq->map = NULL;
+		spin_unlock_irq(&plo->lock);
 	}
 
 	if (*clu >= plo->map.max_index) {
@@ -1814,8 +1818,10 @@ static int discard_get_index(struct ploop_request *preq)
 		preq->iblock = 0;
 
 	if (preq->map) {
+		spin_lock_irq(&plo->lock);
 		map_release(preq->map);
 		preq->map = NULL;
+		spin_unlock_irq(&plo->lock);
 	}
 
 	return 0;
diff --git a/drivers/block/ploop/map.c b/drivers/block/ploop/map.c
index 5f50f81..2e971cd 100644
--- a/drivers/block/ploop/map.c
+++ b/drivers/block/ploop/map.c
@@ -145,6 +145,10 @@ static void flush_lru_buffer(struct ploop_map * map)
 	map->lru_buffer_ptr = 0;
 }
 
+/*
+ * map_release() must be called under plo-lock, because
+ * The pair atomic_read & atomic_dec_and_test is not atomic.
+ */
 void map_release(struct map_node * m)
 {
 	struct ploop_map * map = m->parent;
@@ -1026,9 +1030,11 @@ static void map_wb_complete_post_process(struct ploop_map *map,
 	}
 
 	if (test_bit(PLOOP_REQ_RELOC_S, &preq->state)) {
+		spin_lock_irq(&plo->lock);
 		del_lockout(preq);
 		map_release(preq->map);
 		preq->map = NULL;
+		spin_unlock_irq(&plo->lock);
 
 		requeue_req(preq, PLOOP_E_RELOC_COMPLETE);
 		return;
-- 
1.9.3




More information about the Devel mailing list