qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCHv2] iscsi: add iscsi_truncate support


From: Paolo Bonzini
Subject: Re: [Qemu-devel] [PATCHv2] iscsi: add iscsi_truncate support
Date: Fri, 15 Feb 2013 16:06:26 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130110 Thunderbird/17.0.2

Il 15/02/2013 15:35, Peter Lieven ha scritto:
> this patch adds iscsi_truncate which effectively allows for online
> resizing of iscsi volumes. for this to work you have to resize
> the volume on your storage and then call block_resize command
> in qemu which will issue a readcapacity16 to update the capacity.
> 
> v2:
>  - add a general bdrv_drain_all() before bdrv_truncate() to avoid
>    in-flight AIOs while the device is truncated
>  - since no AIOs are in flight we can use a sync libiscsi call
>    to re-read the capacity
>  - factor out the readcapacity16 logic as it is redundant
>    to iscsi_open() and iscsi_truncate().

Please move the entire switch statement of iscsi_open, the code should
be cleaner.  Also please separate bdrv_drain_all() to a separate patch
and Cc qemu-stable on that one (Kevin's message should provide a good
skeleton for a commit messages).

Paolo

> Signed-off-by: Peter Lieven <address@hidden>
> ---
>  block.c       |    4 ++++
>  block/iscsi.c |   65
> +++++++++++++++++++++++++++++++++++++++++++++------------
>  2 files changed, 56 insertions(+), 13 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 50dab8e..d8880e3 100644
> --- a/block.c
> +++ b/block.c
> @@ -2427,6 +2427,10 @@ int bdrv_truncate(BlockDriverState *bs, int64_t
> offset)
>          return -EACCES;
>      if (bdrv_in_use(bs))
>          return -EBUSY;
> +
> +    /* there should be better no AIOs in flight when we truncate the
> device */
> +    bdrv_drain_all();
> +
>      ret = drv->bdrv_truncate(bs, offset);
>      if (ret == 0) {
>          ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
> diff --git a/block/iscsi.c b/block/iscsi.c
> index deb3b68..dd41943 100644
> --- a/block/iscsi.c
> +++ b/block/iscsi.c
> @@ -823,6 +823,35 @@ static void iscsi_nop_timed_event(void *opaque)
>  }
>  #endif
> 
> +static int iscsi_disk_readcapacity16_sync(IscsiLun *iscsilun) {
> +    struct scsi_task *task = NULL;
> +    struct scsi_readcapacity16 *rc16 = NULL;
> +
> +    task = iscsi_readcapacity16_sync(iscsilun->iscsi, iscsilun->lun);
> +    if (task == NULL) {
> +        error_report("iSCSI: failed to send readcapacity16 command.");
> +        return -EINVAL;
> +    }
> +    if (task->status != SCSI_STATUS_GOOD) {
> +        error_report("iSCSI: failed to send readcapacity16 command.");
> +        scsi_free_scsi_task(task);
> +        return -EINVAL;
> +    }
> +    rc16 = scsi_datain_unmarshall(task);
> +    if (rc16 == NULL) {
> +        error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
> +        scsi_free_scsi_task(task);
> +        return -EINVAL;
> +    }
> +
> +    iscsilun->block_size = rc16->block_length;
> +    iscsilun->num_blocks = rc16->returned_lba + 1;
> +
> +    scsi_free_scsi_task(task);
> +
> +    return 0;
> +}
> +
>  /*
>   * We support iscsi url's on the form
>   * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
> @@ -835,7 +864,6 @@ static int iscsi_open(BlockDriverState *bs, const
> char *filename, int flags)
>      struct scsi_task *task = NULL;
>      struct scsi_inquiry_standard *inq = NULL;
>      struct scsi_readcapacity10 *rc10 = NULL;
> -    struct scsi_readcapacity16 *rc16 = NULL;
>      char *initiator_name = NULL;
>      int ret;
> 
> @@ -926,23 +954,13 @@ static int iscsi_open(BlockDriverState *bs, const
> char *filename, int flags)
>      iscsilun->type = inq->periperal_device_type;
> 
>      scsi_free_scsi_task(task);
> +    task = NULL;
> 
>      switch (iscsilun->type) {
>      case TYPE_DISK:
> -        task = iscsi_readcapacity16_sync(iscsi, iscsilun->lun);
> -        if (task == NULL || task->status != SCSI_STATUS_GOOD) {
> -            error_report("iSCSI: failed to send readcapacity16 command.");
> -            ret = -EINVAL;
> +        if ((ret = iscsi_disk_readcapacity16_sync(iscsilun))) {
>              goto out;
>          }
> -        rc16 = scsi_datain_unmarshall(task);
> -        if (rc16 == NULL) {
> -            error_report("iSCSI: Failed to unmarshall readcapacity16
> data.");
> -            ret = -EINVAL;
> -            goto out;
> -        }
> -        iscsilun->block_size = rc16->block_length;
> -        iscsilun->num_blocks = rc16->returned_lba + 1;
>          break;
>      case TYPE_ROM:
>          task = iscsi_readcapacity10_sync(iscsi, iscsilun->lun, 0, 0);
> @@ -1023,6 +1041,26 @@ static void iscsi_close(BlockDriverState *bs)
>      memset(iscsilun, 0, sizeof(IscsiLun));
>  }
> 
> +static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
> +{
> +    IscsiLun *iscsilun = bs->opaque;
> +    int ret = 0;
> +
> +    if (iscsilun->type != TYPE_DISK) {
> +        return -ENOTSUP;
> +    }
> +
> +    if ((ret = iscsi_disk_readcapacity16_sync(iscsilun))) {
> +        return ret;
> +    }
> +
> +    if (offset > iscsi_getlength(bs)) {
> +        return -EINVAL;
> +    }
> +
> +    return 0;
> +}
> +
>  static int iscsi_has_zero_init(BlockDriverState *bs)
>  {
>      return 0;
> @@ -1093,6 +1131,7 @@ static BlockDriver bdrv_iscsi = {
>      .create_options  = iscsi_create_options,
> 
>      .bdrv_getlength  = iscsi_getlength,
> +    .bdrv_truncate   = iscsi_truncate,
> 
>      .bdrv_aio_readv  = iscsi_aio_readv,
>      .bdrv_aio_writev = iscsi_aio_writev,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]