Message ID | 1337681405-11282-1-git-send-email-ronniesahlberg@gmail.com |
---|---|
State | New |
Headers | show |
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 <ronniesahlberg@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
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
This allows using LUNs bigger than 2TB. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com> --- block/iscsi.c | 101 ++++++++++++++++++++++++++++++++++++++++---------------- trace-events | 4 +- 2 files changed, 74 insertions(+), 31 deletions(-)