qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Max Reitz <mreitz@redhat.com>
Cc: Alberto Garcia <berto@igalia.com>,
	qemu-block@nongnu.org, John Snow <jsnow@redhat.com>,
	qemu-devel@nongnu.org, Markus Armbruster <armbru@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v6 23/39] block: Prepare for NULL BDS
Date: Tue, 13 Oct 2015 17:37:27 +0200	[thread overview]
Message-ID: <20151013153727.GK4906@noname.str.redhat.com> (raw)
In-Reply-To: <1444680042-13207-24-git-send-email-mreitz@redhat.com>

Am 12.10.2015 um 22:00 hat Max Reitz geschrieben:
> blk_bs() will not necessarily return a non-NULL value any more (unless
> blk_is_available() is true or it can be assumed to otherwise, e.g.
> because it is called immediately after a successful blk_new_with_bs() or
> blk_new_open()).
> 
> Signed-off-by: Max Reitz <mreitz@redhat.com>

> @@ -1584,12 +1594,16 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
>                    "Device '%s' not found", backup->device);
>          return;
>      }
> -    bs = blk_bs(blk);
>  
>      /* AioContext is released in .clean() */
> -    state->aio_context = bdrv_get_aio_context(bs);
> +    state->aio_context = blk_get_aio_context(blk);
>      aio_context_acquire(state->aio_context);
>  
> +    if (!blk_is_available(blk)) {
> +        error_setg(errp, "Device '%s' has no medium", backup->device);
> +        return;
> +    }
> +
>      qmp_drive_backup(backup->device, backup->target,
>                       backup->has_format, backup->format,
>                       backup->sync,
> @@ -1604,7 +1618,7 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
>          return;
>      }
>  
> -    state->bs = bs;
> +    state->bs = blk_bs(blk);
>      state->job = state->bs->job;
>  }
>  
> @@ -1639,8 +1653,7 @@ static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp)
>  {
>      BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
>      BlockdevBackup *backup;
> -    BlockDriverState *bs, *target;
> -    BlockBackend *blk;
> +    BlockBackend *blk, *target;
>      Error *local_err = NULL;
>  
>      assert(common->action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
> @@ -1651,18 +1664,16 @@ static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp)
>          error_setg(errp, "Device '%s' not found", backup->device);
>          return;
>      }
> -    bs = blk_bs(blk);
>  
> -    blk = blk_by_name(backup->target);
> -    if (!blk) {
> +    target = blk_by_name(backup->target);
> +    if (!target) {
>          error_setg(errp, "Device '%s' not found", backup->target);
>          return;
>      }
> -    target = blk_bs(blk);
>  
>      /* AioContext is released in .clean() */
> -    state->aio_context = bdrv_get_aio_context(bs);
> -    if (state->aio_context != bdrv_get_aio_context(target)) {
> +    state->aio_context = blk_get_aio_context(blk);
> +    if (state->aio_context != blk_get_aio_context(target)) {
>          state->aio_context = NULL;
>          error_setg(errp, "Backup between two IO threads is not implemented");
>          return;
> @@ -1680,7 +1691,7 @@ static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp)
>          return;
>      }
>  
> -    state->bs = bs;
> +    state->bs = blk_bs(blk);
>      state->job = state->bs->job;
>  }

It's somewhat inconsistent that blockdev_backup_prepare() doesn't do an
explicit blk_is_available() check whereas drive_backup_prepare() does.
As far as I can tell, both don't necessarily need their for their own
code and in both cases the called qmp_*_backup() function checks it
again.

Not really a problem, though, it just looks a bit odd.

