qemu/fsdev/qemu-fsdev.c
Greg Kurz 2023243573 fsdev: Move some types definition to qemu-fsdev.c
It would make sense for these types to be defined in a header file if
we had an API for fsdrivers to register themselves. In practice, we
only have three of them and it is very unlikely we add new ones since
the future of file sharing between host and guest is the upcoming
virtio-fs.

Move the types to qemu-fsdev.c instead since they are only used there.

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
2019-05-17 17:34:48 +02:00

121 lines
2.9 KiB
C

/*
* 9p
*
* Copyright IBM, Corp. 2010
*
* Authors:
* Gautham R Shenoy <ego@in.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-fsdev.h"
#include "qemu/queue.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
/*
* A table to store the various file systems and their callback operations.
* -----------------
* fstype | ops
* -----------------
* local | local_ops
* . |
* . |
* . |
* . |
* -----------------
* etc
*/
typedef struct FsDriverTable {
const char *name;
FileOperations *ops;
} FsDriverTable;
typedef struct FsDriverListEntry {
FsDriverEntry fse;
QTAILQ_ENTRY(FsDriverListEntry) next;
} FsDriverListEntry;
static QTAILQ_HEAD(, FsDriverListEntry) fsdriver_entries =
QTAILQ_HEAD_INITIALIZER(fsdriver_entries);
static FsDriverTable FsDrivers[] = {
{ .name = "local", .ops = &local_ops},
{ .name = "synth", .ops = &synth_ops},
{ .name = "proxy", .ops = &proxy_ops},
};
int qemu_fsdev_add(QemuOpts *opts, Error **errp)
{
int i;
struct FsDriverListEntry *fsle;
const char *fsdev_id = qemu_opts_id(opts);
const char *fsdriver = qemu_opt_get(opts, "fsdriver");
const char *writeout = qemu_opt_get(opts, "writeout");
bool ro = qemu_opt_get_bool(opts, "readonly", 0);
if (!fsdev_id) {
error_setg(errp, "fsdev: No id specified");
return -1;
}
if (fsdriver) {
for (i = 0; i < ARRAY_SIZE(FsDrivers); i++) {
if (strcmp(FsDrivers[i].name, fsdriver) == 0) {
break;
}
}
if (i == ARRAY_SIZE(FsDrivers)) {
error_setg(errp, "fsdev: fsdriver %s not found", fsdriver);
return -1;
}
} else {
error_setg(errp, "fsdev: No fsdriver specified");
return -1;
}
fsle = g_malloc0(sizeof(*fsle));
fsle->fse.fsdev_id = g_strdup(fsdev_id);
fsle->fse.ops = FsDrivers[i].ops;
if (writeout) {
if (!strcmp(writeout, "immediate")) {
fsle->fse.export_flags |= V9FS_IMMEDIATE_WRITEOUT;
}
}
if (ro) {
fsle->fse.export_flags |= V9FS_RDONLY;
} else {
fsle->fse.export_flags &= ~V9FS_RDONLY;
}
if (fsle->fse.ops->parse_opts) {
if (fsle->fse.ops->parse_opts(opts, &fsle->fse, errp)) {
g_free(fsle->fse.fsdev_id);
g_free(fsle);
return -1;
}
}
QTAILQ_INSERT_TAIL(&fsdriver_entries, fsle, next);
return 0;
}
FsDriverEntry *get_fsdev_fsentry(char *id)
{
if (id) {
struct FsDriverListEntry *fsle;
QTAILQ_FOREACH(fsle, &fsdriver_entries, next) {
if (strcmp(fsle->fse.fsdev_id, id) == 0) {
return &fsle->fse;
}
}
}
return NULL;
}