[Devel] [PATCH RHEL10 COMMIT] dm-ploop: Fix file handle leaks when	merging deltas
    Konstantin Khorenko 
    khorenko at virtuozzo.com
       
    Thu Oct  9 23:48:42 MSK 2025
    
    
  
The commit is pushed to "branch-rh10-6.12.0-55.13.1.2.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh10-6.12.0-55.13.1.2.9.vz10
------>
commit 5d8ce2a256704e39050ea72d6202ef570b66eb6b
Author: Vasileios Almpanis <vasileios.almpanis at virtuozzo.com>
Date:   Tue Sep 30 10:46:45 2025 +0000
    dm-ploop: Fix file handle leaks when merging deltas
    
    When merging deltas, we rewrite the deltas array and remove the lower
    delta. Each delta holds file handles for its runners, but these were not
    being released. On vStorage, the files were deleted but a
    temporary handle remained, causing EBUSY errors until reboot. As a
    result, directories containing snapshots could not be deleted.
    
    https://virtuozzo.atlassian.net/browse/VSTOR-116285
    
    Signed-off-by: Vasileios Almpanis <vasileios.almpanis at virtuozzo.com>
    Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
    
    Feature: dm-ploop: ploop target driver
---
 drivers/md/dm-ploop-bat.c    | 18 ++++++++++++++++++
 drivers/md/dm-ploop-cmd.c    |  9 +++++----
 drivers/md/dm-ploop-target.c | 15 ++-------------
 drivers/md/dm-ploop.h        |  1 +
 4 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/drivers/md/dm-ploop-bat.c b/drivers/md/dm-ploop-bat.c
index 1b4d349a5cb6d..fbf949f4dd0fb 100644
--- a/drivers/md/dm-ploop-bat.c
+++ b/drivers/md/dm-ploop-bat.c
@@ -526,3 +526,21 @@ int ploop_add_delta(struct ploop *ploop, u32 level, struct file *file, bool is_r
 	return ret;
 }
 ALLOW_ERROR_INJECTION(ploop_add_delta, ERRNO);
+
+void ploop_put_delta(struct ploop *ploop, struct ploop_delta *delta)
+{
+	int i;
+
+	if (delta->file) {
+		vfs_fsync(delta->file, 1);
+		fput(delta->file);
+	}
+
+	if (delta->mtfile) {
+		for (i = 0; i < ploop->nkt_runners; i++) {
+			if (delta->mtfile[i])
+				fput(delta->mtfile[i]);
+		}
+		kfree(delta->mtfile);
+	}
+}
diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index 2043162164be1..b8edfc8d5d896 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -744,10 +744,11 @@ static int ploop_merge_latest_snapshot(struct ploop *ploop)
 		goto out;
 
 	level = ploop->nr_deltas - 2;
-	file = ploop->deltas[level].file;
+
+	ploop_put_delta(ploop, &ploop->deltas[level]);
+
 	ploop->deltas[level] = ploop->deltas[level + 1];
 	ploop->nr_deltas--;
-	fput(file);
 
 	ploop_resume_submitting_pios(ploop);
 out:
@@ -817,13 +818,13 @@ static void notify_delta_merged(struct ploop *ploop, u8 level,
 		d_md = ploop_md_next_entry(d_md);
 	}
 
-	file = ploop->deltas[level].file;
+	ploop_put_delta(ploop, &ploop->deltas[level]);
+
 	/* Renumber deltas above @level */
 	for (i = level + 1; i < ploop->nr_deltas; i++)
 		ploop->deltas[i - 1] = ploop->deltas[i];
 	memset(&ploop->deltas[--ploop->nr_deltas], 0,
 	       sizeof(struct ploop_delta));
-	fput(file);
 }
 
 static int ploop_process_update_delta_index(struct ploop *ploop, u8 level,
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index 9853db47eda14..d95efea1e5356 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -203,20 +203,9 @@ static void ploop_destroy(struct ploop *ploop)
 	for (i = 0; i < 2; i++)
 		percpu_ref_exit(&ploop->inflight_bios_ref[i]);
 	/* Nobody uses it after destroy_workqueue() */
-	while (ploop->nr_deltas-- > 0) {
-		if (ploop->deltas[ploop->nr_deltas].file) {
-			vfs_fsync(ploop->deltas[ploop->nr_deltas].file, 1);
-			fput(ploop->deltas[ploop->nr_deltas].file);
-		}
+	while (ploop->nr_deltas-- > 0)
+		ploop_put_delta(ploop, &ploop->deltas[ploop->nr_deltas]);
 
-		if (ploop->deltas[ploop->nr_deltas].mtfile) {
-			for (i = 0; i < ploop->nkt_runners; i++) {
-				if (ploop->deltas[ploop->nr_deltas].mtfile[i])
-					fput(ploop->deltas[ploop->nr_deltas].mtfile[i]);
-			}
-		}
-		kfree(ploop->deltas[ploop->nr_deltas].mtfile);
-	}
 	WARN_ON(ploop_has_pending_activity(ploop));
 	WARN_ON(!ploop_empty_htable(ploop->exclusive_pios));
 	WARN_ON(!ploop_empty_htable(ploop->inflight_pios));
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 54d51ab8126ba..fc12efeb0cd93 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -600,6 +600,7 @@ extern bool ploop_try_update_bat_entry(struct ploop *ploop, u32 clu,
 
 extern int ploop_add_delta(struct ploop *ploop, u32 level,
 			   struct file *file, bool is_raw);
+extern void ploop_put_delta(struct ploop *ploop, struct ploop_delta *delta);
 extern int ploop_check_delta_length(struct ploop *ploop, struct file *file,
 				    loff_t *file_size);
 extern void ploop_submit_embedded_pios(struct ploop *ploop,
    
    
More information about the Devel
mailing list