static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
                      Error **errp)
{
    IscsiLun *iscsilun = bs->opaque;
    struct iscsi_context *iscsi = NULL;
    struct iscsi_url *iscsi_url = NULL;
    struct scsi_task *task = NULL;
    struct scsi_inquiry_standard *inq = NULL;
    struct scsi_inquiry_supported_pages *inq_vpd;
    char *initiator_name = NULL;
    QemuOpts *opts;
    Error *local_err = NULL;
    const char *filename;
    int i, ret;
    if ((BDRV_SECTOR_SIZE % 512) != 0) {
        error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
                   "BDRV_SECTOR_SIZE(%lld) is not a multiple "
                   "of 512", BDRV_SECTOR_SIZE);
        return -EINVAL;
    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
    qemu_opts_absorb_qdict(opts, options, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    filename = qemu_opt_get(opts, "filename");
    iscsi_url = iscsi_parse_full_url(iscsi, filename);
    if (iscsi_url == NULL) {
        error_setg(errp, "Failed to parse URL : %s", filename);
        ret = -EINVAL;
    memset(iscsilun, 0, sizeof(IscsiLun));
    initiator_name = parse_initiator_name(iscsi_url->target);
    iscsi = iscsi_create_context(initiator_name);
    if (iscsi == NULL) {
        error_setg(errp, "iSCSI: Failed to create iSCSI context.");
        ret = -ENOMEM;
    if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
        error_setg(errp, "iSCSI: Failed to set target name.");
        ret = -EINVAL;
    if (iscsi_url->user != NULL) {
        ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
                                              iscsi_url->passwd);
        if (ret != 0) {
            error_setg(errp, "Failed to set initiator username and password");
            ret = -EINVAL;
    /* check if we got CHAP username/password via the options */
    parse_chap(iscsi, iscsi_url->target, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
        error_setg(errp, "iSCSI: Failed to set session type to normal.");
        ret = -EINVAL;
    iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
    /* check if we got HEADER_DIGEST via the options */
    parse_header_digest(iscsi, iscsi_url->target, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
        error_setg(errp, "iSCSI: Failed to connect to LUN : %s",
            iscsi_get_error(iscsi));
        ret = -EINVAL;
    iscsilun->iscsi = iscsi;
    iscsilun->aio_context = bdrv_get_aio_context(bs);
    iscsilun->lun   = iscsi_url->lun;
    iscsilun->has_write_same = true;
    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 0, 0,
                            (void **) &inq, errp);
    if (task == NULL) {
        ret = -EINVAL;
    iscsilun->type = inq->periperal_device_type;
    scsi_free_scsi_task(task);
    task = NULL;
    iscsi_readcapacity_sync(iscsilun, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
    bs->request_alignment = iscsilun->block_size;
    /* We don't have any emulation for devices other than disks and CD-ROMs, so
     * this must be sg ioctl compatible. We force it to be sg, otherwise qemu
     * will try to read from the device to guess the image format.
     */
    if (iscsilun->type != TYPE_DISK && iscsilun->type != TYPE_ROM) {
        bs->sg = 1;
    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
                            SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES,
                            (void **) &inq_vpd, errp);
    if (task == NULL) {
        ret = -EINVAL;
    for (i = 0; i < inq_vpd->num_pages; i++) {
        struct scsi_task *inq_task;
        struct scsi_inquiry_logical_block_provisioning *inq_lbp;
        struct scsi_inquiry_block_limits *inq_bl;
        switch (inq_vpd->pages[i]) {
        case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
                                        SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
                                        (void **) &inq_lbp, errp);
            if (inq_task == NULL) {
                ret = -EINVAL;
            memcpy(&iscsilun->lbp, inq_lbp,
                   sizeof(struct scsi_inquiry_logical_block_provisioning));
            scsi_free_scsi_task(inq_task);
            break;
        case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
                                    SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS,
                                    (void **) &inq_bl, errp);
            if (inq_task == NULL) {
                ret = -EINVAL;
            memcpy(&iscsilun->bl, inq_bl,
                   sizeof(struct scsi_inquiry_block_limits));
            scsi_free_scsi_task(inq_task);
            break;
        default:
            break;
    scsi_free_scsi_task(task);
    task = NULL;
    iscsi_attach_aio_context(bs, iscsilun->aio_context);
    /* Guess the internal cluster (page) size of the iscsi target by the means
     * of opt_unmap_gran. Transfer the unmap granularity only if it has a
     * reasonable size */
    if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 4 * 1024 &&
        iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
        iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
                                     iscsilun->block_size) >> BDRV_SECTOR_BITS;
        if (iscsilun->lbprz && !(bs->open_flags & BDRV_O_NOCACHE)) {
            iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
            if (iscsilun->allocationmap == NULL) {
                ret = -ENOMEM;
out:
    qemu_opts_del(opts);
    g_free(initiator_name);
    if (iscsi_url != NULL) {
        iscsi_destroy_url(iscsi_url);
    if (task != NULL) {
        scsi_free_scsi_task(task);
    if (ret) {
        if (iscsi != NULL) {
            iscsi_destroy_context(iscsi);
        memset(iscsilun, 0, sizeof(IscsiLun));
    return ret;
static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
                      Error **errp)
{
    IscsiLun *iscsilun = bs->opaque;
    struct iscsi_context *iscsi = NULL;
    struct iscsi_url *iscsi_url = NULL;
    struct scsi_task *task = NULL;
    struct scsi_inquiry_standard *inq = NULL;
    struct scsi_inquiry_supported_pages *inq_vpd;
    char *initiator_name = NULL;
    QemuOpts *opts;
    Error *local_err = NULL;
    const char *filename;
    int i, ret;
    if ((BDRV_SECTOR_SIZE % 512) != 0) {
        error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
                   "BDRV_SECTOR_SIZE(%lld) is not a multiple "
                   "of 512", BDRV_SECTOR_SIZE);
        return -EINVAL;
    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
    qemu_opts_absorb_qdict(opts, options, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    filename = qemu_opt_get(opts, "filename");
    iscsi_url = iscsi_parse_full_url(iscsi, filename);
    if (iscsi_url == NULL) {
        error_setg(errp, "Failed to parse URL : %s", filename);
        ret = -EINVAL;
    memset(iscsilun, 0, sizeof(IscsiLun));
    initiator_name = parse_initiator_name(iscsi_url->target);
    iscsi = iscsi_create_context(initiator_name);
    if (iscsi == NULL) {
        error_setg(errp, "iSCSI: Failed to create iSCSI context.");
        ret = -ENOMEM;
    if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
        error_setg(errp, "iSCSI: Failed to set target name.");
        ret = -EINVAL;
    if (iscsi_url->user != NULL) {
        ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
                                              iscsi_url->passwd);
        if (ret != 0) {
            error_setg(errp, "Failed to set initiator username and password");
            ret = -EINVAL;
    
    parse_chap(iscsi, iscsi_url->target, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
        error_setg(errp, "iSCSI: Failed to set session type to normal.");
        ret = -EINVAL;
    iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
    
    parse_header_digest(iscsi, iscsi_url->target, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
        error_setg(errp, "iSCSI: Failed to connect to LUN : %s",
            iscsi_get_error(iscsi));
        ret = -EINVAL;
    iscsilun->iscsi = iscsi;
    iscsilun->aio_context = bdrv_get_aio_context(bs);
    iscsilun->lun   = iscsi_url->lun;
    iscsilun->has_write_same = true;
    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 0, 0,
                            (void **) &inq, errp);
    if (task == NULL) {
        ret = -EINVAL;
    iscsilun->type = inq->periperal_device_type;
    scsi_free_scsi_task(task);
    task = NULL;
    iscsi_readcapacity_sync(iscsilun, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
        ret = -EINVAL;
    bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
    bs->request_alignment = iscsilun->block_size;
    



    if (iscsilun->type != TYPE_DISK && iscsilun->type != TYPE_ROM) {
        bs->sg = 1;
    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
                            SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES,
                            (void **) &inq_vpd, errp);
    if (task == NULL) {
        ret = -EINVAL;
    for (i = 0; i < inq_vpd->num_pages; i++) {
        struct scsi_task *inq_task;
        struct scsi_inquiry_logical_block_provisioning *inq_lbp;
        struct scsi_inquiry_block_limits *inq_bl;
        switch (inq_vpd->pages[i]) {
        case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
                                        SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
                                        (void **) &inq_lbp, errp);
            if (inq_task == NULL) {
                ret = -EINVAL;
            memcpy(&iscsilun->lbp, inq_lbp,
                   sizeof(struct scsi_inquiry_logical_block_provisioning));
            scsi_free_scsi_task(inq_task);
            break;
        case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
                                    SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS,
                                    (void **) &inq_bl, errp);
            if (inq_task == NULL) {
                ret = -EINVAL;
            memcpy(&iscsilun->bl, inq_bl,
                   sizeof(struct scsi_inquiry_block_limits));
            scsi_free_scsi_task(inq_task);
            break;
        default:
            break;
    scsi_free_scsi_task(task);
    task = NULL;
    iscsi_attach_aio_context(bs, iscsilun->aio_context);
    


    if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 4 * 1024 &&
        iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
        iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
                                     iscsilun->block_size) >> BDRV_SECTOR_BITS;
        if (iscsilun->lbprz && !(bs->open_flags & BDRV_O_NOCACHE)) {
            iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
            if (iscsilun->allocationmap == NULL) {
                ret = -ENOMEM;
out:
    qemu_opts_del(opts);
    g_free(initiator_name);
    if (iscsi_url != NULL) {
        iscsi_destroy_url(iscsi_url);
    if (task != NULL) {
        scsi_free_scsi_task(task);
    if (ret) {
        if (iscsi != NULL) {
            iscsi_destroy_context(iscsi);
        memset(iscsilun, 0, sizeof(IscsiLun));
    return ret;
static int FUNC_0(BlockDriverState *VAR_0, QDict *VAR_1, int VAR_2,
                      Error **VAR_3)
{
    IscsiLun *iscsilun = VAR_0->opaque;
    struct iscsi_context *VAR_4 = NULL;
    struct VAR_5 *VAR_5 = NULL;
    struct scsi_task *VAR_6 = NULL;
    struct scsi_inquiry_standard *VAR_7 = NULL;
    struct scsi_inquiry_supported_pages *VAR_8;
    char *VAR_9 = NULL;
    QemuOpts *opts;
    Error *local_err = NULL;
    const char *VAR_10;
    int VAR_11, VAR_12;
    if ((BDRV_SECTOR_SIZE % 512) != 0) {
        error_setg(VAR_3, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
                   "BDRV_SECTOR_SIZE(%lld) is not a multiple "
                   "of 512", BDRV_SECTOR_SIZE);
        return -EINVAL;
    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
    qemu_opts_absorb_qdict(opts, VAR_1, &local_err);
    if (local_err) {
        error_propagate(VAR_3, local_err);
        VAR_12 = -EINVAL;
    VAR_10 = qemu_opt_get(opts, "VAR_10");
    VAR_5 = iscsi_parse_full_url(VAR_4, VAR_10);
    if (VAR_5 == NULL) {
        error_setg(VAR_3, "Failed to parse URL : %s", VAR_10);
        VAR_12 = -EINVAL;
    memset(iscsilun, 0, sizeof(IscsiLun));
    VAR_9 = parse_initiator_name(VAR_5->target);
    VAR_4 = iscsi_create_context(VAR_9);
    if (VAR_4 == NULL) {
        error_setg(VAR_3, "iSCSI: Failed to create iSCSI context.");
        VAR_12 = -ENOMEM;
    if (iscsi_set_targetname(VAR_4, VAR_5->target)) {
        error_setg(VAR_3, "iSCSI: Failed to set target name.");
        VAR_12 = -EINVAL;
    if (VAR_5->user != NULL) {
        VAR_12 = iscsi_set_initiator_username_pwd(VAR_4, VAR_5->user,
                                              VAR_5->passwd);
        if (VAR_12 != 0) {
            error_setg(VAR_3, "Failed to set initiator username and password");
            VAR_12 = -EINVAL;
    
    parse_chap(VAR_4, VAR_5->target, &local_err);
    if (local_err != NULL) {
        error_propagate(VAR_3, local_err);
        VAR_12 = -EINVAL;
    if (iscsi_set_session_type(VAR_4, ISCSI_SESSION_NORMAL) != 0) {
        error_setg(VAR_3, "iSCSI: Failed to set session type to normal.");
        VAR_12 = -EINVAL;
    iscsi_set_header_digest(VAR_4, ISCSI_HEADER_DIGEST_NONE_CRC32C);
    
    parse_header_digest(VAR_4, VAR_5->target, &local_err);
    if (local_err != NULL) {
        error_propagate(VAR_3, local_err);
        VAR_12 = -EINVAL;
    if (iscsi_full_connect_sync(VAR_4, VAR_5->portal, VAR_5->lun) != 0) {
        error_setg(VAR_3, "iSCSI: Failed to connect to LUN : %s",
            iscsi_get_error(VAR_4));
        VAR_12 = -EINVAL;
    iscsilun->VAR_4 = VAR_4;
    iscsilun->aio_context = bdrv_get_aio_context(VAR_0);
    iscsilun->lun   = VAR_5->lun;
    iscsilun->has_write_same = true;
    VAR_6 = iscsi_do_inquiry(iscsilun->VAR_4, iscsilun->lun, 0, 0,
                            (void **) &VAR_7, VAR_3);
    if (VAR_6 == NULL) {
        VAR_12 = -EINVAL;
    iscsilun->type = VAR_7->periperal_device_type;
    scsi_free_scsi_task(VAR_6);
    VAR_6 = NULL;
    iscsi_readcapacity_sync(iscsilun, &local_err);
    if (local_err != NULL) {
        error_propagate(VAR_3, local_err);
        VAR_12 = -EINVAL;
    VAR_0->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
    VAR_0->request_alignment = iscsilun->block_size;
    



    if (iscsilun->type != TYPE_DISK && iscsilun->type != TYPE_ROM) {
        VAR_0->sg = 1;
    VAR_6 = iscsi_do_inquiry(iscsilun->VAR_4, iscsilun->lun, 1,
                            SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES,
                            (void **) &VAR_8, VAR_3);
    if (VAR_6 == NULL) {
        VAR_12 = -EINVAL;
    for (VAR_11 = 0; VAR_11 < VAR_8->num_pages; VAR_11++) {
        struct scsi_task *VAR_13;
        struct scsi_inquiry_logical_block_provisioning *VAR_14;
        struct scsi_inquiry_block_limits *VAR_15;
        switch (VAR_8->pages[VAR_11]) {
        case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
            VAR_13 = iscsi_do_inquiry(iscsilun->VAR_4, iscsilun->lun, 1,
                                        SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
                                        (void **) &VAR_14, VAR_3);
            if (VAR_13 == NULL) {
                VAR_12 = -EINVAL;
            memcpy(&iscsilun->lbp, VAR_14,
                   sizeof(struct scsi_inquiry_logical_block_provisioning));
            scsi_free_scsi_task(VAR_13);
            break;
        case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
            VAR_13 = iscsi_do_inquiry(iscsilun->VAR_4, iscsilun->lun, 1,
                                    SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS,
                                    (void **) &VAR_15, VAR_3);
            if (VAR_13 == NULL) {
                VAR_12 = -EINVAL;
            memcpy(&iscsilun->bl, VAR_15,
                   sizeof(struct scsi_inquiry_block_limits));
            scsi_free_scsi_task(VAR_13);
            break;
        default:
            break;
    scsi_free_scsi_task(VAR_6);
    VAR_6 = NULL;
    iscsi_attach_aio_context(VAR_0, iscsilun->aio_context);
    


    if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 4 * 1024 &&
        iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
        iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
                                     iscsilun->block_size) >> BDRV_SECTOR_BITS;
        if (iscsilun->lbprz && !(VAR_0->open_flags & BDRV_O_NOCACHE)) {
            iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
            if (iscsilun->allocationmap == NULL) {
                VAR_12 = -ENOMEM;
out:
    qemu_opts_del(opts);
    g_free(VAR_9);
    if (VAR_5 != NULL) {
        iscsi_destroy_url(VAR_5);
    if (VAR_6 != NULL) {
        scsi_free_scsi_task(VAR_6);
    if (VAR_12) {
        if (VAR_4 != NULL) {
            iscsi_destroy_context(VAR_4);
        memset(iscsilun, 0, sizeof(IscsiLun));
    return VAR_12;
static int FUNC_0(BlockDriverState *VAR_0, QDict *VAR_1, int VAR_2,
Error **VAR_3)
{ IscsiLun *iscsilun = VAR_0->opaque; struct iscsi_context *VAR_4 = NULL; struct VAR_5 *VAR_5 = NULL; struct scsi_task *VAR_6 = NULL; struct scsi_inquiry_standard *VAR_7 = NULL; struct scsi_inquiry_supported_pages *VAR_8; char *VAR_9 = NULL; QemuOpts *opts; Error *local_err = NULL; const char *VAR_10; int VAR_11, VAR_12; if ((BDRV_SECTOR_SIZE % 512) != 0) { error_setg(VAR_3, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
"BDRV_SECTOR_SIZE(%lld) is not a multiple "
"of 512", BDRV_SECTOR_SIZE); return -EINVAL; opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, VAR_1, &local_err); if (local_err) { error_propagate(VAR_3, local_err); VAR_12 = -EINVAL; VAR_10 = qemu_opt_get(opts, "VAR_10"); VAR_5 = iscsi_parse_full_url(VAR_4, VAR_10); if (VAR_5 == NULL) { error_setg(VAR_3, "Failed to parse URL : %s", VAR_10); VAR_12 = -EINVAL; memset(iscsilun, 0, sizeof(IscsiLun)); VAR_9 = parse_initiator_name(VAR_5->target); VAR_4 = iscsi_create_context(VAR_9); if (VAR_4 == NULL) { error_setg(VAR_3, "iSCSI: Failed to create iSCSI context."); VAR_12 = -ENOMEM; if (iscsi_set_targetname(VAR_4, VAR_5->target)) { error_setg(VAR_3, "iSCSI: Failed to set target name."); VAR_12 = -EINVAL; if (VAR_5->user != NULL) { VAR_12 = iscsi_set_initiator_username_pwd(VAR_4, VAR_5->user,
VAR_5->passwd); if (VAR_12 != 0) { error_setg(VAR_3, "Failed to set initiator username and password"); VAR_12 = -EINVAL; parse_chap(VAR_4, VAR_5->target, &local_err); if (local_err != NULL) { error_propagate(VAR_3, local_err); VAR_12 = -EINVAL; if (iscsi_set_session_type(VAR_4, ISCSI_SESSION_NORMAL) != 0) { error_setg(VAR_3, "iSCSI: Failed to set session type to normal."); VAR_12 = -EINVAL; iscsi_set_header_digest(VAR_4, ISCSI_HEADER_DIGEST_NONE_CRC32C); parse_header_digest(VAR_4, VAR_5->target, &local_err); if (local_err != NULL) { error_propagate(VAR_3, local_err); VAR_12 = -EINVAL; if (iscsi_full_connect_sync(VAR_4, VAR_5->portal, VAR_5->lun) != 0) { error_setg(VAR_3, "iSCSI: Failed to connect to LUN : %s",
iscsi_get_error(VAR_4)); VAR_12 = -EINVAL; iscsilun->VAR_4 = VAR_4; iscsilun->aio_context = bdrv_get_aio_context(VAR_0); iscsilun->lun   = VAR_5->lun; iscsilun->has_write_same = true; VAR_6 = iscsi_do_inquiry(iscsilun->VAR_4, iscsilun->lun, 0, 0,
(void **) &VAR_7, VAR_3); if (VAR_6 == NULL) { VAR_12 = -EINVAL; iscsilun->type = VAR_7->periperal_device_type; scsi_free_scsi_task(VAR_6); VAR_6 = NULL; iscsi_readcapacity_sync(iscsilun, &local_err); if (local_err != NULL) { error_propagate(VAR_3, local_err); VAR_12 = -EINVAL; VAR_0->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun); VAR_0->request_alignment = iscsilun->block_size; if (iscsilun->type != TYPE_DISK && iscsilun->type != TYPE_ROM) { VAR_0->sg = 1; VAR_6 = iscsi_do_inquiry(iscsilun->VAR_4, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES,
(void **) &VAR_8, VAR_3); if (VAR_6 == NULL) { VAR_12 = -EINVAL; for (VAR_11 = 0; VAR_11 < VAR_8->num_pages; VAR_11++) { struct scsi_task *VAR_13; struct scsi_inquiry_logical_block_provisioning *VAR_14; struct scsi_inquiry_block_limits *VAR_15; switch (VAR_8->pages[VAR_11]) { case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
VAR_13 = iscsi_do_inquiry(iscsilun->VAR_4, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
(void **) &VAR_14, VAR_3); if (VAR_13 == NULL) { VAR_12 = -EINVAL; memcpy(&iscsilun->lbp, VAR_14,
sizeof(struct scsi_inquiry_logical_block_provisioning)); scsi_free_scsi_task(VAR_13); break; case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
VAR_13 = iscsi_do_inquiry(iscsilun->VAR_4, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS,
(void **) &VAR_15, VAR_3); if (VAR_13 == NULL) { VAR_12 = -EINVAL; memcpy(&iscsilun->bl, VAR_15,
sizeof(struct scsi_inquiry_block_limits)); scsi_free_scsi_task(VAR_13); break; default:
break; scsi_free_scsi_task(VAR_6); VAR_6 = NULL; iscsi_attach_aio_context(VAR_0, iscsilun->aio_context); if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 4 * 1024 &&
iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) { iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
iscsilun->block_size) >> BDRV_SECTOR_BITS; if (iscsilun->lbprz && !(VAR_0->open_flags & BDRV_O_NOCACHE)) { iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun); if (iscsilun->allocationmap == NULL) { VAR_12 = -ENOMEM; out:
qemu_opts_del(opts); g_free(VAR_9); if (VAR_5 != NULL) { iscsi_destroy_url(VAR_5); if (VAR_6 != NULL) { scsi_free_scsi_task(VAR_6); if (VAR_12) { if (VAR_4 != NULL) { iscsi_destroy_context(VAR_4); memset(iscsilun, 0, sizeof(IscsiLun)); return VAR_12;