> @@ -1818,10 +1829,10 @@ static void eject_device(BlockBackend *blk, int force, Error **errp)
>      BlockDriverState *bs = blk_bs(blk);
>      AioContext *aio_context;
>  
> -    aio_context = bdrv_get_aio_context(bs);
> +    aio_context = blk_get_aio_context(blk);
>      aio_context_acquire(aio_context);
>  
> -    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
> +    if (bs && bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
>          goto out;
>      }
>      if (!blk_dev_has_removable_media(blk)) {
>          error_setg(errp, "Device '%s' is not removable",
>                     bdrv_get_device_name(bs));

bs isn't checked to be non-NULL here. You could argue that if it's not
removable, it shouldn't be NULL, but I think we let drive_del forcibly
remove the medium even for devices that can't deal with it and start
producing I/O errors then.

>          goto out;
>      }
>
>      if (blk_dev_is_medium_locked(blk) && !blk_dev_is_tray_open(blk)) {
>          blk_dev_eject_request(blk, force);
>          if (!force) {
>              error_setg(errp, "Device '%s' is locked",
>                         bdrv_get_device_name(bs));

And here.

>              goto out;
>          }
>      }
>  
> -    bdrv_close(bs);
> +    if (bs) {
> +        bdrv_close(bs);
> +    }
>  
>  out:
>      aio_context_release(aio_context);

I think the change becomes simpler if you just return immediately for a
NULL bs instead of evaluation for every place whether checking it could
make a difference.

> @@ -1884,10 +1897,12 @@ void qmp_block_passwd(bool has_device, const char *device,
>  }
>  
>  /* Assumes AioContext is held */
> -static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
> +static void qmp_bdrv_open_encrypted(BlockDriverState **pbs,
> +                                    const char *filename,
>                                      int bdrv_flags, const char *format,
>                                      const char *password, Error **errp)
>  {
> +    BlockDriverState *bs;
>      Error *local_err = NULL;
>      QDict *options = NULL;
>      int ret;
> @@ -1897,11 +1912,12 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
>          qdict_put(options, "driver", qstring_from_str(format));
>      }
>  
> -    ret = bdrv_open(&bs, filename, NULL, options, bdrv_flags, &local_err);
> +    ret = bdrv_open(pbs, filename, NULL, options, bdrv_flags, &local_err);
>      if (ret < 0) {
>          error_propagate(errp, local_err);
>          return;
>      }
> +    bs = *pbs;
>  
>      bdrv_add_key(bs, password, errp);
>  }

Yup, we definitely need a local variable bs for this one line! ;-)

> @@ -1913,6 +1929,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
>      BlockDriverState *bs;
>      AioContext *aio_context;
>      int bdrv_flags;
> +    bool new_bs;
>      Error *err = NULL;
>  
>      blk = blk_by_name(device);
> @@ -1922,8 +1939,9 @@ void qmp_change_blockdev(const char *device, const char *filename,
>          return;
>      }
>      bs = blk_bs(blk);
> +    new_bs = !bs;
>  
> -    aio_context = bdrv_get_aio_context(bs);
> +    aio_context = blk_get_aio_context(blk);
>      aio_context_acquire(aio_context);
>  
>      eject_device(blk, 0, &err);
> @@ -1932,10 +1950,18 @@ void qmp_change_blockdev(const char *device, const char *filename,
>          goto out;
>      }
>  
> -    bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
> -    bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
> +    bdrv_flags = blk_is_read_only(blk) ? 0 : BDRV_O_RDWR;
> +    bdrv_flags |= blk_get_root_state(blk)->open_flags & ~BDRV_O_RDWR;
>  
> -    qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, format, NULL, errp);
> +    qmp_bdrv_open_encrypted(&bs, filename, bdrv_flags, format, NULL, &err);
> +    if (err) {
> +        error_propagate(errp, err);

goto out just to keep working when someone adds another line of code
before out?

> +    } else if (new_bs) {
> +        blk_insert_bs(blk, bs);
> +        /* Has been sent automatically by bdrv_open() if blk_bs(blk) was not
> +         * NULL */
> +        blk_dev_change_media_cb(blk, true);
> +    }
>  
>  out:
>      aio_context_release(aio_context);

