diff options
author | Kevin Wolf <kwolf@redhat.com> | 2016-05-20 18:49:07 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2016-05-25 19:04:10 +0200 |
commit | 88be7b4be4aa17c88247e162bdd7577ea79db94f (patch) | |
tree | cec7d9da5079f6dba0c65945925aedfd8c77267c /block.c | |
parent | 287db79df8af8e31f18e262feb5e05103a09e4d4 (diff) |
block: Fix bdrv_next() memory leak
The bdrv_next() users all leaked the BdrvNextIterator after completing
the iteration. Simply changing bdrv_next() to free the iterator before
returning NULL at the end of list doesn't work because some callers exit
the loop before looking at all BDSes.
This patch moves the BdrvNextIterator from the heap to the stack of
the caller and switches to a bdrv_first()/bdrv_next() interface for
initialising the iterator.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r-- | block.c | 18 |
1 files changed, 8 insertions, 10 deletions
@@ -3195,9 +3195,9 @@ void bdrv_invalidate_cache_all(Error **errp) { BlockDriverState *bs; Error *local_err = NULL; - BdrvNextIterator *it = NULL; + BdrvNextIterator it; - while ((it = bdrv_next(it, &bs)) != NULL) { + for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { AioContext *aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); @@ -3239,11 +3239,11 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs, int bdrv_inactivate_all(void) { BlockDriverState *bs = NULL; - BdrvNextIterator *it = NULL; + BdrvNextIterator it; int ret = 0; int pass; - while ((it = bdrv_next(it, &bs)) != NULL) { + for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { aio_context_acquire(bdrv_get_aio_context(bs)); } @@ -3252,8 +3252,7 @@ int bdrv_inactivate_all(void) * the second pass sets the BDRV_O_INACTIVE flag so that no further write * is allowed. */ for (pass = 0; pass < 2; pass++) { - it = NULL; - while ((it = bdrv_next(it, &bs)) != NULL) { + for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { ret = bdrv_inactivate_recurse(bs, pass); if (ret < 0) { goto out; @@ -3262,8 +3261,7 @@ int bdrv_inactivate_all(void) } out: - it = NULL; - while ((it = bdrv_next(it, &bs)) != NULL) { + for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { aio_context_release(bdrv_get_aio_context(bs)); } @@ -3753,10 +3751,10 @@ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, bool bdrv_is_first_non_filter(BlockDriverState *candidate) { BlockDriverState *bs; - BdrvNextIterator *it = NULL; + BdrvNextIterator it; /* walk down the bs forest recursively */ - while ((it = bdrv_next(it, &bs)) != NULL) { + for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { bool perm; /* try to recurse in this top level bs */ |