[Devel] [PATCH rh7] ploop: Delay reusing cluster on discard till previous index flushed

Kirill Tkhai ktkhai at virtuozzo.com
Thu Feb 20 16:09:43 MSK 2020


There is a race window, when previous index is not guaranteed
to be zeroed, while we already reuse the cluster it pointed before.
This may results in two indexes point to the same cluster after
node crash.

Fix that by moving cluster into free clusters pool one stage later.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 drivers/block/ploop/fmt_ploop1.c |    4 ++++
 drivers/block/ploop/map.c        |    9 +++------
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/block/ploop/fmt_ploop1.c b/drivers/block/ploop/fmt_ploop1.c
index 806f020f0bb7..952db7c12cc5 100644
--- a/drivers/block/ploop/fmt_ploop1.c
+++ b/drivers/block/ploop/fmt_ploop1.c
@@ -865,6 +865,10 @@ static void ploop1_add_free_blk(struct ploop_delta *delta, struct ploop_request
 	if (!delta->holes_bitmap)
 		return;
 
+	if (!(preq->req_rw & REQ_DISCARD) ||
+	    test_bit(PLOOP_REQ_DISCARD, &preq->state))
+		return;
+
 	idx = (preq->req_cluster + PLOOP_MAP_OFFSET) & (INDEX_PER_PAGE - 1);
 	blk = ((map_index_t *)page_address(m->page))[idx];
 
diff --git a/drivers/block/ploop/map.c b/drivers/block/ploop/map.c
index 99b1eb735469..f6a38e40d8c4 100644
--- a/drivers/block/ploop/map.c
+++ b/drivers/block/ploop/map.c
@@ -962,9 +962,6 @@ void ploop_index_update(struct ploop_request * preq)
 
 	copy_index_for_wb(page, m, top_delta->level);
 
-	if (!preq->iblock)
-		top_delta->ops->add_free_blk(top_delta, preq);
-
 	((map_index_t*)page_address(page))[idx] = preq->iblock << ploop_map_log(plo);
 
 	get_page(page);
@@ -1108,6 +1105,9 @@ static void map_wb_complete(struct map_node * m, int err)
 							      list);
 				}
 
+				if (!pr->iblock)
+					top_delta->ops->add_free_blk(top_delta, pr);
+
 				if (m->levels &&  m->levels[idx] != top_delta->level) {
 					spin_lock_irq(&plo->lock);
 					do_levels_update = 1;
@@ -1189,9 +1189,6 @@ static void map_wb_complete(struct map_node * m, int err)
 			preq->sinfo.wi.tpage = page;
 			idx = (preq->req_cluster + PLOOP_MAP_OFFSET) & (INDEX_PER_PAGE - 1);
 
-			if (!preq->iblock)
-				top_delta->ops->add_free_blk(top_delta, preq);
-
 			((map_index_t*)page_address(page))[idx] = preq->iblock << ploop_map_log(plo);
 
 			if (!main_preq) {




More information about the Devel mailing list