[Devel] [PATCH vz9 v1 48/63] dm-ploop: use filp per thread

Alexander Atanasov alexander.atanasov at virtuozzo.com
Fri Jan 24 18:36:22 MSK 2025


For some reason this fixed xfs issues .
I do not know why yet.
To be investigated. And probably reverted.

https://virtuozzo.atlassian.net/browse/VSTOR-91821
Signed-off-by: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
---
 drivers/md/dm-ploop-bat.c    | 15 ++++++++++++-
 drivers/md/dm-ploop-cmd.c    |  6 ++++--
 drivers/md/dm-ploop-map.c    | 41 ++++++++++++++++++++++--------------
 drivers/md/dm-ploop-target.c |  8 +++++++
 drivers/md/dm-ploop.h        |  7 +++++-
 5 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/drivers/md/dm-ploop-bat.c b/drivers/md/dm-ploop-bat.c
index afbd43d74c6a..88b1d02b47d5 100644
--- a/drivers/md/dm-ploop-bat.c
+++ b/drivers/md/dm-ploop-bat.c
@@ -482,7 +482,7 @@ int ploop_add_delta(struct ploop *ploop, u32 level, struct file *file, bool is_r
 	struct rb_root md_root = RB_ROOT;
 	loff_t file_size;
 	u32 nr_be;
-	int ret;
+	int ret, i;
 
 	ret = ploop_check_delta_length(ploop, file, &file_size);
 	if (ret)
@@ -503,6 +503,19 @@ int ploop_add_delta(struct ploop *ploop, u32 level, struct file *file, bool is_r
 	ploop_apply_delta_mappings(ploop, deltas, level, &md_root, nr_be);
 
 	deltas[level].file = file;
+	deltas[level].mtfile = kcalloc(ploop->nkt_runners, sizeof(*file),
+					GFP_KERNEL);
+	if (!deltas[level].mtfile) {
+		ret = ENOMEM;
+		goto out;
+	}
+	for (i = 0; i < ploop->nkt_runners; i++) {
+		deltas[level].mtfile[i] = file_clone_open(file);
+		if (!deltas[level].mtfile[i]) {
+			ret = ENOMEM;
+			goto out;
+		}
+	}
 	deltas[level].file_size = file_size;
 	deltas[level].file_preallocated_area_start = file_size;
 	deltas[level].nr_be = nr_be;
diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index e080d6afaa7f..50a23212270d 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -316,7 +316,8 @@ static int ploop_grow_relocate_cluster(struct ploop *ploop,
 	}
 
 	spin_lock_irq(&ploop->bat_lock);
-	ret = ploop_prepare_reloc_index_wb(ploop, &md, clu, &new_dst);
+	ret = ploop_prepare_reloc_index_wb(ploop, &md, clu, &new_dst,
+					   ploop_top_delta(ploop)->file);
 	spin_unlock_irq(&ploop->bat_lock);
 	if (ret < 0) {
 		PL_ERR("reloc: can't prepare it: %d", ret);
@@ -380,7 +381,8 @@ static int ploop_grow_update_header(struct ploop *ploop,
 	int ret;
 
 	/* hdr is in the same page as bat_entries[0] index */
-	ret = ploop_prepare_reloc_index_wb(ploop, &md, 0, NULL);
+	ret = ploop_prepare_reloc_index_wb(ploop, &md, 0, NULL,
+					   ploop_top_delta(ploop)->file);
 	if (ret)
 		return ret;
 	piwb = md->piwb;
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 4b4facc79aba..7d531564b24c 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -75,6 +75,7 @@ void ploop_index_wb_init(struct ploop_index_wb *piwb, struct ploop *ploop)
 
 void ploop_init_pio(struct ploop *ploop, unsigned int bi_op, struct pio *pio)
 {
+	pio->runner_id = 0;
 	pio->ploop = ploop;
 	pio->css = NULL;
 	pio->bi_op = bi_op;
@@ -694,7 +695,7 @@ static int ploop_handle_discard_pio(struct ploop *ploop, struct pio *pio,
 punch_hole:
 	ploop_remap_to_cluster(ploop, pio, dst_clu);
 	pos = to_bytes(pio->bi_iter.bi_sector);
-	ret = ploop_punch_hole(ploop_top_delta(ploop)->file, pos,
+	ret = ploop_punch_hole(ploop_top_delta(ploop)->mtfile[pio->runner_id], pos,
 			       pio->bi_iter.bi_size);
 	if (ret || ploop->nr_deltas != 1) {
 		if (ret)
@@ -1080,9 +1081,9 @@ ALLOW_ERROR_INJECTION(ploop_find_dst_clu_bit, ERRNO);
 
 static int ploop_truncate_prealloc_safe(struct ploop *ploop,
 					struct ploop_delta *delta,
-					loff_t len, const char *func)
+					loff_t len, struct file *file,
+					const char *func)
 {
-	struct file *file = delta->file;
 	loff_t old_len = delta->file_size;
 	loff_t new_len = len;
 	int ret;
@@ -1106,12 +1107,11 @@ static int ploop_truncate_prealloc_safe(struct ploop *ploop,
 }
 ALLOW_ERROR_INJECTION(ploop_truncate_prealloc_safe, ERRNO);
 
-static int ploop_allocate_cluster(struct ploop *ploop, u32 *dst_clu)
+static int ploop_allocate_cluster(struct ploop *ploop, u32 *dst_clu, struct file *file)
 {
 	struct ploop_delta *top = ploop_top_delta(ploop);
 	u32 clu_size = CLU_SIZE(ploop);
 	loff_t off, pos, end, old_size;
-	struct file *file = top->file;
 	unsigned long flags;
 	int ret;
 
@@ -1156,7 +1156,7 @@ static int ploop_allocate_cluster(struct ploop *ploop, u32 *dst_clu)
 	}
 
 	if (end > old_size) {
-		ret = ploop_truncate_prealloc_safe(ploop, top, end, __func__);
+		ret = ploop_truncate_prealloc_safe(ploop, top, end, file, __func__);
 		if (ret) {
 			ploop_hole_set_bit(*dst_clu, ploop);
 			return ret;
@@ -1175,7 +1175,7 @@ ALLOW_ERROR_INJECTION(ploop_allocate_cluster, ERRNO);
  * in ploop->holes_bitmap and bat_page.
  */
 static int ploop_alloc_cluster(struct ploop *ploop, struct ploop_index_wb *piwb,
-			       u32 clu, u32 *dst_clu)
+			       u32 clu, u32 *dst_clu, struct file *file)
 {
 	bool already_alloced = false;
 	map_index_t *to;
@@ -1198,8 +1198,8 @@ static int ploop_alloc_cluster(struct ploop *ploop, struct ploop_index_wb *piwb,
 	if (already_alloced)
 		goto out;
 
-	ret = ploop_allocate_cluster(ploop, dst_clu);
-	if (ret < 0)
+	ret = ploop_allocate_cluster(ploop, dst_clu, file);
+	if (unlikely(ret < 0))
 		goto out;
 
 	to = kmap_local_page(piwb->bat_page);
@@ -1332,7 +1332,7 @@ static void ploop_submit_rw_mapped(struct ploop *ploop, struct pio *pio)
 
 	pos = to_bytes(pio->bi_iter.bi_sector);
 
-	file = ploop->deltas[pio->level].file;
+	file = ploop->deltas[pio->level].mtfile[pio->runner_id];
 
 	/* Don't touch @pio after that */
 	if (pio->css && !ploop->nokblkcg) {
@@ -1436,14 +1436,14 @@ static int ploop_initiate_cluster_cow(struct ploop *ploop, unsigned int level,
 }
 ALLOW_ERROR_INJECTION(ploop_submit_cluster_cow, ERRNO);
 
-static void ploop_submit_cluster_write(struct ploop_cow *cow)
+static void ploop_submit_cluster_write(struct ploop_cow *cow, struct file *file)
 {
 	struct pio *aux_pio = cow->aux_pio;
 	struct ploop *ploop = cow->ploop;
 	u32 dst_clu;
 	int ret;
 
-	ret = ploop_allocate_cluster(ploop, &dst_clu);
+	ret = ploop_allocate_cluster(ploop, &dst_clu, file);
 	if (unlikely(ret < 0))
 		goto error;
 	cow->dst_clu = dst_clu;
@@ -1524,6 +1524,7 @@ static void ploop_submit_cow_index_wb(struct ploop_cow *cow)
 static void ploop_process_one_delta_cow(struct ploop *ploop, struct pio *aux_pio)
 {
 	struct ploop_cow *cow;
+	struct file *file;
 
 	cow = aux_pio->endio_cb_data;
 	if (unlikely(aux_pio->bi_status != BLK_STS_OK)) {
@@ -1532,12 +1533,15 @@ static void ploop_process_one_delta_cow(struct ploop *ploop, struct pio *aux_pio
 	}
 	/* until type is changed */
 	INIT_LIST_HEAD(&aux_pio->list);
+
+	file = ploop_top_delta(ploop)->mtfile[aux_pio->runner_id];
+
 	if (cow->dst_clu == BAT_ENTRY_NONE) {
 		/*
 		 * Stage #1: assign dst_clu and write data
 		 * to top delta.
 		 */
-		ploop_submit_cluster_write(cow);
+		ploop_submit_cluster_write(cow, file);
 	} else {
 		/*
 		 * Stage #2: data is written to top delta.
@@ -1572,6 +1576,7 @@ static bool ploop_locate_new_cluster_and_attach_pio(struct ploop *ploop,
 	u32 page_id;
 	int err;
 	unsigned long flags;
+	struct file *file;
 
 	WARN_ON_ONCE(pio->queue_list_id != PLOOP_LIST_DEFERRED);
 	spin_lock_irqsave(&ploop->bat_lock, flags);
@@ -1596,7 +1601,9 @@ static bool ploop_locate_new_cluster_and_attach_pio(struct ploop *ploop,
 
 	piwb = md->piwb;
 
-	err = ploop_alloc_cluster(ploop, piwb, clu, dst_clu);
+	file = ploop_top_delta(ploop)->mtfile[pio->runner_id];
+
+	err = ploop_alloc_cluster(ploop, piwb, clu, dst_clu, file);
 	if (err) {
 		pio->bi_status = errno_to_blk_status(err);
 		clear_bit(MD_DIRTY, &md->status);
@@ -2076,6 +2083,7 @@ int ploop_pio_runner(void *data)
 		llist_for_each_safe(pos, t, llwork) {
 			pio = list_entry((struct list_head *)pos, typeof(*pio), list);
 			INIT_LIST_HEAD(&pio->list);
+			pio->runner_id = worker->runner_id;
 			switch (pio->queue_list_id) {
 			case PLOOP_LIST_FLUSH:
 				WARN_ON_ONCE(1);	/* We must not see flushes here */
@@ -2350,7 +2358,8 @@ static void ploop_handle_cleanup(struct ploop *ploop, struct pio *pio)
  */
 int ploop_prepare_reloc_index_wb(struct ploop *ploop,
 				 struct md_page **ret_md,
-				 u32 clu, u32 *dst_clu)
+				 u32 clu, u32 *dst_clu,
+				 struct file *file)
 {
 	enum piwb_type type = PIWB_TYPE_ALLOC;
 	u32 page_id = ploop_bat_clu_to_page_nr(clu);
@@ -2380,7 +2389,7 @@ int ploop_prepare_reloc_index_wb(struct ploop *ploop,
 		 * holes_bitmap.
 		 */
 		ploop_bat_page_zero_cluster(ploop, piwb, clu);
-		err = ploop_alloc_cluster(ploop, piwb, clu, dst_clu);
+		err = ploop_alloc_cluster(ploop, piwb, clu, dst_clu, file);
 		if (err)
 			goto out_reset;
 	}
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index 56539406ce10..e8beacc5841b 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -201,6 +201,10 @@ static void ploop_destroy(struct ploop *ploop)
 	while (ploop->nr_deltas-- > 0) {
 		if (ploop->deltas[ploop->nr_deltas].file)
 			fput(ploop->deltas[ploop->nr_deltas].file);
+		for (i = 0; i < ploop->nkt_runners; i++) {
+			if (ploop->deltas[ploop->nr_deltas].mtfile[i])
+				fput(ploop->deltas[ploop->nr_deltas].mtfile[i]);
+		}
 	}
 	WARN_ON(ploop_has_pending_activity(ploop));
 	WARN_ON(!ploop_empty_htable(ploop->exclusive_pios));
@@ -379,6 +383,10 @@ static struct ploop_worker *ploop_worker_create(struct ploop *ploop,
 	if (IS_ERR(task))
 		goto out_err;
 	worker->task = task;
+	if (*pref == 'r')
+		worker->runner_id = id - 1;
+	else
+		worker->runner_id = 0;
 	init_llist_head(&worker->work_llist);
 
 	wake_up_process(task);
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index ad1033c0898a..9f193afab618 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -42,6 +42,7 @@ struct ploop_pvd_header {
 
 struct ploop_delta {
 	struct file *file;
+	struct file **mtfile;
 	loff_t file_size;
 	loff_t file_preallocated_area_start;
 	u32 nr_be; /* nr BAT entries (or file length in clus if RAW) */
@@ -150,6 +151,7 @@ struct ploop_worker {
 	struct ploop		*ploop;
 	struct task_struct	*task;
 	struct llist_head	work_llist;
+	unsigned int		runner_id;
 	atomic_t		inflight_pios;
 	struct ploop_worker	*next;
 };
@@ -310,6 +312,8 @@ struct pio {
 	void (*complete)(struct pio *me);
 	void *data;
 
+	unsigned int		runner_id;
+
 	atomic_t md_inflight;
 };
 
@@ -596,7 +600,8 @@ extern int ploop_rw_page_sync(unsigned rw, struct file *file,
 extern void ploop_map_and_submit_rw(struct ploop *ploop, u32 dst_clu,
 				    struct pio *pio, u8 level);
 extern int ploop_prepare_reloc_index_wb(struct ploop *ploop,
-					struct md_page **ret_md, u32 clu, u32 *dst_clu);
+					struct md_page **ret_md, u32 clu, u32 *dst_clu,
+					struct file *file);
 extern void ploop_break_bat_update(struct ploop *ploop, struct md_page *md);
 extern void ploop_index_wb_submit(struct ploop *, struct ploop_index_wb *);
 extern int ploop_message(struct dm_target *ti, unsigned int argc, char **argv,
-- 
2.43.0



More information about the Devel mailing list