[Devel] [PATCH vz9/vz10] dm-ploop: Fix file handle leaks when merging deltas

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Tue Sep 30 06:15:29 MSK 2025



On 9/29/25 13:24, Vasileios Almpanis wrote:
> 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>
> Feature: dm-ploop: ploop target driver
> ---
>   drivers/md/dm-ploop-cmd.c | 20 +++++++++++++++++++-
>   1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
> index 2043162164be..1975f782be3c 100644
> --- a/drivers/md/dm-ploop-cmd.c
> +++ b/drivers/md/dm-ploop-cmd.c
> @@ -725,7 +725,7 @@ static int ploop_merge_latest_snapshot(struct ploop *ploop)
>   {
>   	struct file *file;
>   	u8 level;
> -	int ret;
> +	int ret, i;
>   
>   	if (ploop->maintaince)
>   		return -EBUSY;
> @@ -745,6 +745,15 @@ static int ploop_merge_latest_snapshot(struct ploop *ploop)
>   
>   	level = ploop->nr_deltas - 2;
>   	file = ploop->deltas[level].file;
> +
> +	if (ploop->deltas[level].mtfile) {
> +		for (i = 0; i < ploop->nkt_runners; i++) {
> +			if (ploop->deltas[level].mtfile[i])
> +				fput(ploop->deltas[level].mtfile[i]);
> +		}
> +		kfree(ploop->deltas[level].mtfile);
> +	}

Functionally looks good.

We have this code in multiple places (which puts delta file and 
mtfile-s), maybe we can make a helper of it (ploop_put_delta(struct 
ploop_delta *delta)) and use it everywhere (in 
ploop_merge_latest_snapshot, notify_delta_merged and ploop_destroy)?

> +
>   	ploop->deltas[level] = ploop->deltas[level + 1];
>   	ploop->nr_deltas--;
>   	fput(file);
> @@ -818,6 +827,15 @@ static void notify_delta_merged(struct ploop *ploop, u8 level,
>   	}
>   
>   	file = ploop->deltas[level].file;
> +
> +	if (ploop->deltas[level].mtfile) {
> +		for (i = 0; i < ploop->nkt_runners; i++) {
> +			if (ploop->deltas[level].mtfile[i])
> +				fput(ploop->deltas[level].mtfile[i]);
> +		}
> +		kfree(ploop->deltas[level].mtfile);
> +	}
> +
>   	/* Renumber deltas above @level */
>   	for (i = level + 1; i < ploop->nr_deltas; i++)
>   		ploop->deltas[i - 1] = ploop->deltas[i];

-- 
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.



More information about the Devel mailing list