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
