All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] iSCSI: Add support for SG_IO in bdrv_ioctl()
Date: Tue, 21 Aug 2012 09:00:15 +0200	[thread overview]
Message-ID: <503331FF.1070908@redhat.com> (raw)
In-Reply-To: <1345507175-7248-2-git-send-email-ronniesahlberg@gmail.com>

Il 21/08/2012 01:59, Ronnie Sahlberg ha scritto:
> We need to support SG_IO in the synchronous bdrv_ioctl() since this
> is used by scsi-block
> 
> Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
> ---
>  block/iscsi.c |  109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 108 insertions(+), 1 deletions(-)
> 
> diff --git a/block/iscsi.c b/block/iscsi.c
> index 993a86d..9e98bfe 100644
> --- a/block/iscsi.c
> +++ b/block/iscsi.c
> @@ -548,7 +548,8 @@ iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
>  
>  #define SG_ERR_DRIVER_SENSE    0x08
>  
> -    if (status == SCSI_STATUS_CHECK_CONDITION && acb->task->datain.size >= 2) {
> +    if (status == SCSI_STATUS_CHECK_CONDITION
> +    && acb->task->datain.size >= 2) {
>          int ss;
>  
>          acb->ioh->driver_status |= SG_ERR_DRIVER_SENSE;
> @@ -633,9 +634,53 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
>      return &acb->common;
>  }
>  
> +struct IoctlTask {
> +    int status;
> +    int complete;
> +    sg_io_hdr_t *ioh;
> +    struct scsi_task *task;
> +};
> +
> +static void
> +iscsi_ioctl_cb(struct iscsi_context *iscsi, int status,
> +                     void *command_data, void *opaque)
> +{
> +    struct IoctlTask *itask = opaque;
> +
> +    if (status < 0) {
> +        error_report("Failed to ioctl(SG_IO) to iSCSI lun. %s",
> +                     iscsi_get_error(iscsi));
> +        itask->status = -EIO;
> +    }
> +
> +    itask->ioh->driver_status = 0;
> +    itask->ioh->host_status   = 0;
> +    itask->ioh->resid         = 0;
> +
> +#define SG_ERR_DRIVER_SENSE    0x08
> +
> +    if (status == SCSI_STATUS_CHECK_CONDITION
> +    && itask->task->datain.size >= 2) {
> +        int ss;
> +
> +        itask->ioh->driver_status |= SG_ERR_DRIVER_SENSE;
> +
> +        itask->ioh->sb_len_wr = itask->task->datain.size - 2;
> +        ss = (itask->ioh->mx_sb_len >= itask->ioh->sb_len_wr) ?
> +             itask->ioh->mx_sb_len : itask->ioh->sb_len_wr;
> +        memcpy(itask->ioh->sbp, &itask->task->datain.data[2], ss);
> +    }
> +
> +    itask->complete = 1;
> +}
> +
>  static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
>  {
>      IscsiLun *iscsilun = bs->opaque;
> +    struct iscsi_context *iscsi = iscsilun->iscsi;
> +    struct IoctlTask itask;
> +    struct scsi_task *task;
> +    struct iscsi_data data;
>  
>      switch (req) {
>      case SG_GET_VERSION_NUM:
> @@ -644,6 +689,68 @@ static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
>      case SG_GET_SCSI_ID:
>          ((struct sg_scsi_id *)buf)->scsi_type = iscsilun->type;
>          break;
> +    case SG_IO:
> +        itask.ioh = buf;
> +        task = malloc(sizeof(struct scsi_task));
> +        if (task == NULL) {
> +            error_report("iSCSI: Failed to allocate task for scsi command. %s",
> +                         iscsi_get_error(iscsi));
> +            return -1;
> +        }
> +        memset(task, 0, sizeof(struct scsi_task));
> +
> +        switch (itask.ioh->dxfer_direction) {
> +        case SG_DXFER_TO_DEV:
> +            task->xfer_dir = SCSI_XFER_WRITE;
> +            break;
> +        case SG_DXFER_FROM_DEV:
> +            task->xfer_dir = SCSI_XFER_READ;
> +            break;
> +        default:
> +            task->xfer_dir = SCSI_XFER_NONE;
> +            break;
> +        }
> +        task->cdb_size = itask.ioh->cmd_len;
> +        memcpy(&task->cdb[0], itask.ioh->cmdp, itask.ioh->cmd_len);
> +        task->expxferlen = itask.ioh->dxfer_len;
> +
> +        if (task->xfer_dir == SCSI_XFER_WRITE) {
> +            data.data = itask.ioh->dxferp;
> +            data.size = itask.ioh->dxfer_len;
> +        }
> +
> +        if (iscsi_scsi_command_async(iscsi, iscsilun->lun, task,
> +                                     iscsi_ioctl_cb,
> +                                     (task->xfer_dir == SCSI_XFER_WRITE) ?
> +                                         &data : NULL,
> +                                     &itask) != 0) {
> +            scsi_free_scsi_task(task);
> +            return -1;
> +        }
> +
> +        /* tell libiscsi to read straight into the buffer we got from ioctl */
> +        if (task->xfer_dir == SCSI_XFER_READ) {
> +            scsi_task_add_data_in_buffer(task,
> +                                         itask.ioh->dxfer_len,
> +                                         itask.ioh->dxferp);
> +        }
> +
> +        itask.complete = 0;
> +        itask.status   = 0;
> +        itask.task     = task;
> +        while (!itask.complete) {
> +            iscsi_set_events(iscsilun);
> +            qemu_aio_wait();
> +        }
> +        scsi_free_scsi_task(task);
> +
> +        if (itask.status != 0) {
> +            error_report("iSCSI: Failed to send async command to target : %s",
> +                         iscsi_get_error(iscsi));
> +            return -1;
> +        }
> +
> +        return 0;
>      default:
>          return -1;
>      }
> 

Lots of duplicate code, can you just call bdrv_aio_ioctl with a callback
that is as simple as

    int *p_status = opaque;
    *p_status = status;

and then

    status = -EINPROGRESS;
    bdrv_aio_ioctl(..., ioctl_cb, &status);
    while (status == -EINPROGRESS) {
        qemu_aio_wait();
    }

?

The iscsi_set_events should not be needed because bdrv_aio_ioctl calls it.

Paolo

      reply	other threads:[~2012-08-21  7:00 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-20 23:59 [Qemu-devel] [PATCH] iSCSI: Add support for SG_IO to bdrv_ioctl()/iscsi_ioctl() Ronnie Sahlberg
2012-08-20 23:59 ` [Qemu-devel] [PATCH] iSCSI: Add support for SG_IO in bdrv_ioctl() Ronnie Sahlberg
2012-08-21  7:00   ` Paolo Bonzini [this message]

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=503331FF.1070908@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=ronniesahlberg@gmail.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.