submit_alloc may change alloc_head in parallel,
and this may lead to data corruption, when we
read inode size before submit_alloc and update
the size after submit_alloc.

[This may be added to RK too].

Signed-off-by: Kirill Tkhai <[email protected]>
---
 drivers/block/ploop/dev.c        |    5 +++++
 drivers/block/ploop/fmt_ploop1.c |    4 ++++
 2 files changed, 9 insertions(+)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 8b74fe03f17f..32583c187fdb 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -3792,6 +3792,11 @@ static void ploop_merge_complete(struct ploop_device * 
plo,
        ploop_relax(plo);
 }
 
+/*
+ * Calls format and io callbacks. Should not be called
+ * in quiesce state, since it may enter quiesce state
+ * itself (in fmt_prepare_merge callback).
+ */
 static int ploop_prepare_merge(struct ploop_delta *next,
                               struct ploop_snapdata *sd)
 {
diff --git a/drivers/block/ploop/fmt_ploop1.c b/drivers/block/ploop/fmt_ploop1.c
index 4846d96232b8..120d118aecbd 100644
--- a/drivers/block/ploop/fmt_ploop1.c
+++ b/drivers/block/ploop/fmt_ploop1.c
@@ -502,6 +502,7 @@ ploop1_prepare_merge(struct ploop_delta * delta, struct 
ploop_snapdata * sd)
        int err;
        struct ploop_pvd_header *vh;
        struct ploop1_private * ph = delta->priv;
+       struct ploop_device *plo = delta->plo;
 
        vh = (struct ploop_pvd_header *)page_address(ph->dyn_page);
 
@@ -512,9 +513,12 @@ ploop1_prepare_merge(struct ploop_delta * delta, struct 
ploop_snapdata * sd)
        if (pvd_header_is_disk_in_use(vh))
                return -EBUSY;
 
+       /* Close race with submit_alloc */
+       ploop_quiesce(plo);
        ph->alloc_head = delta->io.ops->i_size_read(&delta->io) >>
                         (delta->io.plo->cluster_log + 9);
        delta->io.alloc_head = ph->alloc_head;
+       ploop_relax(plo);
 
        return 0;
 }

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to