static int sd_open(BlockDriverState *bs, QDict *options, int flags,

                   Error **errp)

{

    int ret, fd;

    uint32_t vid = 0;

    BDRVSheepdogState *s = bs->opaque;

    char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid;

    char *buf = NULL;

    QemuOpts *opts;

    Error *local_err = NULL;

    const char *filename;



    s->bs = bs;

    s->aio_context = bdrv_get_aio_context(bs);



    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;

        goto out;

    }



    filename = qemu_opt_get(opts, "filename");



    QLIST_INIT(&s->inflight_aio_head);

    QLIST_INIT(&s->failed_aio_head);

    QLIST_INIT(&s->inflight_aiocb_head);

    s->fd = -1;



    memset(vdi, 0, sizeof(vdi));

    memset(tag, 0, sizeof(tag));



    if (strstr(filename, "://")) {

        ret = sd_parse_uri(s, filename, vdi, &snapid, tag);

    } else {

        ret = parse_vdiname(s, filename, vdi, &snapid, tag);

    }

    if (ret < 0) {

        error_setg(errp, "Can't parse filename");

        goto out;

    }

    s->fd = get_sheep_fd(s, errp);

    if (s->fd < 0) {

        ret = s->fd;

        goto out;

    }



    ret = find_vdi_name(s, vdi, snapid, tag, &vid, true, errp);

    if (ret) {

        goto out;

    }



    /*

     * QEMU block layer emulates writethrough cache as 'writeback + flush', so

     * we always set SD_FLAG_CMD_CACHE (writeback cache) as default.

     */

    s->cache_flags = SD_FLAG_CMD_CACHE;

    if (flags & BDRV_O_NOCACHE) {

        s->cache_flags = SD_FLAG_CMD_DIRECT;

    }

    s->discard_supported = true;



    if (snapid || tag[0] != '\0') {

        DPRINTF("%" PRIx32 " snapshot inode was open.\n", vid);

        s->is_snapshot = true;

    }



    fd = connect_to_sdog(s, errp);

    if (fd < 0) {

        ret = fd;

        goto out;

    }



    buf = g_malloc(SD_INODE_SIZE);

    ret = read_object(fd, s->aio_context, buf, vid_to_vdi_oid(vid),

                      0, SD_INODE_SIZE, 0, s->cache_flags);



    closesocket(fd);



    if (ret) {

        error_setg(errp, "Can't read snapshot inode");

        goto out;

    }



    memcpy(&s->inode, buf, sizeof(s->inode));

    s->min_dirty_data_idx = UINT32_MAX;

    s->max_dirty_data_idx = 0;



    bs->total_sectors = s->inode.vdi_size / BDRV_SECTOR_SIZE;

    pstrcpy(s->name, sizeof(s->name), vdi);

    qemu_co_mutex_init(&s->lock);

    qemu_co_queue_init(&s->overwrapping_queue);

    qemu_opts_del(opts);

    g_free(buf);

    return 0;

out:

    aio_set_fd_handler(bdrv_get_aio_context(bs), s->fd, NULL, NULL, NULL);

    if (s->fd >= 0) {

        closesocket(s->fd);

    }

    qemu_opts_del(opts);

    g_free(buf);

    return ret;

}

static int sd_open(BlockDriverState *bs, QDict *options, int flags,

                   Error **errp)

