[Devel] [PATCH RH8 14/14] dm-qcow2: introduce resubmit qios

Kirill Tkhai ktkhai at virtuozzo.com
Tue Jul 27 11:29:55 MSK 2021


Resubmit partially completed IO.

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

diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
index c3706705c465..9d0649a54e2b 100644
--- a/drivers/md/dm-qcow2-map.c
+++ b/drivers/md/dm-qcow2-map.c
@@ -2698,6 +2698,19 @@ static int prepare_backward_merge(struct qcow2 *qcow2, struct qio **qio,
 	return 0;
 }
 
+static void qcow2_queue_resubmit(struct qio *qio)
+{
+	struct qcow2 *qcow2 = qio->qcow2;
+	unsigned long flags;
+
+	qio->queue_list_id = QLIST_INVALID;
+
+	spin_lock_irqsave(&qcow2->deferred_lock, flags);
+	list_add_tail(&qio->link, &qcow2->resubmit_qios);
+	spin_unlock_irqrestore(&qcow2->deferred_lock, flags);
+	queue_work(qcow2->tgt->wq, &qcow2->worker);
+}
+
 static void data_rw_complete(struct qio *qio)
 {
 	bool finalize_wbd = false, call_endio = true;
@@ -2707,9 +2720,15 @@ static void data_rw_complete(struct qio *qio)
 	struct wb_desc *wbd;
 	unsigned long flags;
 
-	/* FIXME: short read/write */
-	if (qio->ret != qio->bi_iter.bi_size)
-		bi_status = BLK_STS_IOERR;
+	if (unlikely(qio->ret != qio->bi_iter.bi_size)) {
+		if (qio->ret >= 0) {
+			WARN_ON_ONCE(qio->ret == 0);
+			qio_advance(qio, qio->ret);
+			qcow2_queue_resubmit(qio);
+			return;
+		}
+		bi_status = errno_to_blk_status(qio->ret);
+	}
 
 	wbd = qio->data;
 	if (wbd) {
@@ -3898,6 +3917,15 @@ next:		qio = qio_list_pop(qio_list);
 		}
 	}
 }
+static void process_resubmit_qios(struct qcow2 *qcow2, struct list_head *qios)
+{
+	struct qio *qio;
+
+	while ((qio = qio_list_pop(qios)) != NULL) {
+		qio->queue_list_id = QLIST_INVALID;
+		submit_rw_mapped(qcow2, qio);
+	}
+}
 
 void do_qcow2_work(struct work_struct *ws)
 {
@@ -3909,6 +3937,7 @@ void do_qcow2_work(struct work_struct *ws)
 	LIST_HEAD(cow_data_qios);
 	LIST_HEAD(cow_indexes_qios);
 	LIST_HEAD(cow_end_qios);
+	LIST_HEAD(resubmit_qios);
 	unsigned int pflags = current->flags;
 
 	current->flags |= PF_LESS_THROTTLE|PF_MEMALLOC_NOIO;
@@ -3920,6 +3949,7 @@ void do_qcow2_work(struct work_struct *ws)
 	list_splice_init(&qcow2->qios[QLIST_COW_DATA], &cow_data_qios);
 	list_splice_init(&qcow2->qios[QLIST_COW_INDEXES], &cow_indexes_qios);
 	list_splice_init(&qcow2->qios[QLIST_COW_END], &cow_end_qios);
+	list_splice_init(&qcow2->resubmit_qios, &resubmit_qios);
 	spin_unlock_irq(&qcow2->deferred_lock);
 
 	process_embedded_qios(qcow2, &embedded_qios, &deferred_qios);
@@ -3929,6 +3959,7 @@ void do_qcow2_work(struct work_struct *ws)
 	process_cow_data_write(qcow2, &cow_data_qios);
 	process_cow_indexes_write(qcow2, &cow_indexes_qios);
 	process_cow_end(qcow2, &cow_end_qios);
+	process_resubmit_qios(qcow2, &resubmit_qios);
 
 	/* This actually submits batch of md writeback, initiated above */
 	submit_metadata_writeback(qcow2);
diff --git a/drivers/md/dm-qcow2-target.c b/drivers/md/dm-qcow2-target.c
index 895b69f0a767..8c878073ac55 100644
--- a/drivers/md/dm-qcow2-target.c
+++ b/drivers/md/dm-qcow2-target.c
@@ -580,6 +580,7 @@ static struct qcow2 *qcow2_alloc_delta(struct qcow2_target *tgt, struct qcow2 *u
 
 	for (i = 0; i < QLIST_COUNT; i++)
 		INIT_LIST_HEAD(&qcow2->qios[i]);
+	INIT_LIST_HEAD(&qcow2->resubmit_qios);
 	INIT_LIST_HEAD(&qcow2->paused_qios);
 	INIT_LIST_HEAD(&qcow2->wb_batch_list);
 	INIT_LIST_HEAD(&qcow2->slow_wb_batch_list);
diff --git a/drivers/md/dm-qcow2.h b/drivers/md/dm-qcow2.h
index 58c6fe48fef0..4fa02eac0e2a 100644
--- a/drivers/md/dm-qcow2.h
+++ b/drivers/md/dm-qcow2.h
@@ -178,6 +178,7 @@ struct qcow2 {
 	spinlock_t md_pages_lock;
 
 	struct list_head qios[QLIST_COUNT];
+	struct list_head resubmit_qios;
 	struct list_head paused_qios; /* For pause_submitting_qios */
 
 	/* For batching md update: */




More information about the Devel mailing list