mirror of
https://github.com/qemu/qemu.git
synced 2025-08-09 01:50:43 +00:00
block/iscsi: use 16 byte CDBs only when necessary
this patch changes the driver to uses 16 Byte CDBs for READ/WRITE only if the target requires 64bit lba addressing. On one hand this saves 6 bytes in each PDU on the other hand it seems that 10 Byte CDBs seems to be much better supported and tested as a recent issue I had with a major storage supplier lined out. For WRITESAME the logic is a bit more tricky as WRITESAME10 with UNMAP was added really late. Thus a fallback to WRITESAME16 is possible if it supports UNMAP and WRITESAME10 not. Signed-off-by: Peter Lieven <pl@kamp.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
fcd470d857
commit
9281fe9eea
@ -65,6 +65,7 @@ typedef struct IscsiLun {
|
|||||||
unsigned char *zeroblock;
|
unsigned char *zeroblock;
|
||||||
unsigned long *allocationmap;
|
unsigned long *allocationmap;
|
||||||
int cluster_sectors;
|
int cluster_sectors;
|
||||||
|
bool use_16_for_rw;
|
||||||
} IscsiLun;
|
} IscsiLun;
|
||||||
|
|
||||||
typedef struct IscsiTask {
|
typedef struct IscsiTask {
|
||||||
@ -381,10 +382,17 @@ static int coroutine_fn iscsi_co_writev(BlockDriverState *bs,
|
|||||||
#endif
|
#endif
|
||||||
iscsi_co_init_iscsitask(iscsilun, &iTask);
|
iscsi_co_init_iscsitask(iscsilun, &iTask);
|
||||||
retry:
|
retry:
|
||||||
iTask.task = iscsi_write16_task(iscsilun->iscsi, iscsilun->lun, lba,
|
if (iscsilun->use_16_for_rw) {
|
||||||
data, num_sectors * iscsilun->block_size,
|
iTask.task = iscsi_write16_task(iscsilun->iscsi, iscsilun->lun, lba,
|
||||||
iscsilun->block_size, 0, 0, 0, 0, 0,
|
data, num_sectors * iscsilun->block_size,
|
||||||
iscsi_co_generic_cb, &iTask);
|
iscsilun->block_size, 0, 0, 0, 0, 0,
|
||||||
|
iscsi_co_generic_cb, &iTask);
|
||||||
|
} else {
|
||||||
|
iTask.task = iscsi_write10_task(iscsilun->iscsi, iscsilun->lun, lba,
|
||||||
|
data, num_sectors * iscsilun->block_size,
|
||||||
|
iscsilun->block_size, 0, 0, 0, 0, 0,
|
||||||
|
iscsi_co_generic_cb, &iTask);
|
||||||
|
}
|
||||||
if (iTask.task == NULL) {
|
if (iTask.task == NULL) {
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -570,14 +578,12 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
|
|||||||
|
|
||||||
iscsi_co_init_iscsitask(iscsilun, &iTask);
|
iscsi_co_init_iscsitask(iscsilun, &iTask);
|
||||||
retry:
|
retry:
|
||||||
switch (iscsilun->type) {
|
if (iscsilun->use_16_for_rw) {
|
||||||
case TYPE_DISK:
|
|
||||||
iTask.task = iscsi_read16_task(iscsilun->iscsi, iscsilun->lun, lba,
|
iTask.task = iscsi_read16_task(iscsilun->iscsi, iscsilun->lun, lba,
|
||||||
num_sectors * iscsilun->block_size,
|
num_sectors * iscsilun->block_size,
|
||||||
iscsilun->block_size, 0, 0, 0, 0, 0,
|
iscsilun->block_size, 0, 0, 0, 0, 0,
|
||||||
iscsi_co_generic_cb, &iTask);
|
iscsi_co_generic_cb, &iTask);
|
||||||
break;
|
} else {
|
||||||
default:
|
|
||||||
iTask.task = iscsi_read10_task(iscsilun->iscsi, iscsilun->lun, lba,
|
iTask.task = iscsi_read10_task(iscsilun->iscsi, iscsilun->lun, lba,
|
||||||
num_sectors * iscsilun->block_size,
|
num_sectors * iscsilun->block_size,
|
||||||
iscsilun->block_size,
|
iscsilun->block_size,
|
||||||
@ -585,7 +591,6 @@ retry:
|
|||||||
0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0,
|
||||||
#endif
|
#endif
|
||||||
iscsi_co_generic_cb, &iTask);
|
iscsi_co_generic_cb, &iTask);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (iTask.task == NULL) {
|
if (iTask.task == NULL) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -921,19 +926,27 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
|
|||||||
struct IscsiTask iTask;
|
struct IscsiTask iTask;
|
||||||
uint64_t lba;
|
uint64_t lba;
|
||||||
uint32_t nb_blocks;
|
uint32_t nb_blocks;
|
||||||
|
bool use_16_for_ws = iscsilun->use_16_for_rw;
|
||||||
|
|
||||||
if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
|
if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->lbp.lbpws) {
|
if (flags & BDRV_REQ_MAY_UNMAP) {
|
||||||
/* WRITE SAME with UNMAP is not supported by the target,
|
if (!use_16_for_ws && !iscsilun->lbp.lbpws10) {
|
||||||
* fall back and try WRITE SAME without UNMAP */
|
/* WRITESAME10 with UNMAP is unsupported try WRITESAME16 */
|
||||||
flags &= ~BDRV_REQ_MAY_UNMAP;
|
use_16_for_ws = true;
|
||||||
|
}
|
||||||
|
if (use_16_for_ws && !iscsilun->lbp.lbpws) {
|
||||||
|
/* WRITESAME16 with UNMAP is not supported by the target,
|
||||||
|
* fall back and try WRITESAME10/16 without UNMAP */
|
||||||
|
flags &= ~BDRV_REQ_MAY_UNMAP;
|
||||||
|
use_16_for_ws = iscsilun->use_16_for_rw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->has_write_same) {
|
if (!(flags & BDRV_REQ_MAY_UNMAP) && !iscsilun->has_write_same) {
|
||||||
/* WRITE SAME without UNMAP is not supported by the target */
|
/* WRITESAME without UNMAP is not supported by the target */
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,10 +959,18 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
|
|||||||
|
|
||||||
iscsi_co_init_iscsitask(iscsilun, &iTask);
|
iscsi_co_init_iscsitask(iscsilun, &iTask);
|
||||||
retry:
|
retry:
|
||||||
if (iscsi_writesame16_task(iscsilun->iscsi, iscsilun->lun, lba,
|
if (use_16_for_ws) {
|
||||||
iscsilun->zeroblock, iscsilun->block_size,
|
iTask.task = iscsi_writesame16_task(iscsilun->iscsi, iscsilun->lun, lba,
|
||||||
nb_blocks, 0, !!(flags & BDRV_REQ_MAY_UNMAP),
|
iscsilun->zeroblock, iscsilun->block_size,
|
||||||
0, 0, iscsi_co_generic_cb, &iTask) == NULL) {
|
nb_blocks, 0, !!(flags & BDRV_REQ_MAY_UNMAP),
|
||||||
|
0, 0, iscsi_co_generic_cb, &iTask);
|
||||||
|
} else {
|
||||||
|
iTask.task = iscsi_writesame10_task(iscsilun->iscsi, iscsilun->lun, lba,
|
||||||
|
iscsilun->zeroblock, iscsilun->block_size,
|
||||||
|
nb_blocks, 0, !!(flags & BDRV_REQ_MAY_UNMAP),
|
||||||
|
0, 0, iscsi_co_generic_cb, &iTask);
|
||||||
|
}
|
||||||
|
if (iTask.task == NULL) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1147,6 +1168,7 @@ static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
|
|||||||
iscsilun->num_blocks = rc16->returned_lba + 1;
|
iscsilun->num_blocks = rc16->returned_lba + 1;
|
||||||
iscsilun->lbpme = rc16->lbpme;
|
iscsilun->lbpme = rc16->lbpme;
|
||||||
iscsilun->lbprz = rc16->lbprz;
|
iscsilun->lbprz = rc16->lbprz;
|
||||||
|
iscsilun->use_16_for_rw = (rc16->returned_lba > 0xffffffff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user