static BlockDriverAIOCB * iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { IscsiLun *iscsilun = bs->opaque; struct iscsi_context *iscsi = iscsilun->iscsi; IscsiAIOCB *acb; size_t qemu_read_size, lun_read_size; int i; qemu_read_size = BDRV_SECTOR_SIZE * (size_t)nb_sectors; acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque); trace_iscsi_aio_readv(iscsi, sector_num, nb_sectors, opaque, acb); acb->iscsilun = iscsilun; acb->qiov = qiov; acb->canceled = 0; acb->read_size = qemu_read_size; acb->buf = NULL; /* If LUN blocksize is bigger than BDRV_BLOCK_SIZE a read from QEMU * may be misaligned to the LUN, so we may need to read some extra * data. */ acb->read_offset = 0; if (iscsilun->block_size > BDRV_SECTOR_SIZE) { uint64_t bdrv_offset = BDRV_SECTOR_SIZE * 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, 0, 0, 0, 0, 0, iscsi_aio_read10_cb, acb); if (acb->task == NULL) { error_report("iSCSI: Failed to send read10 command. %s", iscsi_get_error(iscsi)); qemu_aio_release(acb); return NULL; } for (i = 0; i < acb->qiov->niov; i++) { scsi_task_add_data_in_buffer(acb->task, acb->qiov->iov[i].iov_len, acb->qiov->iov[i].iov_base); } iscsi_set_events(iscsilun); return &acb->common; }
void fill_read_queue(struct client *client) { int num_blocks; while(client->in_flight < max_in_flight && client->pos < client->src_num_blocks) { client->in_flight++; num_blocks = client->src_num_blocks - client->pos; if (num_blocks > blocks_per_io) { num_blocks = blocks_per_io; } if (iscsi_read10_task(client->src_iscsi, client->src_lun, client->pos, num_blocks * client->src_blocksize, client->src_blocksize, 0, 0, 0, 0, 0, read10_cb, client) == NULL) { printf("failed to send read10 command\n"); exit(10); } client->pos += num_blocks; } }