> @@ -2151,16 +2182,19 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
>          return;
>      }
>  
> -    aio_context = bdrv_get_aio_context(bs);
> +    aio_context = blk_get_aio_context(blk);
>      aio_context_acquire(aio_context);
>  
> -    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
> +    bs = blk_bs(blk);
> +    if (bs && bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
>          error_report_err(local_err);
>          aio_context_release(aio_context);
>          return;
>      }
>  
> -    bdrv_close(bs);
> +    if (bs) {
> +        bdrv_close(bs);
> +    }

Why not a single if (bs) block?

Kevin

  reply	other threads:[~2015-10-13 15:37 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-12 20:00 [Qemu-devel] [PATCH v6 00/39] blockdev: BlockBackend and media Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 01/39] block: Remove host floppy support Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 02/39] block: Set BDRV_O_INCOMING in bdrv_fill_options() Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 03/39] blockdev: Allow creation of BDS trees without BB Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 04/39] iotests: Only create BB if necessary Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 05/39] block: Make bdrv_is_inserted() return a bool Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 06/39] block: Add blk_is_available() Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 07/39] block: Make bdrv_is_inserted() recursive Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 08/39] block/raw_bsd: Drop raw_is_inserted() Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 09/39] block: Invoke change media CB before NULLing drv Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 10/39] hw/block/fdc: Implement tray status Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 11/39] hw/usb-storage: Check whether BB is inserted Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 12/39] block: Fix BB AIOCB AioContext without BDS Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 13/39] block: Move guest_block_size into BlockBackend Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 14/39] block: Remove wr_highest_sector from BlockAcctStats Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 15/39] block: Move BlockAcctStats into BlockBackend Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 16/39] block: Move I/O status and error actions into BB Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 17/39] block/throttle-groups: Make incref/decref public Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 18/39] block: Add BlockBackendRootState Max Reitz
2015-10-19 14:18   ` Kevin Wolf
2015-10-19 14:32     ` Max Reitz
2015-10-19 14:42       ` Kevin Wolf
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 19/39] block: Make some BB functions fall back to BBRS Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 20/39] block: Fail requests to empty BlockBackend Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 21/39] block: Prepare remaining BB functions for NULL BDS Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 22/39] block: Add blk_insert_bs() Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 23/39] block: Prepare for NULL BDS Max Reitz
2015-10-13 15:37   ` Kevin Wolf [this message]
2015-10-14 15:06     ` Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 24/39] blockdev: Do not create BDS for empty drive Max Reitz
2015-10-14 13:27   ` Kevin Wolf
2015-10-14 15:13     ` Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 25/39] blockdev: Pull out blockdev option extraction Max Reitz
2015-10-14 15:12   ` Kevin Wolf
2015-10-14 15:16     ` Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 26/39] blockdev: Allow more options for BB-less BDS tree Max Reitz
2015-10-15 11:29   ` Kevin Wolf
2015-10-17 16:33     ` Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 27/39] block: Add blk_remove_bs() Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 28/39] blockdev: Add blockdev-open-tray Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 29/39] blockdev: Add blockdev-close-tray Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 30/39] blockdev: Add blockdev-remove-medium Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 31/39] blockdev: Add blockdev-insert-medium Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 32/39] blockdev: Implement eject with basic operations Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 33/39] blockdev: Implement change " Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 34/39] block: Inquire tray state before tray-moved events Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 35/39] qmp: Introduce blockdev-change-medium Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 36/39] hmp: Use blockdev-change-medium for change command Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 37/39] blockdev: read-only-mode for blockdev-change-medium Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 38/39] hmp: Add read-only-mode option to change command Max Reitz
2015-10-12 20:00 ` [Qemu-devel] [PATCH v6 39/39] iotests: Add test for change-related QMP commands Max Reitz
2015-10-13 15:38 ` [Qemu-devel] [PATCH v6 00/39] blockdev: BlockBackend and media Kevin Wolf

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=20151013153727.GK4906@noname.str.redhat.com \
    --to=kwolf@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berto@igalia.com \
    --cc=jsnow@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /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).