|
@@ -14,6 +14,7 @@
|
|
#include "qemu/osdep.h"
|
|
#include "qemu/osdep.h"
|
|
#include "9p.h"
|
|
#include "9p.h"
|
|
#include "9p-xattr.h"
|
|
#include "9p-xattr.h"
|
|
|
|
+#include "9p-util.h"
|
|
#include "fsdev/qemu-fsdev.h" /* local_ops */
|
|
#include "fsdev/qemu-fsdev.h" /* local_ops */
|
|
#include <arpa/inet.h>
|
|
#include <arpa/inet.h>
|
|
#include <pwd.h>
|
|
#include <pwd.h>
|
|
@@ -43,6 +44,10 @@
|
|
#define BTRFS_SUPER_MAGIC 0x9123683E
|
|
#define BTRFS_SUPER_MAGIC 0x9123683E
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+typedef struct {
|
|
|
|
+ int mountfd;
|
|
|
|
+} LocalData;
|
|
|
|
+
|
|
#define VIRTFS_META_DIR ".virtfs_metadata"
|
|
#define VIRTFS_META_DIR ".virtfs_metadata"
|
|
|
|
|
|
static char *local_mapped_attr_path(FsContext *ctx, const char *path)
|
|
static char *local_mapped_attr_path(FsContext *ctx, const char *path)
|
|
@@ -1176,13 +1181,20 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
|
|
static int local_init(FsContext *ctx)
|
|
static int local_init(FsContext *ctx)
|
|
{
|
|
{
|
|
struct statfs stbuf;
|
|
struct statfs stbuf;
|
|
|
|
+ LocalData *data = g_malloc(sizeof(*data));
|
|
|
|
+
|
|
|
|
+ data->mountfd = open(ctx->fs_root, O_DIRECTORY | O_RDONLY);
|
|
|
|
+ if (data->mountfd == -1) {
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
|
|
#ifdef FS_IOC_GETVERSION
|
|
#ifdef FS_IOC_GETVERSION
|
|
/*
|
|
/*
|
|
* use ioc_getversion only if the ioctl is definied
|
|
* use ioc_getversion only if the ioctl is definied
|
|
*/
|
|
*/
|
|
- if (statfs(ctx->fs_root, &stbuf) < 0) {
|
|
|
|
- return -1;
|
|
|
|
|
|
+ if (fstatfs(data->mountfd, &stbuf) < 0) {
|
|
|
|
+ close_preserve_errno(data->mountfd);
|
|
|
|
+ goto err;
|
|
}
|
|
}
|
|
switch (stbuf.f_type) {
|
|
switch (stbuf.f_type) {
|
|
case EXT2_SUPER_MAGIC:
|
|
case EXT2_SUPER_MAGIC:
|
|
@@ -1209,7 +1221,20 @@ static int local_init(FsContext *ctx)
|
|
}
|
|
}
|
|
ctx->export_flags |= V9FS_PATHNAME_FSCONTEXT;
|
|
ctx->export_flags |= V9FS_PATHNAME_FSCONTEXT;
|
|
|
|
|
|
|
|
+ ctx->private = data;
|
|
return 0;
|
|
return 0;
|
|
|
|
+
|
|
|
|
+err:
|
|
|
|
+ g_free(data);
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void local_cleanup(FsContext *ctx)
|
|
|
|
+{
|
|
|
|
+ LocalData *data = ctx->private;
|
|
|
|
+
|
|
|
|
+ close(data->mountfd);
|
|
|
|
+ g_free(data);
|
|
}
|
|
}
|
|
|
|
|
|
static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
|
|
static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
|
|
@@ -1252,6 +1277,7 @@ static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
|
|
FileOperations local_ops = {
|
|
FileOperations local_ops = {
|
|
.parse_opts = local_parse_opts,
|
|
.parse_opts = local_parse_opts,
|
|
.init = local_init,
|
|
.init = local_init,
|
|
|
|
+ .cleanup = local_cleanup,
|
|
.lstat = local_lstat,
|
|
.lstat = local_lstat,
|
|
.readlink = local_readlink,
|
|
.readlink = local_readlink,
|
|
.close = local_close,
|
|
.close = local_close,
|