qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>, qemu-block@nongnu.org
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PULL 01/31] block: Fix bdrv_next() memory leak
Date: Mon, 6 Jun 2016 10:41:13 +0200	[thread overview]
Message-ID: <8c037ed3-e5da-7a3f-1ed7-754154c9edf0@redhat.com> (raw)
In-Reply-To: <1464197996-4581-2-git-send-email-kwolf@redhat.com>



On 25/05/2016 19:39, Kevin Wolf wrote:
> @@ -395,20 +399,27 @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs,
>  {
>      int ret = 0;
>      BlockDriverState *bs;
> -    BdrvNextIterator *it = NULL;
> +    BdrvNextIterator it;
>      QEMUSnapshotInfo sn1, *snapshot = &sn1;
>  
> -    while (ret == 0 && (it = bdrv_next(it, &bs))) {
> +    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
>          AioContext *ctx = bdrv_get_aio_context(bs);
>  
>          aio_context_acquire(ctx);
>          if (bdrv_can_snapshot(bs) &&
>                  bdrv_snapshot_find(bs, snapshot, name) >= 0) {
>              ret = bdrv_snapshot_delete_by_id_or_name(bs, name, err);
> +            if (ret < 0) {
> +                goto fail;
> +            }

This is redundant with the check below (and the check below is right;
this one is wrong).

Thanks,

Paolo

>          }
>          aio_context_release(ctx);
> +        if (ret < 0) {
> +            goto fail;
> +        }
>      }
>  
> +fail:
>      *first_bad_bs = bs;
>      return ret;
>  }
> @@ -418,9 +429,9 @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs)
>  {
>      int err = 0;
>      BlockDriverState *bs;
> -    BdrvNextIterator *it = NULL;
> +    BdrvNextIterator it;
>  
> -    while (err == 0 && (it = bdrv_next(it, &bs))) {
> +    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
>          AioContext *ctx = bdrv_get_aio_context(bs);
>  
>          aio_context_acquire(ctx);
> @@ -428,8 +439,12 @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs)
>              err = bdrv_snapshot_goto(bs, name);
>          }
>          aio_context_release(ctx);
> +        if (err < 0) {
> +            goto fail;
> +        }
>      }
>  
> +fail:
>      *first_bad_bs = bs;
>      return err;
>  }
> @@ -439,9 +454,9 @@ int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
>      QEMUSnapshotInfo sn;
>      int err = 0;
>      BlockDriverState *bs;
> -    BdrvNextIterator *it = NULL;
> +    BdrvNextIterator it;
>  
> -    while (err == 0 && (it = bdrv_next(it, &bs))) {
> +    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
>          AioContext *ctx = bdrv_get_aio_context(bs);
>  
>          aio_context_acquire(ctx);
> @@ -449,8 +464,12 @@ int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
>              err = bdrv_snapshot_find(bs, &sn, name);
>          }
>          aio_context_release(ctx);
> +        if (err < 0) {
> +            goto fail;
> +        }
>      }
>  
> +fail:
>      *first_bad_bs = bs;
>      return err;
>  }
> @@ -462,9 +481,9 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
>  {
>      int err = 0;
>      BlockDriverState *bs;
> -    BdrvNextIterator *it = NULL;
> +    BdrvNextIterator it;
>  
> -    while (err == 0 && (it = bdrv_next(it, &bs))) {
> +    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
>          AioContext *ctx = bdrv_get_aio_context(bs);
>  
>          aio_context_acquire(ctx);
> @@ -476,24 +495,32 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
>              err = bdrv_snapshot_create(bs, sn);
>          }
>          aio_context_release(ctx);
> +        if (err < 0) {
> +            goto fail;
> +        }
>      }
>  
> +fail:
>      *first_bad_bs = bs;
>      return err;
>  }
>  
>  BlockDriverState *bdrv_all_find_vmstate_bs(void)
>  {
> -    bool not_found = true;
>      BlockDriverState *bs;
> -    BdrvNextIterator *it = NULL;
> +    BdrvNextIterator it;
>  
> -    while (not_found && (it = bdrv_next(it, &bs))) {
> +    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
>          AioContext *ctx = bdrv_get_aio_context(bs);
> +        bool found;
>  
>          aio_context_acquire(ctx);
> -        not_found = !bdrv_can_snapshot(bs);
> +        found = bdrv_can_snapshot(bs);
>          aio_context_release(ctx);
> +
> +        if (found) {
> +            break;
> +        }
>      }
>      return bs;
>  }
> diff --git a/blockdev.c b/blockdev.c
> index 40e4e6f..0e37e09 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -4164,9 +4164,9 @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp)
>  {
>      BlockJobInfoList *head = NULL, **p_next = &head;
>      BlockDriverState *bs;
> -    BdrvNextIterator *it = NULL;
> +    BdrvNextIterator it;
>  
> -    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);
> diff --git a/include/block/block.h b/include/block/block.h
> index a8c15e3..770ca26 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -17,7 +17,6 @@ typedef struct BlockJob BlockJob;
>  typedef struct BdrvChild BdrvChild;
>  typedef struct BdrvChildRole BdrvChildRole;
>  typedef struct BlockJobTxn BlockJobTxn;
> -typedef struct BdrvNextIterator BdrvNextIterator;
>  
>  typedef struct BlockDriverInfo {
>      /* in bytes, 0 if irrelevant */
> @@ -402,7 +401,19 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
>                                   Error **errp);
>  bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
>  BlockDriverState *bdrv_next_node(BlockDriverState *bs);
> -BdrvNextIterator *bdrv_next(BdrvNextIterator *it, BlockDriverState **bs);
> +
> +typedef struct BdrvNextIterator {
> +    enum {
> +        BDRV_NEXT_BACKEND_ROOTS,
> +        BDRV_NEXT_MONITOR_OWNED,
> +    } phase;
> +    BlockBackend *blk;
> +    BlockDriverState *bs;
> +} BdrvNextIterator;
> +
> +BlockDriverState *bdrv_first(BdrvNextIterator *it);
> +BlockDriverState *bdrv_next(BdrvNextIterator *it);
> +
>  BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
>  int bdrv_is_encrypted(BlockDriverState *bs);
>  int bdrv_key_required(BlockDriverState *bs);
> diff --git a/migration/block.c b/migration/block.c
> index a7a76a0..e0628d1 100644
> --- a/migration/block.c
> +++ b/migration/block.c
> @@ -383,7 +383,7 @@ static void init_blk_migration(QEMUFile *f)
>      BlockDriverState *bs;
>      BlkMigDevState *bmds;
>      int64_t sectors;
> -    BdrvNextIterator *it = NULL;
> +    BdrvNextIterator it;
>  
>      block_mig_state.submitted = 0;
>      block_mig_state.read_done = 0;
> @@ -394,7 +394,7 @@ static void init_blk_migration(QEMUFile *f)
>      block_mig_state.zero_blocks = migrate_zero_blocks();
>  
>  
> -    while ((it = bdrv_next(it, &bs))) {
> +    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
>          if (bdrv_is_read_only(bs)) {
>              continue;
>          }
> diff --git a/monitor.c b/monitor.c
> index 6a32b9b..404d594 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -3432,12 +3432,12 @@ static void vm_completion(ReadLineState *rs, const char *str)
>  {
>      size_t len;
>      BlockDriverState *bs;
> -    BdrvNextIterator *it = NULL;
> +    BdrvNextIterator it;
>  
>      len = strlen(str);
>      readline_set_completion_index(rs, len);
>  
> -    while ((it = bdrv_next(it, &bs))) {
> +    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
>          SnapshotInfoList *snapshots, *snapshot;
>          AioContext *ctx = bdrv_get_aio_context(bs);
>          bool ok = false;
> diff --git a/qmp.c b/qmp.c
> index 8f8ae3a..3165f87 100644
> --- a/qmp.c
> +++ b/qmp.c
> @@ -181,7 +181,7 @@ void qmp_cont(Error **errp)
>      Error *local_err = NULL;
>      BlockBackend *blk;
>      BlockDriverState *bs;
> -    BdrvNextIterator *it;
> +    BdrvNextIterator it;
>  
>      /* if there is a dump in background, we should wait until the dump
>       * finished */
> @@ -201,8 +201,7 @@ void qmp_cont(Error **errp)
>          blk_iostatus_reset(blk);
>      }
>  
> -    it = NULL;
> -    while ((it = bdrv_next(it, &bs))) {
> +    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
>          bdrv_add_key(bs, NULL, &local_err);
>          if (local_err) {
>              error_propagate(errp, local_err);
> 

  reply	other threads:[~2016-06-06  8:41 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-25 17:39 [Qemu-devel] [PULL 00/31] Block layer patches Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 01/31] block: Fix bdrv_next() memory leak Kevin Wolf
2016-06-06  8:41   ` Paolo Bonzini [this message]
2016-05-25 17:39 ` [Qemu-devel] [PULL 02/31] block: Drop useless bdrv_new() call Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 03/31] block: Let bdrv_open_inherit() return the snapshot Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 04/31] tests: Drop BDS from test-throttle.c Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 05/31] block: Drop blk_new_with_bs() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 06/31] block: Drop bdrv_new_root() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 07/31] block: Make bdrv_open() return a BDS Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 08/31] block: Assert !bs->refcnt in bdrv_close() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 09/31] block: Drop bdrv_parent_cb_...() from bdrv_close() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 10/31] block: Drop errp parameter from blk_new() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 11/31] block: Introduce bdrv_replace_child() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 12/31] block: Make bdrv_drain() use bdrv_drained_begin/end() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 13/31] block: Fix reconfiguring graph with drained nodes Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 14/31] block: Propagate .drained_begin/end callbacks Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 15/31] dma-helpers: change interface to byte-based Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 16/31] dma-helpers: change BlockBackend to opaque value in DMAIOFunc Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 17/31] block: Rename blk_write_zeroes() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 18/31] block: keep a list of block jobs Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 19/31] block: Cancel jobs first in bdrv_close_all() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 20/31] block: Default to enabled write cache in blk_new() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 21/31] block: Convert block job core to BlockBackend Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 22/31] block: Make blk_co_preadv/pwritev() public Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 23/31] stream: Use BlockBackend for I/O Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 24/31] mirror: Allow target that already has a BlockBackend Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 25/31] mirror: Use BlockBackend for I/O Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 26/31] backup: Don't leak BackupBlockJob in error path Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 27/31] backup: Pack Notifier within BackupBlockJob Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 28/31] backup: Remove bs parameter from backup_do_cow() Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 29/31] backup: Use BlockBackend for I/O Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 30/31] commit: " Kevin Wolf
2016-05-25 17:39 ` [Qemu-devel] [PULL 31/31] blockjob: Remove BlockJob.bs Kevin Wolf
2016-05-26 14:06 ` [Qemu-devel] [PULL 00/31] Block layer patches Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8c037ed3-e5da-7a3f-1ed7-754154c9edf0@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).