#include "qemu/error-report.h"
#include "qapi/error.h"
#include "block/block_int.h"
+#include "block/qdict.h"
#include "trace.h"
#include "qemu/iov.h"
#include "qemu/option.h"
Error **errp)
{
BlockdevOptionsNfs *opts = NULL;
- QObject *crumpled = NULL;
Visitor *v;
+ const QDictEntry *e;
Error *local_err = NULL;
- crumpled = qdict_crumple(options, errp);
- if (crumpled == NULL) {
+ v = qobject_input_visitor_new_flat_confused(options, errp);
+ if (!v) {
return NULL;
}
- v = qobject_input_visitor_new_keyval(crumpled);
visit_type_BlockdevOptionsNfs(v, NULL, &opts, &local_err);
visit_free(v);
- qobject_decref(crumpled);
if (local_err) {
+ error_propagate(errp, local_err);
return NULL;
}
+ /* Remove the processed options from the QDict (the visitor processes
+ * _all_ options in the QDict) */
+ while ((e = qdict_first(options))) {
+ qdict_del(options, e->key);
+ }
+
return opts;
}
ret = 0;
out:
- QDECREF(options);
+ qobject_unref(options);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
}
-static int nfs_file_truncate(BlockDriverState *bs, int64_t offset,
- PreallocMode prealloc, Error **errp)
+static int coroutine_fn
+nfs_file_co_truncate(BlockDriverState *bs, int64_t offset,
+ PreallocMode prealloc, Error **errp)
{
NFSClient *client = bs->opaque;
int ret;
return 0;
}
-static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
+static void nfs_refresh_filename(BlockDriverState *bs)
{
NFSClient *client = bs->opaque;
- QDict *opts = qdict_new();
- QObject *server_qdict;
- Visitor *ov;
-
- qdict_put_str(opts, "driver", "nfs");
if (client->uid && !client->gid) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"nfs://%s%s", client->server->host, client->path);
}
+}
- ov = qobject_output_visitor_new(&server_qdict);
- visit_type_NFSServer(ov, NULL, &client->server, &error_abort);
- visit_complete(ov, &server_qdict);
- qdict_put_obj(opts, "server", server_qdict);
- qdict_put_str(opts, "path", client->path);
+static char *nfs_dirname(BlockDriverState *bs, Error **errp)
+{
+ NFSClient *client = bs->opaque;
- if (client->uid) {
- qdict_put_int(opts, "user", client->uid);
- }
- if (client->gid) {
- qdict_put_int(opts, "group", client->gid);
- }
- if (client->tcp_syncnt) {
- qdict_put_int(opts, "tcp-syn-cnt", client->tcp_syncnt);
- }
- if (client->readahead) {
- qdict_put_int(opts, "readahead-size", client->readahead);
- }
- if (client->pagecache) {
- qdict_put_int(opts, "page-cache-size", client->pagecache);
- }
- if (client->debug) {
- qdict_put_int(opts, "debug", client->debug);
+ if (client->uid || client->gid) {
+ bdrv_refresh_filename(bs);
+ error_setg(errp, "Cannot generate a base directory for NFS node '%s'",
+ bs->filename);
+ return NULL;
}
- visit_free(ov);
- qdict_flatten(opts);
- bs->full_open_options = opts;
+ return g_strdup_printf("nfs://%s%s/", client->server->host, client->path);
}
#ifdef LIBNFS_FEATURE_PAGECACHE
}
#endif
+static const char *nfs_strong_runtime_opts[] = {
+ "path",
+ "user",
+ "group",
+ "server.",
+
+ NULL
+};
+
static BlockDriver bdrv_nfs = {
.format_name = "nfs",
.protocol_name = "nfs",
.bdrv_has_zero_init = nfs_has_zero_init,
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
- .bdrv_truncate = nfs_file_truncate,
+ .bdrv_co_truncate = nfs_file_co_truncate,
.bdrv_file_open = nfs_file_open,
.bdrv_close = nfs_file_close,
.bdrv_detach_aio_context = nfs_detach_aio_context,
.bdrv_attach_aio_context = nfs_attach_aio_context,
.bdrv_refresh_filename = nfs_refresh_filename,
+ .bdrv_dirname = nfs_dirname,
+
+ .strong_runtime_opts = nfs_strong_runtime_opts,
#ifdef LIBNFS_FEATURE_PAGECACHE
.bdrv_co_invalidate_cache = nfs_co_invalidate_cache,