{

    int ret, fd;

    uint32_t vid = 0;

    BDRVSheepdogState *s = bs->opaque;

    char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid;

    char *buf = NULL;

    QemuOpts *opts;

    Error *local_err = NULL;

    const char *filename;



    s->bs = bs;

    s->aio_context = bdrv_get_aio_context(bs);



    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;

        goto out;

    }



    filename = qemu_opt_get(opts, "filename");



    QLIST_INIT(&s->inflight_aio_head);

    QLIST_INIT(&s->failed_aio_head);

    QLIST_INIT(&s->inflight_aiocb_head);

    s->fd = -1;



    memset(vdi, 0, sizeof(vdi));

    memset(tag, 0, sizeof(tag));



    if (strstr(filename, ":

        ret = sd_parse_uri(s, filename, vdi, &snapid, tag);

    } else {

        ret = parse_vdiname(s, filename, vdi, &snapid, tag);

    }

    if (ret < 0) {

        error_setg(errp, "Can't parse filename");

        goto out;

    }

    s->fd = get_sheep_fd(s, errp);

    if (s->fd < 0) {

        ret = s->fd;

        goto out;

    }



    ret = find_vdi_name(s, vdi, snapid, tag, &vid, true, errp);

    if (ret) {

        goto out;

    }



    







    s->cache_flags = SD_FLAG_CMD_CACHE;

    if (flags & BDRV_O_NOCACHE) {

        s->cache_flags = SD_FLAG_CMD_DIRECT;

    }

    s->discard_supported = true;



    if (snapid || tag[0] != '\0') {

        DPRINTF("%" PRIx32 " snapshot inode was open.\n", vid);

        s->is_snapshot = true;

    }



    fd = connect_to_sdog(s, errp);

    if (fd < 0) {

        ret = fd;

        goto out;

    }



    buf = g_malloc(SD_INODE_SIZE);

    ret = read_object(fd, s->aio_context, buf, vid_to_vdi_oid(vid),

                      0, SD_INODE_SIZE, 0, s->cache_flags);



    closesocket(fd);



    if (ret) {

        error_setg(errp, "Can't read snapshot inode");

        goto out;

    }



    memcpy(&s->inode, buf, sizeof(s->inode));

    s->min_dirty_data_idx = UINT32_MAX;

    s->max_dirty_data_idx = 0;



    bs->total_sectors = s->inode.vdi_size / BDRV_SECTOR_SIZE;

    pstrcpy(s->name, sizeof(s->name), vdi);

    qemu_co_mutex_init(&s->lock);

    qemu_co_queue_init(&s->overwrapping_queue);

    qemu_opts_del(opts);

    g_free(buf);

    return 0;

out:

    aio_set_fd_handler(bdrv_get_aio_context(bs), s->fd, NULL, NULL, NULL);

    if (s->fd >= 0) {

        closesocket(s->fd);

    }

    qemu_opts_del(opts);

    g_free(buf);

    return ret;

}

static int FUNC_0(BlockDriverState *VAR_0, QDict *VAR_1, int VAR_2,

                   Error **VAR_3)

