qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: qemu-stable@nongnu.org, Ronnie Sahlberg <ronniesahlberg@gmail.com>
Subject: [Qemu-devel] [PULL 1/5] Fix iSCSI crash on SG_IO with an iovector
Date: Wed, 17 Jul 2013 17:05:20 +0200	[thread overview]
Message-ID: <1374073524-8469-2-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1374073524-8469-1-git-send-email-pbonzini@redhat.com>

From: Ronnie Sahlberg <ronniesahlberg@gmail.com>

Don't assume that SG_IO is always invoked with a simple buffer,
check the iovec_count and if it is >= 1 then we need to pass an array
of iovectors to libiscsi instead of just a plain buffer.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/iscsi.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 44 insertions(+), 7 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index 0bbf0b1..fa5252c 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -32,6 +32,7 @@
 #include "block/block_int.h"
 #include "trace.h"
 #include "block/scsi.h"
+#include "qemu/iov.h"
 
 #include <iscsi/iscsi.h>
 #include <iscsi/scsi-lowlevel.h>
@@ -651,6 +652,9 @@ iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
 {
     IscsiAIOCB *acb = opaque;
 
+    g_free(acb->buf);
+    acb->buf = NULL;
+
     if (acb->canceled != 0) {
         return;
     }
@@ -727,14 +731,30 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
     memcpy(&acb->task->cdb[0], acb->ioh->cmdp, acb->ioh->cmd_len);
     acb->task->expxferlen = acb->ioh->dxfer_len;
 
+    data.size = 0;
     if (acb->task->xfer_dir == SCSI_XFER_WRITE) {
-        data.data = acb->ioh->dxferp;
-        data.size = acb->ioh->dxfer_len;
+        if (acb->ioh->iovec_count == 0) {
+            data.data = acb->ioh->dxferp;
+            data.size = acb->ioh->dxfer_len;
+        } else {
+#if defined(LIBISCSI_FEATURE_IOVECTOR)
+            scsi_task_set_iov_out(acb->task,
+                                 (struct scsi_iovec *) acb->ioh->dxferp,
+                                 acb->ioh->iovec_count);
+#else
+            struct iovec *iov = (struct iovec *)acb->ioh->dxferp;
+
+            acb->buf = g_malloc(acb->ioh->dxfer_len);
+            data.data = acb->buf;
+            data.size = iov_to_buf(iov, acb->ioh->iovec_count, 0,
+                                   acb->buf, acb->ioh->dxfer_len);
+#endif
+        }
     }
+
     if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
                                  iscsi_aio_ioctl_cb,
-                                 (acb->task->xfer_dir == SCSI_XFER_WRITE) ?
-                                     &data : NULL,
+                                 (data.size > 0) ? &data : NULL,
                                  acb) != 0) {
         scsi_free_scsi_task(acb->task);
         qemu_aio_release(acb);
@@ -743,9 +763,26 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
 
     /* tell libiscsi to read straight into the buffer we got from ioctl */
     if (acb->task->xfer_dir == SCSI_XFER_READ) {
-        scsi_task_add_data_in_buffer(acb->task,
-                                     acb->ioh->dxfer_len,
-                                     acb->ioh->dxferp);
+        if (acb->ioh->iovec_count == 0) {
+            scsi_task_add_data_in_buffer(acb->task,
+                                         acb->ioh->dxfer_len,
+                                         acb->ioh->dxferp);
+        } else {
+#if defined(LIBISCSI_FEATURE_IOVECTOR)
+            scsi_task_set_iov_in(acb->task,
+                                 (struct scsi_iovec *) acb->ioh->dxferp,
+                                 acb->ioh->iovec_count);
+#else
+            int i;
+            for (i = 0; i < acb->ioh->iovec_count; i++) {
+                struct iovec *iov = (struct iovec *)acb->ioh->dxferp;
+
+                scsi_task_add_data_in_buffer(acb->task,
+                    iov[i].iov_len,
+                    iov[i].iov_base);
+            }
+#endif
+        }
     }
 
     iscsi_set_events(iscsilun);
-- 
1.8.1.4

  reply	other threads:[~2013-07-17 15:09 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-17 15:05 [Qemu-devel] [PULL 0/5] SCSI changes for 2013-07-17 Paolo Bonzini
2013-07-17 15:05 ` Paolo Bonzini [this message]
2013-07-17 15:05 ` [Qemu-devel] [PULL 2/5] iscsi: fix -ENOSPC in iscsi_create() Paolo Bonzini
2013-07-17 15:05 ` [Qemu-devel] [PULL 3/5] iscsi: remove support for misaligned nb_sectors in aio_readv Paolo Bonzini
2013-07-17 15:05 ` [Qemu-devel] [PULL 4/5] iscsi: assert that sectors are aligned to LUN blocksize Paolo Bonzini
2013-07-17 15:05 ` [Qemu-devel] [PULL 5/5] iscsi: factor out sector conversions Paolo Bonzini

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=1374073524-8469-2-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-stable@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 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).