|
@@ -13,6 +13,7 @@
|
|
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qemu/osdep.h"
|
|
#include "9p.h"
|
|
#include "9p.h"
|
|
|
|
+#include "9p-local.h"
|
|
#include "9p-xattr.h"
|
|
#include "9p-xattr.h"
|
|
#include "9p-util.h"
|
|
#include "9p-util.h"
|
|
#include "fsdev/qemu-fsdev.h" /* local_ops */
|
|
#include "fsdev/qemu-fsdev.h" /* local_ops */
|
|
@@ -48,6 +49,24 @@ typedef struct {
|
|
int mountfd;
|
|
int mountfd;
|
|
} LocalData;
|
|
} LocalData;
|
|
|
|
|
|
|
|
+int local_open_nofollow(FsContext *fs_ctx, const char *path, int flags,
|
|
|
|
+ mode_t mode)
|
|
|
|
+{
|
|
|
|
+ LocalData *data = fs_ctx->private;
|
|
|
|
+
|
|
|
|
+ /* All paths are relative to the path data->mountfd points to */
|
|
|
|
+ while (*path == '/') {
|
|
|
|
+ path++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return relative_openat_nofollow(data->mountfd, path, flags, mode);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int local_opendir_nofollow(FsContext *fs_ctx, const char *path)
|
|
|
|
+{
|
|
|
|
+ return local_open_nofollow(fs_ctx, path, O_DIRECTORY | O_RDONLY, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
#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)
|
|
@@ -359,13 +378,9 @@ static int local_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
|
static int local_open(FsContext *ctx, V9fsPath *fs_path,
|
|
static int local_open(FsContext *ctx, V9fsPath *fs_path,
|
|
int flags, V9fsFidOpenState *fs)
|
|
int flags, V9fsFidOpenState *fs)
|
|
{
|
|
{
|
|
- char *buffer;
|
|
|
|
- char *path = fs_path->data;
|
|
|
|
int fd;
|
|
int fd;
|
|
|
|
|
|
- buffer = rpath(ctx, path);
|
|
|
|
- fd = open(buffer, flags | O_NOFOLLOW);
|
|
|
|
- g_free(buffer);
|
|
|
|
|
|
+ fd = local_open_nofollow(ctx, fs_path->data, flags, 0);
|
|
if (fd == -1) {
|
|
if (fd == -1) {
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -376,13 +391,15 @@ static int local_open(FsContext *ctx, V9fsPath *fs_path,
|
|
static int local_opendir(FsContext *ctx,
|
|
static int local_opendir(FsContext *ctx,
|
|
V9fsPath *fs_path, V9fsFidOpenState *fs)
|
|
V9fsPath *fs_path, V9fsFidOpenState *fs)
|
|
{
|
|
{
|
|
- char *buffer;
|
|
|
|
- char *path = fs_path->data;
|
|
|
|
|
|
+ int dirfd;
|
|
DIR *stream;
|
|
DIR *stream;
|
|
|
|
|
|
- buffer = rpath(ctx, path);
|
|
|
|
- stream = opendir(buffer);
|
|
|
|
- g_free(buffer);
|
|
|
|
|
|
+ dirfd = local_opendir_nofollow(ctx, fs_path->data);
|
|
|
|
+ if (dirfd == -1) {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ stream = fdopendir(dirfd);
|
|
if (!stream) {
|
|
if (!stream) {
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|