static int sd_open(BlockDriverState *bs, const char *filename, int flags)

{

    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;



    strstart(filename, "sheepdog:", (const char **)&filename);



    QLIST_INIT(&s->inflight_aio_head);

    QLIST_INIT(&s->pending_aio_head);

    s->fd = -1;



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

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

    if (parse_vdiname(s, filename, vdi, &snapid, tag) < 0) {

        ret = -EINVAL;

        goto out;

    }

    s->fd = get_sheep_fd(s);

    if (s->fd < 0) {

        ret = s->fd;

        goto out;

    }



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

    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;

    }



    if (s->cache_flags == SD_FLAG_CMD_CACHE) {

        s->flush_fd = connect_to_sdog(s->addr, s->port);

        if (s->flush_fd < 0) {

            error_report("failed to connect");

            ret = s->flush_fd;

            goto out;

        }

    }



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

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

        s->is_snapshot = true;

    }



    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        error_report("failed to connect");

        ret = fd;

        goto out;

    }



    buf = g_malloc(SD_INODE_SIZE);

    ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0,

                      s->cache_flags);



    closesocket(fd);



    if (ret) {

        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 / SECTOR_SIZE;

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

    qemu_co_mutex_init(&s->lock);

    g_free(buf);

    return 0;

out:

    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);

    if (s->fd >= 0) {

        closesocket(s->fd);

    }

    g_free(buf);

    return ret;

}

static int sd_open(BlockDriverState *bs, const char *filename, int flags)

{

    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;



    strstart(filename, "sheepdog:", (const char **)&filename);



    QLIST_INIT(&s->inflight_aio_head);

    QLIST_INIT(&s->pending_aio_head);

    s->fd = -1;



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

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

    if (parse_vdiname(s, filename, vdi, &snapid, tag) < 0) {

        ret = -EINVAL;

        goto out;

    }

    s->fd = get_sheep_fd(s);

    if (s->fd < 0) {

        ret = s->fd;

        goto out;

    }



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

    if (ret) {

        goto out;

    }



    







    s->cache_flags = SD_FLAG_CMD_CACHE;

    if (flags & BDRV_O_NOCACHE) {

        s->cache_flags = SD_FLAG_CMD_DIRECT;

    }



    if (s->cache_flags == SD_FLAG_CMD_CACHE) {

        s->flush_fd = connect_to_sdog(s->addr, s->port);

        if (s->flush_fd < 0) {

            error_report("failed to connect");

            ret = s->flush_fd;

            goto out;

        }

    }



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

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

        s->is_snapshot = true;

    }



    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        error_report("failed to connect");

        ret = fd;

        goto out;

    }



    buf = g_malloc(SD_INODE_SIZE);

    ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0,

                      s->cache_flags);



    closesocket(fd);



    if (ret) {

        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 / SECTOR_SIZE;

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

    qemu_co_mutex_init(&s->lock);

    g_free(buf);

    return 0;

out:

    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);

    if (s->fd >= 0) {

        closesocket(s->fd);

    }

    g_free(buf);

    return ret;

}

static int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2)

