[Devel] [PATCH RHEL7 COMMIT] ploop: fix a race condition on relocation of blocks

Konstantin Khorenko khorenko at odin.com
Mon May 18 21:27:02 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.1
------>
commit a762247cf8ff0b2ec0ba6e8a9742f7a5e38a8b15
Author: Andrey Smetanin <asmetanin at virtuozzo.com>
Date:   Tue May 19 08:27:02 2015 +0400

    ploop: fix a race condition on relocation of blocks
    
    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;



More information about the Devel mailing list