static int qemu_gluster_open(BlockDriverState *bs,  QDict *options,

                             int bdrv_flags, Error **errp)

{

    BDRVGlusterState *s = bs->opaque;

    int open_flags = 0;

    int ret = 0;

    BlockdevOptionsGluster *gconf = NULL;

    QemuOpts *opts;

    Error *local_err = NULL;

    const char *filename;



    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, GLUSTER_OPT_FILENAME);



    s->debug_level = qemu_opt_get_number(opts, GLUSTER_OPT_DEBUG,

                                         GLUSTER_DEBUG_DEFAULT);

    if (s->debug_level < 0) {

        s->debug_level = 0;

    } else if (s->debug_level > GLUSTER_DEBUG_MAX) {

        s->debug_level = GLUSTER_DEBUG_MAX;

    }



    gconf = g_new0(BlockdevOptionsGluster, 1);

    gconf->debug_level = s->debug_level;

    gconf->has_debug_level = true;

    s->glfs = qemu_gluster_init(gconf, filename, options, errp);

    if (!s->glfs) {

        ret = -errno;

        goto out;

    }



#ifdef CONFIG_GLUSTERFS_XLATOR_OPT

    /* Without this, if fsync fails for a recoverable reason (for instance,

     * ENOSPC), gluster will dump its cache, preventing retries.  This means

     * almost certain data loss.  Not all gluster versions support the

     * 'resync-failed-syncs-after-fsync' key value, but there is no way to

     * discover during runtime if it is supported (this api returns success for

     * unknown key/value pairs) */

    ret = glfs_set_xlator_option(s->glfs, "*-write-behind",

                                          "resync-failed-syncs-after-fsync",

                                          "on");

    if (ret < 0) {

        error_setg_errno(errp, errno, "Unable to set xlator key/value pair");

        ret = -errno;

        goto out;

    }

#endif



    qemu_gluster_parse_flags(bdrv_flags, &open_flags);



    s->fd = glfs_open(s->glfs, gconf->path, open_flags);

    if (!s->fd) {

        ret = -errno;

    }



    s->supports_seek_data = qemu_gluster_test_seek(s->fd);



out:

    qemu_opts_del(opts);

    qapi_free_BlockdevOptionsGluster(gconf);

    if (!ret) {

        return ret;

    }

    if (s->fd) {

        glfs_close(s->fd);

    }

    if (s->glfs) {

        glfs_fini(s->glfs);

    }

    return ret;

}