{

    int VAR_3, VAR_4;

    uint32_t vid = 0;

    BDRVSheepdogState *s = VAR_0->opaque;

    char VAR_5[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid;

    char *VAR_6 = NULL;



    strstart(VAR_1, "sheepdog:", (const char **)&VAR_1);



    QLIST_INIT(&s->inflight_aio_head);

    QLIST_INIT(&s->pending_aio_head);

    s->VAR_4 = -1;



    memset(VAR_5, 0, sizeof(VAR_5));

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

    if (parse_vdiname(s, VAR_1, VAR_5, &snapid, tag) < 0) {

        VAR_3 = -EINVAL;

        goto out;

    }

    s->VAR_4 = get_sheep_fd(s);

    if (s->VAR_4 < 0) {

        VAR_3 = s->VAR_4;

        goto out;

    }



    VAR_3 = find_vdi_name(s, VAR_5, snapid, tag, &vid, 0);

    if (VAR_3) {

        goto out;

    }



    







    s->cache_flags = SD_FLAG_CMD_CACHE;

    if (VAR_2 & BDRV_O_NOCACHE) {

        s->cache_flags = SD_FLAG_CMD_DIRECT;

    }



    if (s->cache_flags == SD_FLAG_CMD_CACHE) {

        s->flush_fd = connect_to_sdog(s->addr, s->port);

        if (s->flush_fd < 0) {

            error_report("failed to connect");

            VAR_3 = s->flush_fd;

            goto out;

        }

    }



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

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

        s->is_snapshot = true;

    }



    VAR_4 = connect_to_sdog(s->addr, s->port);

    if (VAR_4 < 0) {

        error_report("failed to connect");

        VAR_3 = VAR_4;

        goto out;

    }



    VAR_6 = g_malloc(SD_INODE_SIZE);

    VAR_3 = read_object(VAR_4, VAR_6, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0,

                      s->cache_flags);



    closesocket(VAR_4);



    if (VAR_3) {

        goto out;

    }



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

    s->min_dirty_data_idx = UINT32_MAX;

    s->max_dirty_data_idx = 0;



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

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

    qemu_co_mutex_init(&s->lock);

    g_free(VAR_6);

    return 0;

out:

    qemu_aio_set_fd_handler(s->VAR_4, NULL, NULL, NULL, NULL);

    if (s->VAR_4 >= 0) {

        closesocket(s->VAR_4);

    }

    g_free(VAR_6);

    return VAR_3;

}

static int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2)
{ int VAR_3, VAR_4; uint32_t vid = 0; BDRVSheepdogState *s = VAR_0->opaque; char VAR_5[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN]; uint32_t snapid; char *VAR_6 = NULL; strstart(VAR_1, "sheepdog:", (const char **)&VAR_1); QLIST_INIT(&s->inflight_aio_head); QLIST_INIT(&s->pending_aio_head); s->VAR_4 = -1; memset(VAR_5, 0, sizeof(VAR_5)); memset(tag, 0, sizeof(tag)); if (parse_vdiname(s, VAR_1, VAR_5, &snapid, tag) < 0) { VAR_3 = -EINVAL; goto out; } s->VAR_4 = get_sheep_fd(s); if (s->VAR_4 < 0) { VAR_3 = s->VAR_4; goto out; } VAR_3 = find_vdi_name(s, VAR_5, snapid, tag, &vid, 0); if (VAR_3) { goto out; } s->cache_flags = SD_FLAG_CMD_CACHE; if (VAR_2 & BDRV_O_NOCACHE) { s->cache_flags = SD_FLAG_CMD_DIRECT; } if (s->cache_flags == SD_FLAG_CMD_CACHE) { s->flush_fd = connect_to_sdog(s->addr, s->port); if (s->flush_fd < 0) { error_report("failed to connect"); VAR_3 = s->flush_fd; goto out; } } if (snapid || tag[0] != '\0') { dprintf("%" PRIx32 " snapshot inode was open.\n", vid); s->is_snapshot = true; } VAR_4 = connect_to_sdog(s->addr, s->port); if (VAR_4 < 0) { error_report("failed to connect"); VAR_3 = VAR_4; goto out; } VAR_6 = g_malloc(SD_INODE_SIZE); VAR_3 = read_object(VAR_4, VAR_6, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0,
s->cache_flags); closesocket(VAR_4); if (VAR_3) { goto out; } memcpy(&s->inode, VAR_6, sizeof(s->inode)); s->min_dirty_data_idx = UINT32_MAX; s->max_dirty_data_idx = 0; VAR_0->total_sectors = s->inode.vdi_size / SECTOR_SIZE; pstrcpy(s->name, sizeof(s->name), VAR_5); qemu_co_mutex_init(&s->lock); g_free(VAR_6); return 0; out:
qemu_aio_set_fd_handler(s->VAR_4, NULL, NULL, NULL, NULL); if (s->VAR_4 >= 0) { closesocket(s->VAR_4); } g_free(VAR_6); return VAR_3; }