All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: Kevin Wolf <kwolf@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: Wed, 14 Oct 2015 17:06:13 +0200	[thread overview]
Message-ID: <561E6F65.7090705@redhat.com> (raw)
In-Reply-To: <20151013153727.GK4906@noname.str.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 9327 bytes --]

On 13.10.2015 17:37, Kevin Wolf wrote:
> 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.

Probably some kind of a rebase conflict. blockdev-backup was added only
rather recently, and so I made a different decision then than for
drive-backup.

I think I'll drop the check from drive_backup_prepare(). Having it in
qmp_drive_backup() is enough.

> 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.

I'd mainly argue that this function is to be removed anyway. :-)

I should just return immediately for NULL bs, as you're suggesting.

> 
>>          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! ;-)

*cough cough*

> 
>> @@ -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?

Yes, will do.

>> +    } 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?

Because that would mean more lines modified. Every line git blame
associates with me is a line Markus might ask me something about.

I'll put it into a single block.

As always, thanks for reviewing!

Max


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

  reply	other threads:[~2015-10-14 15:06 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
2015-10-14 15:06     ` Max Reitz [this message]
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=561E6F65.7090705@redhat.com \
    --to=mreitz@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berto@igalia.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.