[Devel] [PATCH rh7 8/9] ploop: fix barriers for PLOOP_E_RELOC_NULLIFY

Maxim Patlasov mpatlasov at virtuozzo.com
Thu Jun 23 22:41:36 PDT 2016


The last step of processing of RELOC_A request is
nullifying BAT block. We smartly noticed, that flush
needed after that, but fsync is not enough:

> 	/*
> 	 * Lately we think we does sync of nullified blocks at format
> 	 * driver by image fsync before header update.
> 	 * But we write this data directly into underlying device
> 	 * bypassing EXT4 by usage of extent map tree
> 	 * (see dio_submit()). So fsync of EXT4 image doesnt help us.
> 	 * We need to force sync of nullified blocks.
> 	 */
> 	set_bit(PLOOP_REQ_FORCE_FUA, &preq->state);
> 	top_delta->io.ops->submit(&top_delta->io, preq, preq->req_rw,
> 				  &sbl, preq->iblock, 1<<plo->cluster_log);

Unfortunately, the way how we handle FORCE_FUA in dio_submit
(sending last bio with REQ_FUA bit set) is not safe: firstly because
we decided that ploop shouldn't strongly rely on the assumption of
equivalence of REQ_FUA and post-FLUSH; and secondly because dio_submit
cannot ensure that that last bio marked as REQ_FUA won't be actually
processed before others.

To fix this problem the patch makes explicit ->issue_flush to flush
nullified block.

Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
---
 drivers/block/ploop/dev.c       |   11 ++++++++++-
 drivers/block/ploop/io_direct.c |    3 ++-
 drivers/block/ploop/map.c       |    4 +++-
 include/linux/ploop/ploop.h     |    1 +
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 557ddba..2b60dfa 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -1305,6 +1305,8 @@ static void ploop_complete_request(struct ploop_request * preq)
 	}
 	preq->bl.tail = NULL;
 
+	WARN_ON(!preq->error && test_bit(PLOOP_REQ_ISSUE_FLUSH, &preq->state));
+
 	if (test_bit(PLOOP_REQ_RELOC_A, &preq->state) ||
 	    test_bit(PLOOP_REQ_RELOC_S, &preq->state)) {
 		if (preq->error)
@@ -2429,6 +2431,13 @@ static void ploop_req_state_process(struct ploop_request * preq)
 		preq->eng_io = NULL;
 	}
 
+	if (test_bit(PLOOP_REQ_ISSUE_FLUSH, &preq->state)) {
+		preq->eng_io->ops->issue_flush(preq->eng_io, preq);
+		clear_bit(PLOOP_REQ_ISSUE_FLUSH, &preq->state);
+		preq->eng_io = NULL;
+		goto out;
+	}
+
 restart:
 	BUG_ON(test_bit(PLOOP_REQ_POST_SUBMIT, &preq->state));
 	__TRACE("ST %p %u %lu\n", preq, preq->req_cluster, preq->eng_state);
@@ -2705,7 +2714,7 @@ restart:
 	default:
 		BUG();
 	}
-
+out:
 	if (release_ioc) {
 		struct io_context * ioc = current->io_context;
 		current->io_context = saved_ioc;
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index 94936c7..c4d0f63 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -413,6 +413,7 @@ try_again:
 
 		preq->iblock = iblk;
 		preq->eng_io = io;
+		BUG_ON(test_bit(PLOOP_REQ_ISSUE_FLUSH, &preq->state));
 		set_bit(PLOOP_REQ_POST_SUBMIT, &preq->state);
 		dio_submit_pad(io, preq, sbl, size, em);
 		err = 0;
@@ -1819,7 +1820,7 @@ static void dio_issue_flush(struct ploop_io * io, struct ploop_request *preq)
 
 	atomic_inc(&preq->io_count);
 	ploop_acc_ff_out(io->plo, preq->req_rw | bio->bi_rw);
-	submit_bio(preq->req_rw, bio);
+	submit_bio(WRITE_FLUSH, bio);
 	ploop_complete_io_request(preq);
 }
 
diff --git a/drivers/block/ploop/map.c b/drivers/block/ploop/map.c
index f87fb08..915a216 100644
--- a/drivers/block/ploop/map.c
+++ b/drivers/block/ploop/map.c
@@ -1077,7 +1077,9 @@ static void map_wb_complete_post_process(struct ploop_map *map,
 	 * (see dio_submit()). So fsync of EXT4 image doesnt help us.
 	 * We need to force sync of nullified blocks.
 	 */
-	set_bit(PLOOP_REQ_FORCE_FUA, &preq->state);
+	preq->eng_io = &top_delta->io;
+	BUG_ON(test_bit(PLOOP_REQ_POST_SUBMIT, &preq->state));
+	set_bit(PLOOP_REQ_ISSUE_FLUSH, &preq->state);
 	top_delta->io.ops->submit(&top_delta->io, preq, preq->req_rw,
 				  &sbl, preq->iblock, 1<<plo->cluster_log);
 }
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index af222f1..920daf7 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -479,6 +479,7 @@ enum
 	PLOOP_REQ_POST_SUBMIT, /* preq needs post_submit processing */
 	PLOOP_REQ_PUSH_BACKUP, /* preq was ACKed by userspace push_backup */
 	PLOOP_REQ_FSYNC_DONE,  /* fsync_thread() performed f_op->fsync() */
+	PLOOP_REQ_ISSUE_FLUSH, /* preq needs ->issue_flush before completing */
 };
 
 #define PLOOP_REQ_MERGE_FL (1 << PLOOP_REQ_MERGE)



More information about the Devel mailing list