[Devel] [PATCH RHEL7 COMMIT] ploop: Delay reusing cluster on discard till previous index flushed
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Feb 27 17:41:20 MSK 2020
The commit is pushed to "branch-rh7-3.10.0-1062.12.1.vz7.131.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1062.12.1.vz7.131.4
------>
commit c7d428f3a7d83e75899ac97cbac7e2e77640e7cb
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date: Thu Feb 20 16:09:43 2020 +0300
ploop: Delay reusing cluster on discard till previous index flushed
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>
v2: WARN_ON added as we don't expect ploop1_add_free_blk() is ever
called in "maintenance" mode or upon non-discard ploop request.
---
drivers/block/ploop/fmt_ploop1.c | 6 ++++++
drivers/block/ploop/map.c | 9 +++------
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/block/ploop/fmt_ploop1.c b/drivers/block/ploop/fmt_ploop1.c
index 806f020f0bb7d..40e24a31689b0 100644
--- a/drivers/block/ploop/fmt_ploop1.c
+++ b/drivers/block/ploop/fmt_ploop1.c
@@ -865,6 +865,12 @@ 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)) {
+ WARN_ON_ONCE(1);
+ 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 99b1eb7354691..f6a38e40d8c45 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