[Devel] [PATCH RH8 18/18] ploop: Introduce resubmitting partially completed pios

Kirill Tkhai ktkhai at virtuozzo.com
Wed Jun 16 18:47:51 MSK 2021


In case of a part of pio was written or read,
we continue its submitting in next iteration.
This will allow to handle ENOSPC in appropriate
way in the future.

Note, that the best place for resubmitting code
is in main kwork, but we can't place it there,
while BAT write is synchronuos.

https://jira.sw.ru/browse/PSBM-127225

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 drivers/md/dm-ploop-map.c    |   46 ++++++++++++++++++++++++++++++++++++++++--
 drivers/md/dm-ploop-target.c |    1 +
 drivers/md/dm-ploop.h        |    1 +
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 4cb4ebe37f6e..6ba547626b20 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -1000,12 +1000,33 @@ static bool ploop_attach_end_action(struct pio *pio, struct ploop_index_wb *piwb
 	return true;
 }
 
+static void ploop_queue_resubmit(struct pio *pio)
+{
+	struct ploop *ploop = pio->ploop;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ploop->deferred_lock, flags);
+	list_add_tail(&pio->list, &ploop->resubmit_pios);
+	spin_unlock_irqrestore(&ploop->deferred_lock, flags);
+
+	queue_work(ploop->wq, &ploop->fsync_worker);
+}
+
 static void data_rw_complete(struct pio *pio)
 {
 	bool completed;
 
-	if (pio->ret != pio->bi_iter.bi_size)
-                pio->bi_status = BLK_STS_IOERR;
+	if (pio->ret != pio->bi_iter.bi_size) {
+		if (pio->ret >= 0) {
+			/* Partial IO */
+			WARN_ON_ONCE(pio->ret == 0);
+			pio_advance(pio, pio->ret);
+			ploop_queue_resubmit(pio);
+			return;
+		}
+
+                pio->bi_status = errno_to_blk_status(pio->ret);
+	}
 
 	if (pio->is_data_alloc) {
 		completed = ploop_data_pio_end(pio);
@@ -1016,6 +1037,11 @@ static void data_rw_complete(struct pio *pio)
 	pio_endio(pio);
 }
 
+/*
+ * XXX: Keep in mind, data_rw_complete may queue resubmit after partial IO.
+ * Don't use this function from fsync kwork in case of the caller blocks
+ * to wait for completion, since kwork is who resubmits after partial IO.
+ */
 static void submit_rw_mapped(struct ploop *ploop, struct pio *pio)
 {
 	unsigned int rw, nr_segs;
@@ -1466,6 +1492,14 @@ static void process_discard_pios(struct ploop *ploop, struct list_head *pios,
 		process_one_discard_pio(ploop, pio, piwb);
 }
 
+static void process_resubmit_pios(struct ploop *ploop, struct list_head *pios)
+{
+	struct pio *pio;
+
+	while ((pio = pio_list_pop(pios)) != NULL)
+		submit_rw_mapped(ploop, pio);
+}
+
 void do_ploop_work(struct work_struct *ws)
 {
 	struct ploop *ploop = container_of(ws, struct ploop, worker);
@@ -1511,6 +1545,7 @@ void do_ploop_work(struct work_struct *ws)
 void do_ploop_fsync_work(struct work_struct *ws)
 {
 	struct ploop *ploop = container_of(ws, struct ploop, fsync_worker);
+	LIST_HEAD(resubmit_pios);
 	LIST_HEAD(flush_pios);
 	struct file *file;
 	struct pio *pio;
@@ -1518,8 +1553,15 @@ void do_ploop_fsync_work(struct work_struct *ws)
 
 	spin_lock_irq(&ploop->deferred_lock);
 	list_splice_init(&ploop->flush_pios, &flush_pios);
+	list_splice_init(&ploop->resubmit_pios, &resubmit_pios);
 	spin_unlock_irq(&ploop->deferred_lock);
 
+	/*
+	 * FIXME: move this to main kwork, after BAT write
+	 * will be made async.
+	 */
+	process_resubmit_pios(ploop, &resubmit_pios);
+
 	file = top_delta(ploop)->file;
 	ret = vfs_fsync(file, 0);
 
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index 9e173f5d8d0c..5b2235319f1c 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -309,6 +309,7 @@ static int ploop_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 	INIT_LIST_HEAD(&ploop->deferred_pios);
 	INIT_LIST_HEAD(&ploop->flush_pios);
 	INIT_LIST_HEAD(&ploop->discard_pios);
+	INIT_LIST_HEAD(&ploop->resubmit_pios);
 	INIT_LIST_HEAD(&ploop->cluster_lk_list);
 	INIT_LIST_HEAD(&ploop->delta_cow_action_list);
 	ploop->bat_entries = RB_ROOT;
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 533249d8eea8..fe387c981c2c 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -170,6 +170,7 @@ struct ploop {
 	struct list_head deferred_pios;
 	struct list_head flush_pios;
 	struct list_head discard_pios;
+	struct list_head resubmit_pios; /* After partial IO */
 
 	struct rw_semaphore ctl_rwsem;
 	struct ploop_cmd *deferred_cmd;




More information about the Devel mailing list