mirror of https://gitee.com/openkylin/qemu.git
9pfs: local: keep a file descriptor on the shared folder
This patch opens the shared folder and caches the file descriptor, so that it can be used to do symlink-safe path walk. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
6482a96163
commit
0e35a37829
|
@ -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) {
|
if (fstatfs(data->mountfd, &stbuf) < 0) {
|
||||||
return -1;
|
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,
|
||||||
|
|
Loading…
Reference in New Issue