{

    int VAR_4, VAR_5;

    uint32_t vid = 0;

    BDRVSheepdogState *s = VAR_0->opaque;

    char VAR_6[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid;

    char *VAR_7 = NULL;

    QemuOpts *opts;

    Error *local_err = NULL;

    const char *VAR_8;



    s->VAR_0 = VAR_0;

    s->aio_context = bdrv_get_aio_context(VAR_0);



    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_4 = -EINVAL;

        goto out;

    }



    VAR_8 = qemu_opt_get(opts, "VAR_8");



    QLIST_INIT(&s->inflight_aio_head);

    QLIST_INIT(&s->failed_aio_head);

    QLIST_INIT(&s->inflight_aiocb_head);

    s->VAR_5 = -1;



    memset(VAR_6, 0, sizeof(VAR_6));

    memset(tag, 0, sizeof(tag));



    if (strstr(VAR_8, ":

        VAR_4 = sd_parse_uri(s, VAR_8, VAR_6, &snapid, tag);

    } else {

        VAR_4 = parse_vdiname(s, VAR_8, VAR_6, &snapid, tag);

    }

    if (VAR_4 < 0) {

        error_setg(VAR_3, "Can't parse VAR_8");

        goto out;

    }

    s->VAR_5 = get_sheep_fd(s, VAR_3);

    if (s->VAR_5 < 0) {

        VAR_4 = s->VAR_5;

        goto out;

    }



    VAR_4 = find_vdi_name(s, VAR_6, snapid, tag, &vid, true, VAR_3);

    if (VAR_4) {

        goto out;

    }



    







    s->cache_flags = SD_FLAG_CMD_CACHE;

    if (VAR_2 & BDRV_O_NOCACHE) {

        s->cache_flags = SD_FLAG_CMD_DIRECT;

    }

    s->discard_supported = true;



    if (snapid || tag[0] != '\0') {

        DPRINTF("%" PRIx32 " snapshot inode was open.\n", vid);

        s->is_snapshot = true;

    }



    VAR_5 = connect_to_sdog(s, VAR_3);

    if (VAR_5 < 0) {

        VAR_4 = VAR_5;

        goto out;

    }



    VAR_7 = g_malloc(SD_INODE_SIZE);

    VAR_4 = read_object(VAR_5, s->aio_context, VAR_7, vid_to_vdi_oid(vid),

                      0, SD_INODE_SIZE, 0, s->cache_flags);



    closesocket(VAR_5);



    if (VAR_4) {

        error_setg(VAR_3, "Can't read snapshot inode");

        goto out;

    }



    memcpy(&s->inode, VAR_7, sizeof(s->inode));

    s->min_dirty_data_idx = UINT32_MAX;

    s->max_dirty_data_idx = 0;



    VAR_0->total_sectors = s->inode.vdi_size / BDRV_SECTOR_SIZE;

    pstrcpy(s->name, sizeof(s->name), VAR_6);

    qemu_co_mutex_init(&s->lock);

    qemu_co_queue_init(&s->overwrapping_queue);

    qemu_opts_del(opts);

    g_free(VAR_7);

    return 0;

out:

    aio_set_fd_handler(bdrv_get_aio_context(VAR_0), s->VAR_5, NULL, NULL, NULL);

    if (s->VAR_5 >= 0) {

        closesocket(s->VAR_5);

    }

    qemu_opts_del(opts);

    g_free(VAR_7);

    return VAR_4;

}

static int FUNC_0(BlockDriverState *VAR_0, QDict *VAR_1, int VAR_2,
Error **VAR_3)
{ int VAR_4, VAR_5; uint32_t vid = 0; BDRVSheepdogState *s = VAR_0->opaque; char VAR_6[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN]; uint32_t snapid; char *VAR_7 = NULL; QemuOpts *opts; Error *local_err = NULL; const char *VAR_8; s->VAR_0 = VAR_0; s->aio_context = bdrv_get_aio_context(VAR_0); 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_4 = -EINVAL; goto out; } VAR_8 = qemu_opt_get(opts, "VAR_8"); QLIST_INIT(&s->inflight_aio_head); QLIST_INIT(&s->failed_aio_head); QLIST_INIT(&s->inflight_aiocb_head); s->VAR_5 = -1; memset(VAR_6, 0, sizeof(VAR_6)); memset(tag, 0, sizeof(tag)); if (strstr(VAR_8, ":
VAR_4 = sd_parse_uri(s, VAR_8, VAR_6, &snapid, tag); } else { VAR_4 = parse_vdiname(s, VAR_8, VAR_6, &snapid, tag); } if (VAR_4 < 0) { error_setg(VAR_3, "Can't parse VAR_8"); goto out; } s->VAR_5 = get_sheep_fd(s, VAR_3); if (s->VAR_5 < 0) { VAR_4 = s->VAR_5; goto out; } VAR_4 = find_vdi_name(s, VAR_6, snapid, tag, &vid, true, VAR_3); if (VAR_4) { goto out; } s->cache_flags = SD_FLAG_CMD_CACHE; if (VAR_2 & BDRV_O_NOCACHE) { s->cache_flags = SD_FLAG_CMD_DIRECT; } s->discard_supported = true; if (snapid || tag[0] != '\0') { DPRINTF("%" PRIx32 " snapshot inode was open.\n", vid); s->is_snapshot = true; } VAR_5 = connect_to_sdog(s, VAR_3); if (VAR_5 < 0) { VAR_4 = VAR_5; goto out; } VAR_7 = g_malloc(SD_INODE_SIZE); VAR_4 = read_object(VAR_5, s->aio_context, VAR_7, vid_to_vdi_oid(vid),
0, SD_INODE_SIZE, 0, s->cache_flags); closesocket(VAR_5); if (VAR_4) { error_setg(VAR_3, "Can't read snapshot inode"); goto out; } memcpy(&s->inode, VAR_7, sizeof(s->inode)); s->min_dirty_data_idx = UINT32_MAX; s->max_dirty_data_idx = 0; VAR_0->total_sectors = s->inode.vdi_size / BDRV_SECTOR_SIZE; pstrcpy(s->name, sizeof(s->name), VAR_6); qemu_co_mutex_init(&s->lock); qemu_co_queue_init(&s->overwrapping_queue); qemu_opts_del(opts); g_free(VAR_7); return 0; out:
aio_set_fd_handler(bdrv_get_aio_context(VAR_0), s->VAR_5, NULL, NULL, NULL); if (s->VAR_5 >= 0) { closesocket(s->VAR_5); } qemu_opts_del(opts); g_free(VAR_7); return VAR_4; }