summaryrefslogtreecommitdiff
path: root/block/io.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2016-05-20 18:49:07 +0200
committerKevin Wolf <kwolf@redhat.com>2016-05-25 19:04:10 +0200
commit88be7b4be4aa17c88247e162bdd7577ea79db94f (patch)
treecec7d9da5079f6dba0c65945925aedfd8c77267c /block/io.c
parent287db79df8af8e31f18e262feb5e05103a09e4d4 (diff)
downloadqemu-88be7b4be4aa17c88247e162bdd7577ea79db94f.zip
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/io.c')
-rw-r--r--block/io.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/block/io.c b/block/io.c
index 60a6bd8bdb..2a28d63720 100644
--- a/block/io.c
+++ b/block/io.c
@@ -271,10 +271,10 @@ void bdrv_drain_all(void)
/* Always run first iteration so any pending completion BHs run */
bool busy = true;
BlockDriverState *bs;
- BdrvNextIterator *it = NULL;
+ BdrvNextIterator it;
GSList *aio_ctxs = NULL, *ctx;
- while ((it = bdrv_next(it, &bs))) {
+ for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
AioContext *aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
@@ -302,10 +302,9 @@ void bdrv_drain_all(void)
for (ctx = aio_ctxs; ctx != NULL; ctx = ctx->next) {
AioContext *aio_context = ctx->data;
- it = NULL;
aio_context_acquire(aio_context);
- while ((it = bdrv_next(it, &bs))) {
+ for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
if (aio_context == bdrv_get_aio_context(bs)) {
if (bdrv_requests_pending(bs)) {
busy = true;
@@ -318,8 +317,7 @@ void bdrv_drain_all(void)
}
}
- it = NULL;
- while ((it = bdrv_next(it, &bs))) {
+ for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
AioContext *aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);