On Thu 01 Oct 2015 03:13:26 PM CEST, Kevin Wolf wrote:

> @@ -2428,12 +2434,9 @@ int bdrv_drop_intermediate(BlockDriverState *active, 
> BlockDriverState *top,
>      BlockDriverState *intermediate;
>      BlockDriverState *base_bs = NULL;
>      BlockDriverState *new_top_bs = NULL;
> -    BlkIntermediateStates *intermediate_state, *next;
> +    BlkIntermediateStates *intermediate_state;
>      int ret = -EIO;
>  
> -    QSIMPLEQ_HEAD(states_to_delete, BlkIntermediateStates) states_to_delete;
> -    QSIMPLEQ_INIT(&states_to_delete);
> -
>      if (!top->drv || !base->drv) {
>          goto exit;
>      }
> @@ -2460,7 +2463,6 @@ int bdrv_drop_intermediate(BlockDriverState *active, 
> BlockDriverState *top,
>      while (intermediate) {
>          intermediate_state = g_new0(BlkIntermediateStates, 1);
>          intermediate_state->bs = intermediate;
> -        QSIMPLEQ_INSERT_TAIL(&states_to_delete, intermediate_state, entry);
>  
>          if (backing_bs(intermediate) == base) {
>              base_bs = backing_bs(intermediate);

The purpose of this while() loop in the original code was to make a list
of all the intermediate states whose references need to be dropped after
the bdrv_set_backing_hd() call. Since now bdrv_set_backing_hd() is the
one who manages the backing references, this list is no longer
necessary, and you are actually leaking the BlkIntermediateStates
objects here (see the rest of the patch below).

The loop is also useful to check that 'base' is indeed part of the
backing chain, so that we should keep.

> @@ -2483,17 +2485,8 @@ int bdrv_drop_intermediate(BlockDriverState *active, 
> BlockDriverState *top,
>      }
>      bdrv_set_backing_hd(new_top_bs, base_bs);
>  
> -    QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, 
> next) {
> -        /* so that bdrv_close() does not recursively close the chain */
> -        bdrv_set_backing_hd(intermediate_state->bs, NULL);
> -        bdrv_unref(intermediate_state->bs);
> -    }
>      ret = 0;
> -
>  exit:
> -    QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, 
> next) {
> -        g_free(intermediate_state);
> -    }
>      return ret;
>  }

Berto

Reply via email to