Re: [Qemu-devel] [PATCH] Fix iSCSI crash on SG_IO with an iovector
Il 25/06/2013 11:24, Stefan Hajnoczi ha scritto: > On Mon, Jun 24, 2013 at 04:40:11PM +0200, Paolo Bonzini wrote: >> Il 23/06/2013 17:07, Ronnie Sahlberg ha scritto: >>> 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 >>> --- >>> block/iscsi.c | 56 >>> +--- >>> 1 files changed, 49 insertions(+), 7 deletions(-) >> >> Cc: qemu-sta...@nongnu.org >> >> Will apply to scsi-next in the next few days. > > Paolo, there are small whitespace issues that you might like to fix when > merging: Yup, will do. Paolo >>> +} else { >>> +#if defined(LIBISCSI_FEATURE_IOVECTOR) >>> + scsi_task_set_iov_out(acb->task, >>> + (struct scsi_iovec *) acb->ioh->dxferp, >>> + acb->ioh->iovec_count); > > Should be 4-space indentation. > >>> + #else > > Space before #else? >
Re: [Qemu-devel] [PATCH] Fix iSCSI crash on SG_IO with an iovector
On Mon, Jun 24, 2013 at 04:40:11PM +0200, Paolo Bonzini wrote: > Il 23/06/2013 17:07, Ronnie Sahlberg ha scritto: > > 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 > > --- > > block/iscsi.c | 56 > > +--- > > 1 files changed, 49 insertions(+), 7 deletions(-) > > Cc: qemu-sta...@nongnu.org > > Will apply to scsi-next in the next few days. Paolo, there are small whitespace issues that you might like to fix when merging: > > +} else { > > +#if defined(LIBISCSI_FEATURE_IOVECTOR) > > + scsi_task_set_iov_out(acb->task, > > + (struct scsi_iovec *) acb->ioh->dxferp, > > + acb->ioh->iovec_count); Should be 4-space indentation. > > + #else Space before #else?
Re: [Qemu-devel] [PATCH] Fix iSCSI crash on SG_IO with an iovector
On Fri, Jun 21, 2013 at 06:37:18PM -0700, Ronnie Sahlberg wrote: Looks fine except these whitespace issues: > @@ -727,14 +730,36 @@ 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, Indentation should be 4 spaces. > + (struct scsi_iovec *) acb->ioh->dxferp, > + acb->ioh->iovec_count); > + #else Space before #else?
Re: [Qemu-devel] [PATCH] Fix iSCSI crash on SG_IO with an iovector
Il 23/06/2013 17:07, Ronnie Sahlberg ha scritto: > 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 > --- > block/iscsi.c | 56 +--- > 1 files changed, 49 insertions(+), 7 deletions(-) Cc: qemu-sta...@nongnu.org Will apply to scsi-next in the next few days. Paolo > diff --git a/block/iscsi.c b/block/iscsi.c > index 0bbf0b1..dca38c4 100644 > --- a/block/iscsi.c > +++ b/block/iscsi.c > @@ -651,6 +651,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 +730,36 @@ 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 > +int i; > +char *buf; > +struct scsi_iovec *iov = (struct scsi_iovec *)acb->ioh->dxferp; > + > +acb->buf = g_malloc(acb->ioh->dxfer_len); > +buf = (char *)acb->buf; > +for (i = 0; i < acb->ioh->iovec_count; i++) { > +memcpy(buf, iov[i].iov_base, iov[i].iov_len); > +buf += iov[i].iov_len; > +} > +data.data = acb->buf; > +data.size = 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 +768,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 scsi_iovec *iov = (struct scsi_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); >
Re: [Qemu-devel] [PATCH] Fix iSCSI crash on SG_IO with an iovector
On 06/23/13 17:07, Ronnie Sahlberg wrote: > 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 > --- > block/iscsi.c | 56 +--- > 1 files changed, 49 insertions(+), 7 deletions(-) > > diff --git a/block/iscsi.c b/block/iscsi.c > index 0bbf0b1..dca38c4 100644 > --- a/block/iscsi.c > +++ b/block/iscsi.c > @@ -651,6 +651,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 +730,36 @@ 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 > +int i; > +char *buf; > +struct scsi_iovec *iov = (struct scsi_iovec *)acb->ioh->dxferp; > + > +acb->buf = g_malloc(acb->ioh->dxfer_len); > +buf = (char *)acb->buf; > +for (i = 0; i < acb->ioh->iovec_count; i++) { > +memcpy(buf, iov[i].iov_base, iov[i].iov_len); > +buf += iov[i].iov_len; > +} > +data.data = acb->buf; > +data.size = 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 +768,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 scsi_iovec *iov = (struct scsi_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); > Reviewed-by: Laszlo Ersek
[Qemu-devel] [PATCH] Fix iSCSI crash on SG_IO with an iovector
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 --- block/iscsi.c | 56 +--- 1 files changed, 49 insertions(+), 7 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 0bbf0b1..dca38c4 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -651,6 +651,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 +730,36 @@ 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 +int i; +char *buf; +struct scsi_iovec *iov = (struct scsi_iovec *)acb->ioh->dxferp; + +acb->buf = g_malloc(acb->ioh->dxfer_len); +buf = (char *)acb->buf; +for (i = 0; i < acb->ioh->iovec_count; i++) { +memcpy(buf, iov[i].iov_base, iov[i].iov_len); +buf += iov[i].iov_len; +} +data.data = acb->buf; +data.size = 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 +768,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 scsi_iovec *iov = (struct scsi_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.7.3.1
Re: [Qemu-devel] [PATCH] Fix iSCSI crash on SG_IO with an iovector
On 06/22/13 03:37, Ronnie Sahlberg wrote: > 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 > --- > block/iscsi.c | 56 +--- > 1 files changed, 49 insertions(+), 7 deletions(-) Looks okay to me, but of course I'm not too familiar with this code. You (or the maintainer with jurisdiction) might want to change the commit message: - check the iovec_count and if it is > 1 then we need to pass an array + check the iovec_count and if it is >= 1 then we need to pass an array But I won't insist on a repost naturally! I assume you tested the code for both definednesses of LIBISCSI_FEATURE_IOVECTOR. Reviewed-by: Laszlo Ersek Thanks Laszlo > > diff --git a/block/iscsi.c b/block/iscsi.c > index 0bbf0b1..cbe2e8f 100644 > --- a/block/iscsi.c > +++ b/block/iscsi.c > @@ -651,6 +651,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 +730,36 @@ 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 > +int i; > +char *buf; > +struct scsi_iovec *iov = (struct scsi_iovec *)acb->ioh->dxferp; > + > +acb->buf = g_malloc(acb->ioh->dxfer_len); > +buf = acb->buf; > +for (i = 0; i < acb->ioh->iovec_count; i++) { > +memcpy(buf, iov[i].iov_base, iov[i].iov_len); > +buf += iov[i].iov_len; > +} > +data.data = acb->buf; > +data.size = 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 +768,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 scsi_iovec *iov = (struct scsi_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); >
[Qemu-devel] [PATCH] Fix iSCSI crash on SG_IO with an iovector
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 --- block/iscsi.c | 56 +--- 1 files changed, 49 insertions(+), 7 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 0bbf0b1..cbe2e8f 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -651,6 +651,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 +730,36 @@ 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 +int i; +char *buf; +struct scsi_iovec *iov = (struct scsi_iovec *)acb->ioh->dxferp; + +acb->buf = g_malloc(acb->ioh->dxfer_len); +buf = acb->buf; +for (i = 0; i < acb->ioh->iovec_count; i++) { +memcpy(buf, iov[i].iov_base, iov[i].iov_len); +buf += iov[i].iov_len; +} +data.data = acb->buf; +data.size = 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 +768,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 scsi_iovec *iov = (struct scsi_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.7.3.1
[Qemu-devel] [PATCH] Fix iSCSI crash on SG_IO with an iovector
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 --- block/iscsi.c | 31 --- 1 files changed, 24 insertions(+), 7 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 0bbf0b1..2d1cb4e 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -727,25 +727,42 @@ 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; +} } 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); return NULL; } +/* We got an iovector for writing to the target */ +if (acb->task->xfer_dir == SCSI_XFER_WRITE) { +if (acb->ioh->iovec_count > 0) { +scsi_task_set_iov_out(acb->task, + (struct scsi_iovec *) acb->ioh->dxferp, + acb->ioh->iovec_count); +} +} + /* 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 { +scsi_task_set_iov_in(acb->task, + (struct scsi_iovec *) acb->ioh->dxferp, + acb->ioh->iovec_count); +} } iscsi_set_events(iscsilun); -- 1.7.3.1