Loading Makefile.objs +4 −4 Original line number Diff line number Diff line Loading @@ -308,7 +308,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y) 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o 9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o 9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-handle.o hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y)) $(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS) Loading fsdev/file-op-9p.h +36 −18 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <sys/stat.h> #include <sys/uio.h> #include <sys/vfs.h> #define SM_LOCAL_MODE_BITS 0600 #define SM_LOCAL_DIR_MODE_BITS 0700 Loading Loading @@ -49,51 +50,68 @@ typedef struct FsCred struct xattr_operations; /* FsContext flag values */ #define PATHNAME_FSCONTEXT 0x1 typedef struct FsContext { int flags; char *fs_root; SecModel fs_sm; uid_t uid; struct xattr_operations **xops; /* fs driver specific data */ void *private; } FsContext; typedef struct V9fsPath { int16_t size; char *data; } V9fsPath; void cred_init(FsCred *); typedef struct FileOperations { int (*lstat)(FsContext *, const char *, struct stat *); ssize_t (*readlink)(FsContext *, const char *, char *, size_t); int (*chmod)(FsContext *, const char *, FsCred *); int (*chown)(FsContext *, const char *, FsCred *); int (*mknod)(FsContext *, const char *, FsCred *); int (*utimensat)(FsContext *, const char *, const struct timespec *); int (*init)(struct FsContext *); int (*lstat)(FsContext *, V9fsPath *, struct stat *); ssize_t (*readlink)(FsContext *, V9fsPath *, char *, size_t); int (*chmod)(FsContext *, V9fsPath *, FsCred *); int (*chown)(FsContext *, V9fsPath *, FsCred *); int (*mknod)(FsContext *, V9fsPath *, const char *, FsCred *); int (*utimensat)(FsContext *, V9fsPath *, const struct timespec *); int (*remove)(FsContext *, const char *); int (*symlink)(FsContext *, const char *, const char *, FsCred *); int (*link)(FsContext *, const char *, const char *); int (*symlink)(FsContext *, const char *, V9fsPath *, const char *, FsCred *); int (*link)(FsContext *, V9fsPath *, V9fsPath *, const char *); int (*setuid)(FsContext *, uid_t); int (*close)(FsContext *, int); int (*closedir)(FsContext *, DIR *); DIR *(*opendir)(FsContext *, const char *); int (*open)(FsContext *, const char *, int); int (*open2)(FsContext *, const char *, int, FsCred *); DIR *(*opendir)(FsContext *, V9fsPath *); int (*open)(FsContext *, V9fsPath *, int); int (*open2)(FsContext *, V9fsPath *, const char *, int, FsCred *); void (*rewinddir)(FsContext *, DIR *); off_t (*telldir)(FsContext *, DIR *); int (*readdir_r)(FsContext *, DIR *, struct dirent *, struct dirent **); void (*seekdir)(FsContext *, DIR *, off_t); ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t); ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t); int (*mkdir)(FsContext *, const char *, FsCred *); int (*mkdir)(FsContext *, V9fsPath *, const char *, FsCred *); int (*fstat)(FsContext *, int, struct stat *); int (*rename)(FsContext *, const char *, const char *); int (*truncate)(FsContext *, const char *, off_t); int (*truncate)(FsContext *, V9fsPath *, off_t); int (*fsync)(FsContext *, int, int); int (*statfs)(FsContext *s, const char *path, struct statfs *stbuf); ssize_t (*lgetxattr)(FsContext *, const char *, int (*statfs)(FsContext *s, V9fsPath *path, struct statfs *stbuf); ssize_t (*lgetxattr)(FsContext *, V9fsPath *, const char *, void *, size_t); ssize_t (*llistxattr)(FsContext *, const char *, void *, size_t); int (*lsetxattr)(FsContext *, const char *, ssize_t (*llistxattr)(FsContext *, V9fsPath *, void *, size_t); int (*lsetxattr)(FsContext *, V9fsPath *, const char *, void *, size_t, int); int (*lremovexattr)(FsContext *, const char *, const char *); int (*lremovexattr)(FsContext *, V9fsPath *, const char *); int (*name_to_path)(FsContext *, V9fsPath *, const char *, V9fsPath *); int (*renameat)(FsContext *ctx, V9fsPath *olddir, const char *old_name, V9fsPath *newdir, const char *new_name); int (*unlinkat)(FsContext *ctx, V9fsPath *dir, const char *name, int flags); void *opaque; } FileOperations; Loading fsdev/qemu-fsdev.c +1 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ static QTAILQ_HEAD(FsTypeEntry_head, FsTypeListEntry) fstype_entries = static FsTypeTable FsTypes[] = { { .name = "local", .ops = &local_ops}, { .name = "handle", .ops = &handle_ops}, }; int qemu_fsdev_add(QemuOpts *opts) Loading fsdev/qemu-fsdev.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,4 +52,5 @@ typedef struct FsTypeListEntry { int qemu_fsdev_add(QemuOpts *opts); FsTypeEntry *get_fsdev_fsentry(char *id); extern FileOperations local_ops; extern FileOperations handle_ops; #endif hw/9pfs/codir.c +54 −10 Original line number Diff line number Diff line Loading @@ -17,11 +17,15 @@ #include "qemu-coroutine.h" #include "virtio-9p-coth.h" int v9fs_co_readdir_r(V9fsState *s, V9fsFidState *fidp, struct dirent *dent, int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent, struct dirent **result) { int err; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR; } v9fs_co_run_in_worker( { errno = 0; Loading @@ -35,10 +39,14 @@ int v9fs_co_readdir_r(V9fsState *s, V9fsFidState *fidp, struct dirent *dent, return err; } off_t v9fs_co_telldir(V9fsState *s, V9fsFidState *fidp) off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp) { off_t err; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR; } v9fs_co_run_in_worker( { err = s->ops->telldir(&s->ctx, fidp->fs.dir); Loading @@ -49,67 +57,103 @@ off_t v9fs_co_telldir(V9fsState *s, V9fsFidState *fidp) return err; } void v9fs_co_seekdir(V9fsState *s, V9fsFidState *fidp, off_t offset) void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset) { V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return; } v9fs_co_run_in_worker( { s->ops->seekdir(&s->ctx, fidp->fs.dir, offset); }); } void v9fs_co_rewinddir(V9fsState *s, V9fsFidState *fidp) void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp) { V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return; } v9fs_co_run_in_worker( { s->ops->rewinddir(&s->ctx, fidp->fs.dir); }); } int v9fs_co_mkdir(V9fsState *s, char *name, mode_t mode, uid_t uid, gid_t gid) int v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, mode_t mode, uid_t uid, gid_t gid, struct stat *stbuf) { int err; FsCred cred; V9fsPath path; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR;; } cred_init(&cred); cred.fc_mode = mode; cred.fc_uid = uid; cred.fc_gid = gid; v9fs_path_read_lock(s); v9fs_co_run_in_worker( { err = s->ops->mkdir(&s->ctx, name, &cred); err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred); if (err < 0) { err = -errno; } else { v9fs_path_init(&path); err = v9fs_name_to_path(s, &fidp->path, name->data, &path); if (!err) { err = s->ops->lstat(&s->ctx, &path, stbuf); if (err < 0) { err = -errno; } } v9fs_path_free(&path); } }); v9fs_path_unlock(s); return err; } int v9fs_co_opendir(V9fsState *s, V9fsFidState *fidp) int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp) { int err; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR;; } v9fs_path_read_lock(s); v9fs_co_run_in_worker( { fidp->fs.dir = s->ops->opendir(&s->ctx, fidp->path.data); fidp->fs.dir = s->ops->opendir(&s->ctx, &fidp->path); if (!fidp->fs.dir) { err = -errno; } else { err = 0; } }); v9fs_path_unlock(s); if (!err) { total_open_fd++; if (total_open_fd > open_fd_hw) { v9fs_reclaim_fd(s); v9fs_reclaim_fd(pdu); } } return err; } int v9fs_co_closedir(V9fsState *s, DIR *dir) int v9fs_co_closedir(V9fsPDU *pdu, DIR *dir) { int err; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR;; } v9fs_co_run_in_worker( { err = s->ops->closedir(&s->ctx, dir); Loading Loading
Makefile.objs +4 −4 Original line number Diff line number Diff line Loading @@ -308,7 +308,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y) 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o 9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o 9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-handle.o hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y)) $(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS) Loading
fsdev/file-op-9p.h +36 −18 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <sys/stat.h> #include <sys/uio.h> #include <sys/vfs.h> #define SM_LOCAL_MODE_BITS 0600 #define SM_LOCAL_DIR_MODE_BITS 0700 Loading Loading @@ -49,51 +50,68 @@ typedef struct FsCred struct xattr_operations; /* FsContext flag values */ #define PATHNAME_FSCONTEXT 0x1 typedef struct FsContext { int flags; char *fs_root; SecModel fs_sm; uid_t uid; struct xattr_operations **xops; /* fs driver specific data */ void *private; } FsContext; typedef struct V9fsPath { int16_t size; char *data; } V9fsPath; void cred_init(FsCred *); typedef struct FileOperations { int (*lstat)(FsContext *, const char *, struct stat *); ssize_t (*readlink)(FsContext *, const char *, char *, size_t); int (*chmod)(FsContext *, const char *, FsCred *); int (*chown)(FsContext *, const char *, FsCred *); int (*mknod)(FsContext *, const char *, FsCred *); int (*utimensat)(FsContext *, const char *, const struct timespec *); int (*init)(struct FsContext *); int (*lstat)(FsContext *, V9fsPath *, struct stat *); ssize_t (*readlink)(FsContext *, V9fsPath *, char *, size_t); int (*chmod)(FsContext *, V9fsPath *, FsCred *); int (*chown)(FsContext *, V9fsPath *, FsCred *); int (*mknod)(FsContext *, V9fsPath *, const char *, FsCred *); int (*utimensat)(FsContext *, V9fsPath *, const struct timespec *); int (*remove)(FsContext *, const char *); int (*symlink)(FsContext *, const char *, const char *, FsCred *); int (*link)(FsContext *, const char *, const char *); int (*symlink)(FsContext *, const char *, V9fsPath *, const char *, FsCred *); int (*link)(FsContext *, V9fsPath *, V9fsPath *, const char *); int (*setuid)(FsContext *, uid_t); int (*close)(FsContext *, int); int (*closedir)(FsContext *, DIR *); DIR *(*opendir)(FsContext *, const char *); int (*open)(FsContext *, const char *, int); int (*open2)(FsContext *, const char *, int, FsCred *); DIR *(*opendir)(FsContext *, V9fsPath *); int (*open)(FsContext *, V9fsPath *, int); int (*open2)(FsContext *, V9fsPath *, const char *, int, FsCred *); void (*rewinddir)(FsContext *, DIR *); off_t (*telldir)(FsContext *, DIR *); int (*readdir_r)(FsContext *, DIR *, struct dirent *, struct dirent **); void (*seekdir)(FsContext *, DIR *, off_t); ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t); ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t); int (*mkdir)(FsContext *, const char *, FsCred *); int (*mkdir)(FsContext *, V9fsPath *, const char *, FsCred *); int (*fstat)(FsContext *, int, struct stat *); int (*rename)(FsContext *, const char *, const char *); int (*truncate)(FsContext *, const char *, off_t); int (*truncate)(FsContext *, V9fsPath *, off_t); int (*fsync)(FsContext *, int, int); int (*statfs)(FsContext *s, const char *path, struct statfs *stbuf); ssize_t (*lgetxattr)(FsContext *, const char *, int (*statfs)(FsContext *s, V9fsPath *path, struct statfs *stbuf); ssize_t (*lgetxattr)(FsContext *, V9fsPath *, const char *, void *, size_t); ssize_t (*llistxattr)(FsContext *, const char *, void *, size_t); int (*lsetxattr)(FsContext *, const char *, ssize_t (*llistxattr)(FsContext *, V9fsPath *, void *, size_t); int (*lsetxattr)(FsContext *, V9fsPath *, const char *, void *, size_t, int); int (*lremovexattr)(FsContext *, const char *, const char *); int (*lremovexattr)(FsContext *, V9fsPath *, const char *); int (*name_to_path)(FsContext *, V9fsPath *, const char *, V9fsPath *); int (*renameat)(FsContext *ctx, V9fsPath *olddir, const char *old_name, V9fsPath *newdir, const char *new_name); int (*unlinkat)(FsContext *ctx, V9fsPath *dir, const char *name, int flags); void *opaque; } FileOperations; Loading
fsdev/qemu-fsdev.c +1 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ static QTAILQ_HEAD(FsTypeEntry_head, FsTypeListEntry) fstype_entries = static FsTypeTable FsTypes[] = { { .name = "local", .ops = &local_ops}, { .name = "handle", .ops = &handle_ops}, }; int qemu_fsdev_add(QemuOpts *opts) Loading
fsdev/qemu-fsdev.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,4 +52,5 @@ typedef struct FsTypeListEntry { int qemu_fsdev_add(QemuOpts *opts); FsTypeEntry *get_fsdev_fsentry(char *id); extern FileOperations local_ops; extern FileOperations handle_ops; #endif
hw/9pfs/codir.c +54 −10 Original line number Diff line number Diff line Loading @@ -17,11 +17,15 @@ #include "qemu-coroutine.h" #include "virtio-9p-coth.h" int v9fs_co_readdir_r(V9fsState *s, V9fsFidState *fidp, struct dirent *dent, int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent, struct dirent **result) { int err; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR; } v9fs_co_run_in_worker( { errno = 0; Loading @@ -35,10 +39,14 @@ int v9fs_co_readdir_r(V9fsState *s, V9fsFidState *fidp, struct dirent *dent, return err; } off_t v9fs_co_telldir(V9fsState *s, V9fsFidState *fidp) off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp) { off_t err; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR; } v9fs_co_run_in_worker( { err = s->ops->telldir(&s->ctx, fidp->fs.dir); Loading @@ -49,67 +57,103 @@ off_t v9fs_co_telldir(V9fsState *s, V9fsFidState *fidp) return err; } void v9fs_co_seekdir(V9fsState *s, V9fsFidState *fidp, off_t offset) void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset) { V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return; } v9fs_co_run_in_worker( { s->ops->seekdir(&s->ctx, fidp->fs.dir, offset); }); } void v9fs_co_rewinddir(V9fsState *s, V9fsFidState *fidp) void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp) { V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return; } v9fs_co_run_in_worker( { s->ops->rewinddir(&s->ctx, fidp->fs.dir); }); } int v9fs_co_mkdir(V9fsState *s, char *name, mode_t mode, uid_t uid, gid_t gid) int v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, mode_t mode, uid_t uid, gid_t gid, struct stat *stbuf) { int err; FsCred cred; V9fsPath path; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR;; } cred_init(&cred); cred.fc_mode = mode; cred.fc_uid = uid; cred.fc_gid = gid; v9fs_path_read_lock(s); v9fs_co_run_in_worker( { err = s->ops->mkdir(&s->ctx, name, &cred); err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred); if (err < 0) { err = -errno; } else { v9fs_path_init(&path); err = v9fs_name_to_path(s, &fidp->path, name->data, &path); if (!err) { err = s->ops->lstat(&s->ctx, &path, stbuf); if (err < 0) { err = -errno; } } v9fs_path_free(&path); } }); v9fs_path_unlock(s); return err; } int v9fs_co_opendir(V9fsState *s, V9fsFidState *fidp) int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp) { int err; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR;; } v9fs_path_read_lock(s); v9fs_co_run_in_worker( { fidp->fs.dir = s->ops->opendir(&s->ctx, fidp->path.data); fidp->fs.dir = s->ops->opendir(&s->ctx, &fidp->path); if (!fidp->fs.dir) { err = -errno; } else { err = 0; } }); v9fs_path_unlock(s); if (!err) { total_open_fd++; if (total_open_fd > open_fd_hw) { v9fs_reclaim_fd(s); v9fs_reclaim_fd(pdu); } } return err; } int v9fs_co_closedir(V9fsState *s, DIR *dir) int v9fs_co_closedir(V9fsPDU *pdu, DIR *dir) { int err; V9fsState *s = pdu->s; if (v9fs_request_cancelled(pdu)) { return -EINTR;; } v9fs_co_run_in_worker( { err = s->ops->closedir(&s->ctx, dir); Loading