[Devel] [PATCH v4 vz9/vz10] dm-ploop: Fix file handle leaks when merging deltas
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Tue Sep 30 13:52:31 MSK 2025
On 9/30/25 18:46, 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
>
Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> Signed-off-by: Vasileios Almpanis <vasileios.almpanis at virtuozzo.com>
> Feature: dm-ploop: ploop target driver
> ---
>
> v2: Extract delta cleanup into helper function.
> v3: Removes unused variable.
> v4: Fixes styling issues.
> ---
> 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 88b1d02b47d5..a0b678b30b97 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 2043162164be..b8edfc8d5d89 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 89a2b520ca32..ec12c5d2a2c3 100644
> --- a/drivers/md/dm-ploop-target.c
> +++ b/drivers/md/dm-ploop-target.c
> @@ -202,20 +202,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 54d51ab8126b..fc12efeb0cd9 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,
--
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.
More information about the Devel
mailing list