[Devel] [PATCH RH8 10/61] ploop: Kill bat_bio

Kirill Tkhai ktkhai at virtuozzo.com
Fri May 14 18:55:30 MSK 2021


Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 drivers/md/dm-ploop-cmd.c    |    5 +++
 drivers/md/dm-ploop-map.c    |   77 +++++++++++++++++-------------------------
 drivers/md/dm-ploop-target.c |    4 +-
 drivers/md/dm-ploop.h        |    3 +-
 4 files changed, 40 insertions(+), 49 deletions(-)

diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index d49d346b9de8..07e69fc0ed01 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -213,6 +213,11 @@ void bio_prepare_offsets(struct ploop *ploop, struct bio *bio,
 	bio->bi_iter.bi_size = 1 << (cluster_log + 9);
 }
 
+static int rw_pages_sync(int rw, struct file *file, u64 page_id, void *data)
+{
+	return 0;
+}
+
 static int ploop_read_cluster_sync(struct ploop *ploop, struct ploop_bvec *pvec,
 				   unsigned int dst_cluster)
 {
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 518075645ed9..8b60d200d729 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -72,7 +72,6 @@ static void ploop_index_wb_init(struct ploop_index_wb *piwb, struct ploop *ploop
 	init_completion(&piwb->comp);
 	spin_lock_init(&piwb->lock);
 	piwb->bat_page = NULL;
-	piwb->bat_bio = NULL;
 	piwb->bi_status = 0;
 	bio_list_init(&piwb->ready_data_bios);
 	bio_list_init(&piwb->cow_list);
@@ -144,6 +143,16 @@ void defer_bios(struct ploop *ploop, struct bio *bio, struct bio_list *bl)
 	queue_work(ploop->wq, &ploop->worker);
 }
 
+void track_dst_cluster(struct ploop *ploop, u32 dst_cluster)
+{
+	unsigned long flags;
+
+	read_lock_irqsave(&ploop->bat_rwlock, flags);
+	if (ploop->tracking_bitmap && !WARN_ON(dst_cluster >= ploop->tb_nr))
+		set_bit(dst_cluster, ploop->tracking_bitmap);
+	read_unlock_irqrestore(&ploop->bat_rwlock, flags);
+}
+
 /*
  * Userspace calls dm_suspend() to get changed blocks finally.
  * dm_suspend() waits for dm's inflight bios, so this function
@@ -155,17 +164,13 @@ void defer_bios(struct ploop *ploop, struct bio *bio, struct bio_list *bl)
 void __track_bio(struct ploop *ploop, struct bio *bio)
 {
 	unsigned int dst_cluster = bio->bi_iter.bi_sector >> ploop->cluster_log;
-	unsigned long flags;
 
 	if (!op_is_write(bio->bi_opf) || !bio_sectors(bio))
 		return;
 
 	WARN_ON_ONCE(bio->bi_disk != ploop->origin_dev->bdev->bd_disk);
 
-	read_lock_irqsave(&ploop->bat_rwlock, flags);
-	if (ploop->tracking_bitmap && !WARN_ON(dst_cluster >= ploop->tb_nr))
-		set_bit(dst_cluster, ploop->tracking_bitmap);
-	read_unlock_irqrestore(&ploop->bat_rwlock, flags);
+	track_dst_cluster(ploop, dst_cluster);
 }
 
 static void queue_discard_index_wb(struct ploop *ploop, struct bio *bio)
@@ -667,17 +672,15 @@ static void put_piwb(struct ploop_index_wb *piwb)
 }
 
 /* This handler is called after BAT is updated. */
-static void ploop_bat_write_complete(struct bio *bio)
+static void ploop_bat_write_complete(struct ploop_index_wb *piwb,
+				     blk_status_t bi_status)
 {
-	struct ploop_index_wb *piwb = bio->bi_private;
 	struct bio *data_bio, *cluster_bio;
 	struct ploop *ploop = piwb->ploop;
 	struct ploop_cow *cow;
 	unsigned long flags;
 
-	track_bio(ploop, bio);
-
-	if (!bio->bi_status) {
+	if (!bi_status) {
 		/*
 		 * Success: now update local BAT copy. We could do this
 		 * from our delayed work, but we want to publish new
@@ -691,7 +694,7 @@ static void ploop_bat_write_complete(struct bio *bio)
 
 	spin_lock_irqsave(&piwb->lock, flags);
 	piwb->completed = true;
-	piwb->bi_status = bio->bi_status;
+	piwb->bi_status = bi_status;
 	spin_unlock_irqrestore(&piwb->lock, flags);
 
 	/*
@@ -699,15 +702,15 @@ static void ploop_bat_write_complete(struct bio *bio)
 	 * add a new element after piwc->completed is true.
 	 */
 	while ((data_bio = bio_list_pop(&piwb->ready_data_bios))) {
-		if (bio->bi_status)
-			data_bio->bi_status = bio->bi_status;
+		if (bi_status)
+			data_bio->bi_status = bi_status;
 		if (data_bio->bi_end_io)
 			data_bio->bi_end_io(data_bio);
 	}
 
 	while ((cluster_bio = bio_list_pop(&piwb->cow_list))) {
 		cow = cluster_bio->bi_private;
-		complete_cow(cow, bio->bi_status);
+		complete_cow(cow, bi_status);
 	}
 
 	/*
@@ -724,19 +727,11 @@ static int ploop_prepare_bat_update(struct ploop *ploop, unsigned int page_nr,
 	bool is_last_page = true;
 	struct md_page *md;
 	struct page *page;
-	struct bio *bio;
 	map_index_t *to;
-	sector_t sector;
 
 	piwb->bat_page = page = alloc_page(GFP_NOIO);
 	if (!page)
 		return -ENOMEM;
-	piwb->bat_bio = bio = bio_alloc(GFP_NOIO, 1);
-	if (!bio) {
-		put_page(page);
-		piwb->bat_page = NULL;
-		return -ENOMEM;
-	}
 
 	md = md_page_find(ploop, page_nr);
 	BUG_ON(!md);
@@ -774,16 +769,6 @@ static int ploop_prepare_bat_update(struct ploop *ploop, unsigned int page_nr,
 
 	kunmap_atomic(to);
 	kunmap_atomic(bat_entries);
-
-	sector = (page_nr * PAGE_SIZE) >> SECTOR_SHIFT;
-	bio->bi_iter.bi_sector = sector;
-	remap_to_origin(ploop, bio);
-
-	bio->bi_private = piwb;
-	bio->bi_end_io = ploop_bat_write_complete;
-	bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_SYNC | REQ_FUA | REQ_PREFLUSH);
-	bio_add_page(bio, page, PAGE_SIZE, 0);
-
 	return 0;
 }
 
@@ -792,7 +777,6 @@ void ploop_reset_bat_update(struct ploop_index_wb *piwb)
 	struct ploop *ploop = piwb->ploop;
 
 	put_page(piwb->bat_page);
-	bio_put(piwb->bat_bio);
 	ploop_index_wb_init(piwb, ploop);
 }
 
@@ -1415,21 +1399,22 @@ static int process_one_deferred_bio(struct ploop *ploop, struct bio *bio,
 void ploop_submit_index_wb_sync(struct ploop *ploop,
 				struct ploop_index_wb *piwb)
 {
-	struct block_device *bdev = ploop->origin_dev->bdev;
+	blk_status_t status = BLK_STS_OK;
+	u32 dst_cluster;
+	int ret;
 
 	/* track_bio() will be called in ploop_bat_write_complete() */
-	submit_bio(piwb->bat_bio);
-	wait_for_completion(&piwb->comp);
 
-	if (!blk_queue_fua(bdev_get_queue(bdev))) {
-		/*
-		 * Error here does not mean that cluster write is failed,
-		 * since ploop_map() could submit more bios in parallel.
-		 * But it's not possible to differ them. Should we block
-		 * ploop_map() during we do this?
-		 */
-		WARN_ON(blkdev_issue_flush(bdev, GFP_NOIO, NULL));
-	}
+	ret = rw_page_sync(WRITE, top_delta(ploop)->file,
+			   piwb->page_nr, piwb->bat_page);
+	if (ret)
+		status = errno_to_blk_status(ret);
+
+	dst_cluster = ((u64)piwb->page_nr << PAGE_SHIFT) / to_bytes(1 << ploop->cluster_log);
+	track_dst_cluster(ploop, dst_cluster);
+
+	ploop_bat_write_complete(piwb, status);
+	wait_for_completion(&piwb->comp);
 }
 
 static void process_deferred_bios(struct ploop *ploop, struct bio_list *bios,
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index 5797ff2660cd..4b02b8a2da4b 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -66,8 +66,8 @@ void call_rw_iter(struct file *file, loff_t pos, unsigned rw,
 		iocb->ki_complete(iocb, ret, 0);
 }
 
-static int rw_page_sync(unsigned rw, struct file *file,
-			u64 index, struct page *page)
+int rw_page_sync(unsigned rw, struct file *file,
+		 u64 index, struct page *page)
 {
 	struct bio_vec *bvec, bvec_on_stack;
 	struct iov_iter iter;
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 63a860bc84c8..a42c9d603df4 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -119,7 +119,6 @@ struct ploop_index_wb {
 	enum piwb_type type;
 	spinlock_t lock;
 	struct page *bat_page;
-	struct bio *bat_bio;
 	struct bio_list ready_data_bios;
 	struct bio_list cow_list;
 	atomic_t count;
@@ -510,6 +509,8 @@ extern struct pio *find_lk_of_cluster(struct ploop *ploop, u32 cluster);
 extern void unlink_postponed_backup_endio(struct ploop *ploop,
 					  struct bio_list *bio_list,
 					  struct pio *h);
+extern int rw_page_sync(unsigned rw, struct file *file,
+			u64 index, struct page *page);
 
 extern int ploop_prepare_reloc_index_wb(struct ploop *, struct ploop_index_wb *,
 					unsigned int, unsigned int *);




More information about the Devel mailing list