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 <asmeta...@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 <ava...@openvz.org>
    
    Acked-by: Maxim Patlasov <mpatla...@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;
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to