iscsi: Switch to .bdrv_co_block_status()

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the iscsi driver accordingly.  In this case,
it is handy to teach iscsi_co_block_status() to handle a NULL map
and file parameter, even though the block layer passes non-NULL
values, because we also call the function directly.  For now, there
are no optimizations done based on the want_zero flag.

We can also make the simplification of asserting that the block
layer passed in aligned values.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Eric Blake 2018-02-13 14:26:48 -06:00 committed by Kevin Wolf
parent 04a408fbff
commit 92809c3600
1 changed files with 32 additions and 35 deletions

View File

@ -653,36 +653,36 @@ out_unlock:
static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs, static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs,
int64_t sector_num, bool want_zero, int64_t offset,
int nb_sectors, int *pnum, int64_t bytes, int64_t *pnum,
BlockDriverState **file) int64_t *map,
BlockDriverState **file)
{ {
IscsiLun *iscsilun = bs->opaque; IscsiLun *iscsilun = bs->opaque;
struct scsi_get_lba_status *lbas = NULL; struct scsi_get_lba_status *lbas = NULL;
struct scsi_lba_status_descriptor *lbasd = NULL; struct scsi_lba_status_descriptor *lbasd = NULL;
struct IscsiTask iTask; struct IscsiTask iTask;
uint64_t lba; uint64_t lba;
int64_t ret; int ret;
iscsi_co_init_iscsitask(iscsilun, &iTask); iscsi_co_init_iscsitask(iscsilun, &iTask);
if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { assert(QEMU_IS_ALIGNED(offset | bytes, iscsilun->block_size));
ret = -EINVAL;
goto out;
}
/* default to all sectors allocated */ /* default to all sectors allocated */
ret = BDRV_BLOCK_DATA; ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
ret |= (sector_num << BDRV_SECTOR_BITS) | BDRV_BLOCK_OFFSET_VALID; if (map) {
*pnum = nb_sectors; *map = offset;
}
*pnum = bytes;
/* LUN does not support logical block provisioning */ /* LUN does not support logical block provisioning */
if (!iscsilun->lbpme) { if (!iscsilun->lbpme) {
goto out; goto out;
} }
lba = sector_qemu2lun(sector_num, iscsilun); lba = offset / iscsilun->block_size;
qemu_mutex_lock(&iscsilun->mutex); qemu_mutex_lock(&iscsilun->mutex);
retry: retry:
@ -727,12 +727,12 @@ retry:
lbasd = &lbas->descriptors[0]; lbasd = &lbas->descriptors[0];
if (sector_qemu2lun(sector_num, iscsilun) != lbasd->lba) { if (lba != lbasd->lba) {
ret = -EIO; ret = -EIO;
goto out_unlock; goto out_unlock;
} }
*pnum = sector_lun2qemu(lbasd->num_blocks, iscsilun); *pnum = lbasd->num_blocks * iscsilun->block_size;
if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED || if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||
lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) { lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {
@ -743,15 +743,13 @@ retry:
} }
if (ret & BDRV_BLOCK_ZERO) { if (ret & BDRV_BLOCK_ZERO) {
iscsi_allocmap_set_unallocated(iscsilun, sector_num * BDRV_SECTOR_SIZE, iscsi_allocmap_set_unallocated(iscsilun, offset, *pnum);
*pnum * BDRV_SECTOR_SIZE);
} else { } else {
iscsi_allocmap_set_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE, iscsi_allocmap_set_allocated(iscsilun, offset, *pnum);
*pnum * BDRV_SECTOR_SIZE);
} }
if (*pnum > nb_sectors) { if (*pnum > bytes) {
*pnum = nb_sectors; *pnum = bytes;
} }
out_unlock: out_unlock:
qemu_mutex_unlock(&iscsilun->mutex); qemu_mutex_unlock(&iscsilun->mutex);
@ -760,7 +758,7 @@ out:
if (iTask.task != NULL) { if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task); scsi_free_scsi_task(iTask.task);
} }
if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) { if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID && file) {
*file = bs; *file = bs;
} }
return ret; return ret;
@ -800,25 +798,24 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
nb_sectors * BDRV_SECTOR_SIZE) && nb_sectors * BDRV_SECTOR_SIZE) &&
!iscsi_allocmap_is_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE, !iscsi_allocmap_is_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
nb_sectors * BDRV_SECTOR_SIZE)) { nb_sectors * BDRV_SECTOR_SIZE)) {
int pnum; int64_t pnum;
BlockDriverState *file;
/* check the block status from the beginning of the cluster /* check the block status from the beginning of the cluster
* containing the start sector */ * containing the start sector */
int cluster_sectors = iscsilun->cluster_size >> BDRV_SECTOR_BITS; int64_t head;
int head; int ret;
int64_t ret;
assert(cluster_sectors); assert(iscsilun->cluster_size);
head = sector_num % cluster_sectors; head = (sector_num * BDRV_SECTOR_SIZE) % iscsilun->cluster_size;
ret = iscsi_co_get_block_status(bs, sector_num - head, ret = iscsi_co_block_status(bs, true,
BDRV_REQUEST_MAX_SECTORS, &pnum, sector_num * BDRV_SECTOR_SIZE - head,
&file); BDRV_REQUEST_MAX_BYTES, &pnum, NULL, NULL);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
/* if the whole request falls into an unallocated area we can avoid /* if the whole request falls into an unallocated area we can avoid
* reading and directly return zeroes instead */ * reading and directly return zeroes instead */
if (ret & BDRV_BLOCK_ZERO && pnum >= nb_sectors + head) { if (ret & BDRV_BLOCK_ZERO &&
pnum >= nb_sectors * BDRV_SECTOR_SIZE + head) {
qemu_iovec_memset(iov, 0, 0x00, iov->size); qemu_iovec_memset(iov, 0, 0x00, iov->size);
return 0; return 0;
} }
@ -2218,7 +2215,7 @@ static BlockDriver bdrv_iscsi = {
.bdrv_truncate = iscsi_truncate, .bdrv_truncate = iscsi_truncate,
.bdrv_refresh_limits = iscsi_refresh_limits, .bdrv_refresh_limits = iscsi_refresh_limits,
.bdrv_co_get_block_status = iscsi_co_get_block_status, .bdrv_co_block_status = iscsi_co_block_status,
.bdrv_co_pdiscard = iscsi_co_pdiscard, .bdrv_co_pdiscard = iscsi_co_pdiscard,
.bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes, .bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes,
.bdrv_co_readv = iscsi_co_readv, .bdrv_co_readv = iscsi_co_readv,
@ -2253,7 +2250,7 @@ static BlockDriver bdrv_iser = {
.bdrv_truncate = iscsi_truncate, .bdrv_truncate = iscsi_truncate,
.bdrv_refresh_limits = iscsi_refresh_limits, .bdrv_refresh_limits = iscsi_refresh_limits,
.bdrv_co_get_block_status = iscsi_co_get_block_status, .bdrv_co_block_status = iscsi_co_block_status,
.bdrv_co_pdiscard = iscsi_co_pdiscard, .bdrv_co_pdiscard = iscsi_co_pdiscard,
.bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes, .bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes,
.bdrv_co_readv = iscsi_co_readv, .bdrv_co_readv = iscsi_co_readv,