Il 22/05/2012 12:10, Ronnie Sahlberg ha scritto: > This allows using LUNs bigger than 2TB.
Applied to scsi-next for 1.2, thanks. Paolo > Signed-off-by: Ronnie Sahlberg <ronniesahlb...@gmail.com> > --- > block/iscsi.c | 101 ++++++++++++++++++++++++++++++++++++++++---------------- > trace-events | 4 +- > 2 files changed, 74 insertions(+), 31 deletions(-) > > diff --git a/block/iscsi.c b/block/iscsi.c > index f956824..ed1ad7b 100644 > --- a/block/iscsi.c > +++ b/block/iscsi.c > @@ -25,6 +25,7 @@ > #include "config-host.h" > > #include <poll.h> > +#include <arpa/inet.h> > #include "qemu-common.h" > #include "qemu-error.h" > #include "block_int.h" > @@ -168,12 +169,12 @@ iscsi_readv_writev_bh_cb(void *p) > > > static void > -iscsi_aio_write10_cb(struct iscsi_context *iscsi, int status, > +iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status, > void *command_data, void *opaque) > { > IscsiAIOCB *acb = opaque; > > - trace_iscsi_aio_write10_cb(iscsi, status, acb, acb->canceled); > + trace_iscsi_aio_write16_cb(iscsi, status, acb, acb->canceled); > > g_free(acb->buf); > > @@ -186,7 +187,7 @@ iscsi_aio_write10_cb(struct iscsi_context *iscsi, int > status, > > acb->status = 0; > if (status < 0) { > - error_report("Failed to write10 data to iSCSI lun. %s", > + error_report("Failed to write16 data to iSCSI lun. %s", > iscsi_get_error(iscsi)); > acb->status = -EIO; > } > @@ -211,12 +212,9 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t > sector_num, > struct iscsi_context *iscsi = iscsilun->iscsi; > IscsiAIOCB *acb; > size_t size; > - int fua = 0; > - > - /* set FUA on writes when cache mode is write through */ > - if (!(bs->open_flags & BDRV_O_CACHE_WB)) { > - fua = 1; > - } > + uint32_t num_sectors; > + uint64_t lba; > + struct iscsi_data data; > > acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque); > trace_iscsi_aio_writev(iscsi, sector_num, nb_sectors, opaque, acb); > @@ -226,18 +224,44 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t > sector_num, > > acb->canceled = 0; > > - /* XXX we should pass the iovec to write10 to avoid the extra copy */ > + /* XXX we should pass the iovec to write16 to avoid the extra copy */ > /* this will allow us to get rid of 'buf' completely */ > size = nb_sectors * BDRV_SECTOR_SIZE; > acb->buf = g_malloc(size); > qemu_iovec_to_buffer(acb->qiov, acb->buf); > - acb->task = iscsi_write10_task(iscsi, iscsilun->lun, acb->buf, size, > - sector_qemu2lun(sector_num, iscsilun), > - fua, 0, iscsilun->block_size, > - iscsi_aio_write10_cb, acb); > + > + > + acb->task = malloc(sizeof(struct scsi_task)); > if (acb->task == NULL) { > - error_report("iSCSI: Failed to send write10 command. %s", > - iscsi_get_error(iscsi)); > + error_report("iSCSI: Failed to allocate task for scsi WRITE16 " > + "command. %s", iscsi_get_error(iscsi)); > + qemu_aio_release(acb); > + return NULL; > + } > + memset(acb->task, 0, sizeof(struct scsi_task)); > + > + acb->task->xfer_dir = SCSI_XFER_WRITE; > + acb->task->cdb_size = 16; > + acb->task->cdb[0] = 0x8a; > + if (!(bs->open_flags & BDRV_O_CACHE_WB)) { > + /* set FUA on writes when cache mode is write through */ > + acb->task->cdb[1] |= 0x04; > + } > + lba = sector_qemu2lun(sector_num, iscsilun); > + *(uint32_t *)&acb->task->cdb[2] = htonl(lba >> 32); > + *(uint32_t *)&acb->task->cdb[6] = htonl(lba & 0xffffffff); > + num_sectors = size / iscsilun->block_size; > + *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors); > + acb->task->expxferlen = size; > + > + data.data = acb->buf; > + data.size = size; > + > + if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task, > + iscsi_aio_write16_cb, > + &data, > + acb) != 0) { > + scsi_free_scsi_task(acb->task); > g_free(acb->buf); > qemu_aio_release(acb); > return NULL; > @@ -249,12 +273,12 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t > sector_num, > } > > static void > -iscsi_aio_read10_cb(struct iscsi_context *iscsi, int status, > +iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status, > void *command_data, void *opaque) > { > IscsiAIOCB *acb = opaque; > > - trace_iscsi_aio_read10_cb(iscsi, status, acb, acb->canceled); > + trace_iscsi_aio_read16_cb(iscsi, status, acb, acb->canceled); > > if (acb->canceled != 0) { > qemu_aio_release(acb); > @@ -265,7 +289,7 @@ iscsi_aio_read10_cb(struct iscsi_context *iscsi, int > status, > > acb->status = 0; > if (status != 0) { > - error_report("Failed to read10 data from iSCSI lun. %s", > + error_report("Failed to read16 data from iSCSI lun. %s", > iscsi_get_error(iscsi)); > acb->status = -EIO; > } > @@ -284,8 +308,10 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num, > IscsiLun *iscsilun = bs->opaque; > struct iscsi_context *iscsi = iscsilun->iscsi; > IscsiAIOCB *acb; > - size_t qemu_read_size, lun_read_size; > + size_t qemu_read_size; > int i; > + uint64_t lba; > + uint32_t num_sectors; > > qemu_read_size = BDRV_SECTOR_SIZE * (size_t)nb_sectors; > > @@ -310,16 +336,33 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t > sector_num, > acb->read_offset = bdrv_offset % iscsilun->block_size; > } > > - lun_read_size = (qemu_read_size + iscsilun->block_size > - + acb->read_offset - 1) > - / iscsilun->block_size * iscsilun->block_size; > - acb->task = iscsi_read10_task(iscsi, iscsilun->lun, > - sector_qemu2lun(sector_num, iscsilun), > - lun_read_size, iscsilun->block_size, > - iscsi_aio_read10_cb, acb); > + num_sectors = (qemu_read_size + iscsilun->block_size > + + acb->read_offset - 1) > + / iscsilun->block_size; > + > + acb->task = malloc(sizeof(struct scsi_task)); > if (acb->task == NULL) { > - error_report("iSCSI: Failed to send read10 command. %s", > - iscsi_get_error(iscsi)); > + error_report("iSCSI: Failed to allocate task for scsi READ16 " > + "command. %s", iscsi_get_error(iscsi)); > + qemu_aio_release(acb); > + return NULL; > + } > + memset(acb->task, 0, sizeof(struct scsi_task)); > + > + acb->task->xfer_dir = SCSI_XFER_READ; > + acb->task->cdb_size = 16; > + acb->task->cdb[0] = 0x88; > + lba = sector_qemu2lun(sector_num, iscsilun); > + *(uint32_t *)&acb->task->cdb[2] = htonl(lba >> 32); > + *(uint32_t *)&acb->task->cdb[6] = htonl(lba & 0xffffffff); > + *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors); > + acb->task->expxferlen = qemu_read_size; > + > + if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task, > + iscsi_aio_read16_cb, > + NULL, > + acb) != 0) { > + scsi_free_scsi_task(acb->task); > qemu_aio_release(acb); > return NULL; > } > diff --git a/trace-events b/trace-events > index 87cb96c..45c6bc1 100644 > --- a/trace-events > +++ b/trace-events > @@ -602,9 +602,9 @@ escc_kbd_command(int val) "Command %d" > escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d > buttons=%01x" > > # block/iscsi.c > -iscsi_aio_write10_cb(void *iscsi, int status, void *acb, int canceled) > "iscsi %p status %d acb %p canceled %d" > +iscsi_aio_write16_cb(void *iscsi, int status, void *acb, int canceled) > "iscsi %p status %d acb %p canceled %d" > iscsi_aio_writev(void *iscsi, int64_t sector_num, int nb_sectors, void > *opaque, void *acb) "iscsi %p sector_num %"PRId64" nb_sectors %d opaque %p > acb %p" > -iscsi_aio_read10_cb(void *iscsi, int status, void *acb, int canceled) "iscsi > %p status %d acb %p canceled %d" > +iscsi_aio_read16_cb(void *iscsi, int status, void *acb, int canceled) "iscsi > %p status %d acb %p canceled %d" > iscsi_aio_readv(void *iscsi, int64_t sector_num, int nb_sectors, void > *opaque, void *acb) "iscsi %p sector_num %"PRId64" nb_sectors %d opaque %p > acb %p" > > # hw/esp.c