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