void read10_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data) { struct client *client = (struct client *)private_data; struct scsi_task *task = command_data; struct write_task *wt; if (status == SCSI_STATUS_CHECK_CONDITION) { printf("Read10 failed with sense key:%d ascq:%04x\n", task->sense.key, task->sense.ascq); exit(10); } wt = malloc(sizeof(struct write_task)); wt->rt = task; wt->client = client; if (iscsi_write10_task(client->dst_iscsi, client->dst_lun, task->params.read10.lba, task->datain.data, task->datain.size, client->dst_blocksize, 0, 0, 0, 0, 0, write10_cb, wt) == NULL) { printf("failed to send read10 command\n"); scsi_free_scsi_task(task); exit(10); } }
static BlockDriverAIOCB * iscsi_aio_writev(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 size; int fua = 0; /* set FUA on writes when cache mode is write through */ if (!(bs->open_flags & BDRV_O_CACHE_WB)) { fua = 1; } acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque); trace_iscsi_aio_writev(iscsi, sector_num, nb_sectors, opaque, acb); acb->iscsilun = iscsilun; acb->qiov = qiov; acb->canceled = 0; /* XXX we should pass the iovec to write10 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, sector_qemu2lun(sector_num, iscsilun), acb->buf, size, iscsilun->block_size, 0, 0, fua, 0, 0, iscsi_aio_write10_cb, acb); if (acb->task == NULL) { error_report("iSCSI: Failed to send write10 command. %s", iscsi_get_error(iscsi)); g_free(acb->buf); qemu_aio_release(acb); return NULL; } iscsi_set_events(iscsilun); return &acb->common; }