[RH7,1/4] ploop: Introduce ->fastmap_end_io

Submitted by Kirill Tkhai on Aug. 6, 2020, 11:55 a.m.

Details

Message ID 159671455264.36238.2242174941451373682.stgit@localhost.localdomain
State New
Series "ploop: Protect fastmap against defrag and punch hole"
Headers show

Commit Message

Kirill Tkhai Aug. 6, 2020, 11:55 a.m.
This will be used in kaio to put inode->i_dio_count
after fastmap IO is ended.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 drivers/block/ploop/dev.c   |   25 +++++++++++++++++++++++--
 include/linux/ploop/ploop.h |    8 ++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 6ee315b54fc9..5f1a0c289a26 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -692,10 +692,18 @@  static struct ploop_delta * find_delta(struct ploop_device * plo, int level)
 DEFINE_BIO_CB(ploop_fast_end_io)
 {
 	unsigned long flags;
+	struct ploop_delta * delta;
 	struct ploop_device * plo;
 	struct bio * orig = bio->bi_private;
 
-	plo = orig->bi_bdev->bd_disk->private_data;
+	/* Assigned in bio_fast_map() */
+	delta = (void *)orig->bi_next;
+	orig->bi_next = NULL;
+
+	if (delta->io.ops->fastmap_end_io)
+		delta->io.ops->fastmap_end_io(&delta->io, orig);
+
+	plo = delta->plo;
 
 	/* End of fast bio wakes up main process only when this could
 	 * mean exit from ATTENTION state.
@@ -774,6 +782,7 @@  bio_fast_map(struct ploop_device * plo, struct bio * orig_bio, struct bio * bio)
 {
 	struct ploop_delta * delta;
 	sector_t isector;
+	int ret;
 
 	if (orig_bio->bi_size == 0)
 		delta = ploop_top_delta(plo);
@@ -788,7 +797,19 @@  bio_fast_map(struct ploop_device * plo, struct bio * orig_bio, struct bio * bio)
 	if (delta->io.ops->fastmap == NULL)
 		return 1;
 
-	return delta->io.ops->fastmap(&delta->io, orig_bio, bio, isector);
+	ret = delta->io.ops->fastmap(&delta->io, orig_bio, bio, isector);
+
+	if (ret)
+		return 1;
+
+	/*
+	 * We reuse orig_bio->bi_next for a while.
+	 * ploop_fast_end_io() nullifies it back.
+	 */
+	BUG_ON(orig_bio->bi_next);
+	orig_bio->bi_next = (void *)delta;
+
+	return 0;
 }
 
 static inline unsigned int block_vecs(struct ploop_device * plo)
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index 0ea069abd40a..3e1b59ea7881 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -165,8 +165,16 @@  struct ploop_io_ops
 	void	(*post_submit)(struct ploop_io *, struct ploop_request *);
 
 	int	(*disable_merge)(struct ploop_io * io, sector_t isector, unsigned int len);
+
+	/*
+	 * fastmap maps @isec to the sector on the underlining device.
+	 * Before ->fastmap_end_io is called the mapper sector is stable.
+	 * I.e., fastmap works as opening protection bracket,
+	 * while fastmap_end_io is closing protection bracket.
+	 */
 	int	(*fastmap)(struct ploop_io * io, struct bio *orig_bio,
 			   struct bio * bio, sector_t isec);
+	void	(*fastmap_end_io)(struct ploop_io *io, struct bio *orig_bio);
 
 	void	(*read_page)(struct ploop_io * io, struct ploop_request * preq,
 			     struct page * page, sector_t sec);