summaryrefslogtreecommitdiff
path: root/hw/9pfs
diff options
context:
space:
mode:
Diffstat (limited to 'hw/9pfs')
-rw-r--r--hw/9pfs/9p-handle.c24
-rw-r--r--hw/9pfs/9p-local.c36
-rw-r--r--hw/9pfs/9p-proxy.c26
-rw-r--r--hw/9pfs/9p-proxy.h5
-rw-r--r--hw/9pfs/9p-synth.c219
-rw-r--r--hw/9pfs/9p-synth.h5
-rw-r--r--hw/9pfs/9p-xattr.h5
-rw-r--r--hw/9pfs/9p.c214
-rw-r--r--hw/9pfs/9p.h30
-rw-r--r--hw/9pfs/codir.c13
-rw-r--r--hw/9pfs/cofile.c3
-rw-r--r--hw/9pfs/cofs.c3
-rw-r--r--hw/9pfs/coth.c5
-rw-r--r--hw/9pfs/coth.h11
-rw-r--r--hw/9pfs/coxattr.c3
-rw-r--r--hw/9pfs/trace-events47
-rw-r--r--hw/9pfs/virtio-9p-device.c16
-rw-r--r--hw/9pfs/virtio-9p.h4
18 files changed, 239 insertions, 430 deletions
diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c
index 3d77594f9..894041488 100644
--- a/hw/9pfs/9p-handle.c
+++ b/hw/9pfs/9p-handle.c
@@ -112,7 +112,7 @@ static int handle_close(FsContext *ctx, V9fsFidOpenState *fs)
static int handle_closedir(FsContext *ctx, V9fsFidOpenState *fs)
{
- return closedir(fs->dir.stream);
+ return closedir(fs->dir);
}
static int handle_open(FsContext *ctx, V9fsPath *fs_path,
@@ -132,8 +132,8 @@ static int handle_opendir(FsContext *ctx,
if (ret < 0) {
return -1;
}
- fs->dir.stream = fdopendir(ret);
- if (!fs->dir.stream) {
+ fs->dir = fdopendir(ret);
+ if (!fs->dir) {
return -1;
}
return 0;
@@ -141,22 +141,24 @@ static int handle_opendir(FsContext *ctx,
static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
{
- rewinddir(fs->dir.stream);
+ rewinddir(fs->dir);
}
static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs)
{
- return telldir(fs->dir.stream);
+ return telldir(fs->dir);
}
-static struct dirent *handle_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+static int handle_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+ struct dirent *entry,
+ struct dirent **result)
{
- return readdir(fs->dir.stream);
+ return readdir_r(fs->dir, entry, result);
}
static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
{
- seekdir(fs->dir.stream, off);
+ seekdir(fs->dir, off);
}
static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@@ -260,7 +262,7 @@ static int handle_fstat(FsContext *fs_ctx, int fid_type,
int fd;
if (fid_type == P9_FID_DIR) {
- fd = dirfd(fs->dir.stream);
+ fd = dirfd(fs->dir);
} else {
fd = fs->fd;
}
@@ -407,7 +409,7 @@ static int handle_fsync(FsContext *ctx, int fid_type,
int fd;
if (fid_type == P9_FID_DIR) {
- fd = dirfd(fs->dir.stream);
+ fd = dirfd(fs->dir);
} else {
fd = fs->fd;
}
@@ -679,7 +681,7 @@ FileOperations handle_ops = {
.opendir = handle_opendir,
.rewinddir = handle_rewinddir,
.telldir = handle_telldir,
- .readdir = handle_readdir,
+ .readdir_r = handle_readdir_r,
.seekdir = handle_seekdir,
.preadv = handle_preadv,
.pwritev = handle_pwritev,
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 3f271fcbd..16f45f485 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -348,7 +348,7 @@ static int local_close(FsContext *ctx, V9fsFidOpenState *fs)
static int local_closedir(FsContext *ctx, V9fsFidOpenState *fs)
{
- return closedir(fs->dir.stream);
+ return closedir(fs->dir);
}
static int local_open(FsContext *ctx, V9fsPath *fs_path,
@@ -370,9 +370,9 @@ static int local_opendir(FsContext *ctx,
char *path = fs_path->data;
buffer = rpath(ctx, path);
- fs->dir.stream = opendir(buffer);
+ fs->dir = opendir(buffer);
g_free(buffer);
- if (!fs->dir.stream) {
+ if (!fs->dir) {
return -1;
}
return 0;
@@ -380,40 +380,38 @@ static int local_opendir(FsContext *ctx,
static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
{
- rewinddir(fs->dir.stream);
+ rewinddir(fs->dir);
}
static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
{
- return telldir(fs->dir.stream);
+ return telldir(fs->dir);
}
-static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+ struct dirent *entry,
+ struct dirent **result)
{
- struct dirent *entry;
+ int ret;
again:
- entry = readdir(fs->dir.stream);
- if (!entry) {
- return NULL;
- }
-
+ ret = readdir_r(fs->dir, entry, result);
if (ctx->export_flags & V9FS_SM_MAPPED) {
entry->d_type = DT_UNKNOWN;
} else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
- if (!strcmp(entry->d_name, VIRTFS_META_DIR)) {
+ if (!ret && *result != NULL &&
+ !strcmp(entry->d_name, VIRTFS_META_DIR)) {
/* skp the meta data directory */
goto again;
}
entry->d_type = DT_UNKNOWN;
}
-
- return entry;
+ return ret;
}
static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
{
- seekdir(fs->dir.stream, off);
+ seekdir(fs->dir, off);
}
static ssize_t local_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@@ -612,7 +610,7 @@ static int local_fstat(FsContext *fs_ctx, int fid_type,
int err, fd;
if (fid_type == P9_FID_DIR) {
- fd = dirfd(fs->dir.stream);
+ fd = dirfd(fs->dir);
} else {
fd = fs->fd;
}
@@ -1000,7 +998,7 @@ static int local_fsync(FsContext *ctx, int fid_type,
int fd;
if (fid_type == P9_FID_DIR) {
- fd = dirfd(fs->dir.stream);
+ fd = dirfd(fs->dir);
} else {
fd = fs->fd;
}
@@ -1256,7 +1254,7 @@ FileOperations local_ops = {
.opendir = local_opendir,
.rewinddir = local_rewinddir,
.telldir = local_telldir,
- .readdir = local_readdir,
+ .readdir_r = local_readdir_r,
.seekdir = local_seekdir,
.preadv = local_preadv,
.pwritev = local_pwritev,
diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index f265501ea..00a4eb2a7 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -633,7 +633,7 @@ static int proxy_close(FsContext *ctx, V9fsFidOpenState *fs)
static int proxy_closedir(FsContext *ctx, V9fsFidOpenState *fs)
{
- return closedir(fs->dir.stream);
+ return closedir(fs->dir);
}
static int proxy_open(FsContext *ctx, V9fsPath *fs_path,
@@ -652,14 +652,14 @@ static int proxy_opendir(FsContext *ctx,
{
int serrno, fd;
- fs->dir.stream = NULL;
+ fs->dir = NULL;
fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY);
if (fd < 0) {
errno = -fd;
return -1;
}
- fs->dir.stream = fdopendir(fd);
- if (!fs->dir.stream) {
+ fs->dir = fdopendir(fd);
+ if (!fs->dir) {
serrno = errno;
close(fd);
errno = serrno;
@@ -670,22 +670,24 @@ static int proxy_opendir(FsContext *ctx,
static void proxy_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
{
- rewinddir(fs->dir.stream);
+ rewinddir(fs->dir);
}
static off_t proxy_telldir(FsContext *ctx, V9fsFidOpenState *fs)
{
- return telldir(fs->dir.stream);
+ return telldir(fs->dir);
}
-static struct dirent *proxy_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+static int proxy_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+ struct dirent *entry,
+ struct dirent **result)
{
- return readdir(fs->dir.stream);
+ return readdir_r(fs->dir, entry, result);
}
static void proxy_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
{
- seekdir(fs->dir.stream, off);
+ seekdir(fs->dir, off);
}
static ssize_t proxy_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@@ -789,7 +791,7 @@ static int proxy_fstat(FsContext *fs_ctx, int fid_type,
int fd;
if (fid_type == P9_FID_DIR) {
- fd = dirfd(fs->dir.stream);
+ fd = dirfd(fs->dir);
} else {
fd = fs->fd;
}
@@ -934,7 +936,7 @@ static int proxy_fsync(FsContext *ctx, int fid_type,
int fd;
if (fid_type == P9_FID_DIR) {
- fd = dirfd(fs->dir.stream);
+ fd = dirfd(fs->dir);
} else {
fd = fs->fd;
}
@@ -1190,7 +1192,7 @@ FileOperations proxy_ops = {
.opendir = proxy_opendir,
.rewinddir = proxy_rewinddir,
.telldir = proxy_telldir,
- .readdir = proxy_readdir,
+ .readdir_r = proxy_readdir_r,
.seekdir = proxy_seekdir,
.preadv = proxy_preadv,
.pwritev = proxy_pwritev,
diff --git a/hw/9pfs/9p-proxy.h b/hw/9pfs/9p-proxy.h
index b84301d00..ba9ca203d 100644
--- a/hw/9pfs/9p-proxy.h
+++ b/hw/9pfs/9p-proxy.h
@@ -9,9 +9,8 @@
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/
-
-#ifndef QEMU_9P_PROXY_H
-#define QEMU_9P_PROXY_H
+#ifndef _QEMU_9P_PROXY_H
+#define _QEMU_9P_PROXY_H
#define PROXY_MAX_IO_SZ (64 * 1024)
#define V9FS_FD_VALID INT_MAX
diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c
index 4b6d4e6a3..f1475dfd6 100644
--- a/hw/9pfs/9p-synth.c
+++ b/hw/9pfs/9p-synth.c
@@ -1,5 +1,5 @@
/*
- * 9p synthetic file system support
+ * Virtio 9p synthetic file system support
*
* Copyright IBM, Corp. 2011
*
@@ -13,7 +13,9 @@
*/
#include "qemu/osdep.h"
+#include "hw/virtio/virtio.h"
#include "9p.h"
+#include "9p-xattr.h"
#include "fsdev/qemu-fsdev.h"
#include "9p-synth.h"
#include "qemu/rcu.h"
@@ -21,19 +23,19 @@
#include "qemu/cutils.h"
/* Root node for synth file system */
-static V9fsSynthNode synth_root = {
+static V9fsSynthNode v9fs_synth_root = {
.name = "/",
.actual_attr = {
.mode = 0555 | S_IFDIR,
.nlink = 1,
},
- .attr = &synth_root.actual_attr,
+ .attr = &v9fs_synth_root.actual_attr,
};
-static QemuMutex synth_mutex;
-static int synth_node_count;
+static QemuMutex v9fs_synth_mutex;
+static int v9fs_synth_node_count;
/* set to 1 when the synth fs is ready */
-static int synth_fs;
+static int v9fs_synth_fs;
static V9fsSynthNode *v9fs_add_dir_node(V9fsSynthNode *parent, int mode,
const char *name,
@@ -69,16 +71,16 @@ int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
int ret;
V9fsSynthNode *node, *tmp;
- if (!synth_fs) {
+ if (!v9fs_synth_fs) {
return EAGAIN;
}
if (!name || (strlen(name) >= NAME_MAX)) {
return EINVAL;
}
if (!parent) {
- parent = &synth_root;
+ parent = &v9fs_synth_root;
}
- qemu_mutex_lock(&synth_mutex);
+ qemu_mutex_lock(&v9fs_synth_mutex);
QLIST_FOREACH(tmp, &parent->child, sibling) {
if (!strcmp(tmp->name, name)) {
ret = EEXIST;
@@ -86,7 +88,7 @@ int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
}
}
/* Add the name */
- node = v9fs_add_dir_node(parent, mode, name, NULL, synth_node_count++);
+ node = v9fs_add_dir_node(parent, mode, name, NULL, v9fs_synth_node_count++);
v9fs_add_dir_node(node, parent->attr->mode, "..",
parent->attr, parent->attr->inode);
v9fs_add_dir_node(node, node->attr->mode, ".",
@@ -94,7 +96,7 @@ int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
*result = node;
ret = 0;
err_out:
- qemu_mutex_unlock(&synth_mutex);
+ qemu_mutex_unlock(&v9fs_synth_mutex);
return ret;
}
@@ -105,17 +107,17 @@ int qemu_v9fs_synth_add_file(V9fsSynthNode *parent, int mode,
int ret;
V9fsSynthNode *node, *tmp;
- if (!synth_fs) {
+ if (!v9fs_synth_fs) {
return EAGAIN;
}
if (!name || (strlen(name) >= NAME_MAX)) {
return EINVAL;
}
if (!parent) {
- parent = &synth_root;
+ parent = &v9fs_synth_root;
}
- qemu_mutex_lock(&synth_mutex);
+ qemu_mutex_lock(&v9fs_synth_mutex);
QLIST_FOREACH(tmp, &parent->child, sibling) {
if (!strcmp(tmp->name, name)) {
ret = EEXIST;
@@ -126,7 +128,7 @@ int qemu_v9fs_synth_add_file(V9fsSynthNode *parent, int mode,
mode = ((mode & 0777) | S_IFREG);
node = g_malloc0(sizeof(V9fsSynthNode));
node->attr = &node->actual_attr;
- node->attr->inode = synth_node_count++;
+ node->attr->inode = v9fs_synth_node_count++;
node->attr->nlink = 1;
node->attr->read = read;
node->attr->write = write;
@@ -136,11 +138,11 @@ int qemu_v9fs_synth_add_file(V9fsSynthNode *parent, int mode,
QLIST_INSERT_HEAD_RCU(&parent->child, node, sibling);
ret = 0;
err_out:
- qemu_mutex_unlock(&synth_mutex);
+ qemu_mutex_unlock(&v9fs_synth_mutex);
return ret;
}
-static void synth_fill_statbuf(V9fsSynthNode *node, struct stat *stbuf)
+static void v9fs_synth_fill_statbuf(V9fsSynthNode *node, struct stat *stbuf)
{
stbuf->st_dev = 0;
stbuf->st_ino = node->attr->inode;
@@ -157,24 +159,24 @@ static void synth_fill_statbuf(V9fsSynthNode *node, struct stat *stbuf)
stbuf->st_ctime = 0;
}
-static int synth_lstat(FsContext *fs_ctx,
+static int v9fs_synth_lstat(FsContext *fs_ctx,
V9fsPath *fs_path, struct stat *stbuf)
{
V9fsSynthNode *node = *(V9fsSynthNode **)fs_path->data;
- synth_fill_statbuf(node, stbuf);
+ v9fs_synth_fill_statbuf(node, stbuf);
return 0;
}
-static int synth_fstat(FsContext *fs_ctx, int fid_type,
+static int v9fs_synth_fstat(FsContext *fs_ctx, int fid_type,
V9fsFidOpenState *fs, struct stat *stbuf)
{
V9fsSynthOpenState *synth_open = fs->private;
- synth_fill_statbuf(synth_open->node, stbuf);
+ v9fs_synth_fill_statbuf(synth_open->node, stbuf);
return 0;
}
-static int synth_opendir(FsContext *ctx,
+static int v9fs_synth_opendir(FsContext *ctx,
V9fsPath *fs_path, V9fsFidOpenState *fs)
{
V9fsSynthOpenState *synth_open;
@@ -187,7 +189,7 @@ static int synth_opendir(FsContext *ctx,
return 0;
}
-static int synth_closedir(FsContext *ctx, V9fsFidOpenState *fs)
+static int v9fs_synth_closedir(FsContext *ctx, V9fsFidOpenState *fs)
{
V9fsSynthOpenState *synth_open = fs->private;
V9fsSynthNode *node = synth_open->node;
@@ -198,24 +200,24 @@ static int synth_closedir(FsContext *ctx, V9fsFidOpenState *fs)
return 0;
}
-static off_t synth_telldir(FsContext *ctx, V9fsFidOpenState *fs)
+static off_t v9fs_synth_telldir(FsContext *ctx, V9fsFidOpenState *fs)
{
V9fsSynthOpenState *synth_open = fs->private;
return synth_open->offset;
}
-static void synth_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
+static void v9fs_synth_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
{
V9fsSynthOpenState *synth_open = fs->private;
synth_open->offset = off;
}
-static void synth_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
+static void v9fs_synth_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
{
- synth_seekdir(ctx, fs, 0);
+ v9fs_synth_seekdir(ctx, fs, 0);
}
-static void synth_direntry(V9fsSynthNode *node,
+static void v9fs_synth_direntry(V9fsSynthNode *node,
struct dirent *entry, off_t off)
{
strcpy(entry->d_name, node->name);
@@ -223,8 +225,8 @@ static void synth_direntry(V9fsSynthNode *node,
entry->d_off = off + 1;
}
-static struct dirent *synth_get_dentry(V9fsSynthNode *dir,
- struct dirent *entry, off_t off)
+static int v9fs_synth_get_dentry(V9fsSynthNode *dir, struct dirent *entry,
+ struct dirent **result, off_t off)
{
int i = 0;
V9fsSynthNode *node;
@@ -240,25 +242,28 @@ static struct dirent *synth_get_dentry(V9fsSynthNode *dir,
rcu_read_unlock();
if (!node) {
/* end of directory */
- return NULL;
+ *result = NULL;
+ return 0;
}
- synth_direntry(node, entry, off);
- return entry;
+ v9fs_synth_direntry(node, entry, off);
+ *result = entry;
+ return 0;
}
-static struct dirent *synth_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+static int v9fs_synth_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+ struct dirent *entry, struct dirent **result)
{
- struct dirent *entry;
+ int ret;
V9fsSynthOpenState *synth_open = fs->private;
V9fsSynthNode *node = synth_open->node;
- entry = synth_get_dentry(node, &synth_open->dent, synth_open->offset);
- if (entry) {
+ ret = v9fs_synth_get_dentry(node, entry, result, synth_open->offset);
+ if (!ret && *result != NULL) {
synth_open->offset++;
}
- return entry;
+ return ret;
}
-static int synth_open(FsContext *ctx, V9fsPath *fs_path,
+static int v9fs_synth_open(FsContext *ctx, V9fsPath *fs_path,
int flags, V9fsFidOpenState *fs)
{
V9fsSynthOpenState *synth_open;
@@ -271,7 +276,7 @@ static int synth_open(FsContext *ctx, V9fsPath *fs_path,
return 0;
}
-static int synth_open2(FsContext *fs_ctx, V9fsPath *dir_path,
+static int v9fs_synth_open2(FsContext *fs_ctx, V9fsPath *dir_path,
const char *name, int flags,
FsCred *credp, V9fsFidOpenState *fs)
{
@@ -279,7 +284,7 @@ static int synth_open2(FsContext *fs_ctx, V9fsPath *dir_path,
return -1;
}
-static int synth_close(FsContext *ctx, V9fsFidOpenState *fs)
+static int v9fs_synth_close(FsContext *ctx, V9fsFidOpenState *fs)
{
V9fsSynthOpenState *synth_open = fs->private;
V9fsSynthNode *node = synth_open->node;
@@ -290,7 +295,7 @@ static int synth_close(FsContext *ctx, V9fsFidOpenState *fs)
return 0;
}
-static ssize_t synth_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
+static ssize_t v9fs_synth_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
const struct iovec *iov,
int iovcnt, off_t offset)
{
@@ -314,7 +319,7 @@ static ssize_t synth_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
return count;
}
-static ssize_t synth_preadv(FsContext *ctx, V9fsFidOpenState *fs,
+static ssize_t v9fs_synth_preadv(FsContext *ctx, V9fsFidOpenState *fs,
const struct iovec *iov,
int iovcnt, off_t offset)
{
@@ -338,112 +343,112 @@ static ssize_t synth_preadv(FsContext *ctx, V9fsFidOpenState *fs,
return count;
}
-static int synth_truncate(FsContext *ctx, V9fsPath *path, off_t offset)
+static int v9fs_synth_truncate(FsContext *ctx, V9fsPath *path, off_t offset)
{
errno = ENOSYS;
return -1;
}
-static int synth_chmod(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
+static int v9fs_synth_chmod(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
{
errno = EPERM;
return -1;
}
-static int synth_mknod(FsContext *fs_ctx, V9fsPath *path,
+static int v9fs_synth_mknod(FsContext *fs_ctx, V9fsPath *path,
const char *buf, FsCred *credp)
{
errno = EPERM;
return -1;
}
-static int synth_mkdir(FsContext *fs_ctx, V9fsPath *path,
+static int v9fs_synth_mkdir(FsContext *fs_ctx, V9fsPath *path,
const char *buf, FsCred *credp)
{
errno = EPERM;
return -1;
}
-static ssize_t synth_readlink(FsContext *fs_ctx, V9fsPath *path,
+static ssize_t v9fs_synth_readlink(FsContext *fs_ctx, V9fsPath *path,
char *buf, size_t bufsz)
{
errno = ENOSYS;
return -1;
}
-static int synth_symlink(FsContext *fs_ctx, const char *oldpath,
+static int v9fs_synth_symlink(FsContext *fs_ctx, const char *oldpath,
V9fsPath *newpath, const char *buf, FsCred *credp)
{
errno = EPERM;
return -1;
}
-static int synth_link(FsContext *fs_ctx, V9fsPath *oldpath,
+static int v9fs_synth_link(FsContext *fs_ctx, V9fsPath *oldpath,
V9fsPath *newpath, const char *buf)
{
errno = EPERM;
return -1;
}
-static int synth_rename(FsContext *ctx, const char *oldpath,
+static int v9fs_synth_rename(FsContext *ctx, const char *oldpath,
const char *newpath)
{
errno = EPERM;
return -1;
}
-static int synth_chown(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
+static int v9fs_synth_chown(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
{
errno = EPERM;
return -1;
}
-static int synth_utimensat(FsContext *fs_ctx, V9fsPath *path,
+static int v9fs_synth_utimensat(FsContext *fs_ctx, V9fsPath *path,
const struct timespec *buf)
{
errno = EPERM;
return 0;
}
-static int synth_remove(FsContext *ctx, const char *path)
+static int v9fs_synth_remove(FsContext *ctx, const char *path)
{
errno = EPERM;
return -1;
}
-static int synth_fsync(FsContext *ctx, int fid_type,
+static int v9fs_synth_fsync(FsContext *ctx, int fid_type,
V9fsFidOpenState *fs, int datasync)
{
errno = ENOSYS;
return 0;
}
-static int synth_statfs(FsContext *s, V9fsPath *fs_path,
+static int v9fs_synth_statfs(FsContext *s, V9fsPath *fs_path,
struct statfs *stbuf)
{
stbuf->f_type = 0xABCD;
stbuf->f_bsize = 512;
stbuf->f_blocks = 0;
- stbuf->f_files = synth_node_count;
+ stbuf->f_files = v9fs_synth_node_count;
stbuf->f_namelen = NAME_MAX;
return 0;
}
-static ssize_t synth_lgetxattr(FsContext *ctx, V9fsPath *path,
+static ssize_t v9fs_synth_lgetxattr(FsContext *ctx, V9fsPath *path,
const char *name, void *value, size_t size)
{
errno = ENOTSUP;
return -1;
}
-static ssize_t synth_llistxattr(FsContext *ctx, V9fsPath *path,
+static ssize_t v9fs_synth_llistxattr(FsContext *ctx, V9fsPath *path,
void *value, size_t size)
{
errno = ENOTSUP;
return -1;
}
-static int synth_lsetxattr(FsContext *ctx, V9fsPath *path,
+static int v9fs_synth_lsetxattr(FsContext *ctx, V9fsPath *path,
const char *name, void *value,
size_t size, int flags)
{
@@ -451,14 +456,14 @@ static int synth_lsetxattr(FsContext *ctx, V9fsPath *path,
return -1;
}
-static int synth_lremovexattr(FsContext *ctx,
+static int v9fs_synth_lremovexattr(FsContext *ctx,
V9fsPath *path, const char *name)
{
errno = ENOTSUP;
return -1;
}
-static int synth_name_to_path(FsContext *ctx, V9fsPath *dir_path,
+static int v9fs_synth_name_to_path(FsContext *ctx, V9fsPath *dir_path,
const char *name, V9fsPath *target)
{
V9fsSynthNode *node;
@@ -471,7 +476,7 @@ static int synth_name_to_path(FsContext *ctx, V9fsPath *dir_path,
}
if (!dir_path) {
- dir_node = &synth_root;
+ dir_node = &v9fs_synth_root;
} else {
dir_node = *(V9fsSynthNode **)dir_path->data;
}
@@ -500,7 +505,7 @@ out:
return 0;
}
-static int synth_renameat(FsContext *ctx, V9fsPath *olddir,
+static int v9fs_synth_renameat(FsContext *ctx, V9fsPath *olddir,
const char *old_name, V9fsPath *newdir,
const char *new_name)
{
@@ -508,62 +513,62 @@ static int synth_renameat(FsContext *ctx, V9fsPath *olddir,
return -1;
}
-static int synth_unlinkat(FsContext *ctx, V9fsPath *dir,
+static int v9fs_synth_unlinkat(FsContext *ctx, V9fsPath *dir,
const char *name, int flags)
{
errno = EPERM;
return -1;
}
-static int synth_init(FsContext *ctx)
+static int v9fs_synth_init(FsContext *ctx)
{
- QLIST_INIT(&synth_root.child);
- qemu_mutex_init(&synth_mutex);
+ QLIST_INIT(&v9fs_synth_root.child);
+ qemu_mutex_init(&v9fs_synth_mutex);
/* Add "." and ".." entries for root */
- v9fs_add_dir_node(&synth_root, synth_root.attr->mode,
- "..", synth_root.attr, synth_root.attr->inode);
- v9fs_add_dir_node(&synth_root, synth_root.attr->mode,
- ".", synth_root.attr, synth_root.attr->inode);
+ v9fs_add_dir_node(&v9fs_synth_root, v9fs_synth_root.attr->mode,
+ "..", v9fs_synth_root.attr, v9fs_synth_root.attr->inode);
+ v9fs_add_dir_node(&v9fs_synth_root, v9fs_synth_root.attr->mode,
+ ".", v9fs_synth_root.attr, v9fs_synth_root.attr->inode);
/* Mark the subsystem is ready for use */
- synth_fs = 1;
+ v9fs_synth_fs = 1;
return 0;
}
FileOperations synth_ops = {
- .init = synth_init,
- .lstat = synth_lstat,
- .readlink = synth_readlink,
- .close = synth_close,
- .closedir = synth_closedir,
- .open = synth_open,
- .opendir = synth_opendir,
- .rewinddir = synth_rewinddir,
- .telldir = synth_telldir,
- .readdir = synth_readdir,
- .seekdir = synth_seekdir,
- .preadv = synth_preadv,
- .pwritev = synth_pwritev,
- .chmod = synth_chmod,
- .mknod = synth_mknod,
- .mkdir = synth_mkdir,
- .fstat = synth_fstat,
- .open2 = synth_open2,
- .symlink = synth_symlink,
- .link = synth_link,
- .truncate = synth_truncate,
- .rename = synth_rename,
- .chown = synth_chown,
- .utimensat = synth_utimensat,
- .remove = synth_remove,
- .fsync = synth_fsync,
- .statfs = synth_statfs,
- .lgetxattr = synth_lgetxattr,
- .llistxattr = synth_llistxattr,
- .lsetxattr = synth_lsetxattr,
- .lremovexattr = synth_lremovexattr,
- .name_to_path = synth_name_to_path,
- .renameat = synth_renameat,
- .unlinkat = synth_unlinkat,
+ .init = v9fs_synth_init,
+ .lstat = v9fs_synth_lstat,
+ .readlink = v9fs_synth_readlink,
+ .close = v9fs_synth_close,
+ .closedir = v9fs_synth_closedir,
+ .open = v9fs_synth_open,
+ .opendir = v9fs_synth_opendir,
+ .rewinddir = v9fs_synth_rewinddir,
+ .telldir = v9fs_synth_telldir,
+ .readdir_r = v9fs_synth_readdir_r,
+ .seekdir = v9fs_synth_seekdir,
+ .preadv = v9fs_synth_preadv,
+ .pwritev = v9fs_synth_pwritev,
+ .chmod = v9fs_synth_chmod,
+ .mknod = v9fs_synth_mknod,
+ .mkdir = v9fs_synth_mkdir,
+ .fstat = v9fs_synth_fstat,
+ .open2 = v9fs_synth_open2,
+ .symlink = v9fs_synth_symlink,
+ .link = v9fs_synth_link,
+ .truncate = v9fs_synth_truncate,
+ .rename = v9fs_synth_rename,
+ .chown = v9fs_synth_chown,
+ .utimensat = v9fs_synth_utimensat,
+ .remove = v9fs_synth_remove,
+ .fsync = v9fs_synth_fsync,
+ .statfs = v9fs_synth_statfs,
+ .lgetxattr = v9fs_synth_lgetxattr,
+ .llistxattr = v9fs_synth_llistxattr,
+ .lsetxattr = v9fs_synth_lsetxattr,
+ .lremovexattr = v9fs_synth_lremovexattr,
+ .name_to_path = v9fs_synth_name_to_path,
+ .renameat = v9fs_synth_renameat,
+ .unlinkat = v9fs_synth_unlinkat,
};
diff --git a/hw/9pfs/9p-synth.h b/hw/9pfs/9p-synth.h
index 6bcb44ace..82962512a 100644
--- a/hw/9pfs/9p-synth.h
+++ b/hw/9pfs/9p-synth.h
@@ -10,9 +10,9 @@
* the COPYING file in the top-level directory.
*
*/
+#ifndef HW_9PFS_SYNTH_H
+#define HW_9PFS_SYNTH_H 1
-#ifndef QEMU_9P_SYNTH_H
-#define QEMU_9P_SYNTH_H
typedef struct V9fsSynthNode V9fsSynthNode;
typedef ssize_t (*v9fs_synth_read)(void *buf, int len, off_t offset,
@@ -40,7 +40,6 @@ struct V9fsSynthNode {
typedef struct V9fsSynthOpenState {
off_t offset;
V9fsSynthNode *node;
- struct dirent dent;
} V9fsSynthOpenState;
extern int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
diff --git a/hw/9pfs/9p-xattr.h b/hw/9pfs/9p-xattr.h
index a853ea641..4d39a2026 100644
--- a/hw/9pfs/9p-xattr.h
+++ b/hw/9pfs/9p-xattr.h
@@ -10,9 +10,8 @@
* the COPYING file in the top-level directory.
*
*/
-
-#ifndef QEMU_9P_XATTR_H
-#define QEMU_9P_XATTR_H
+#ifndef _QEMU_9P_XATTR_H
+#define _QEMU_9P_XATTR_H
#include "qemu/xattr.h"
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index dfe293d11..f5e30125f 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -13,6 +13,7 @@
#include "qemu/osdep.h"
#include "hw/virtio/virtio.h"
+#include "hw/i386/pc.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/iov.h"
@@ -231,7 +232,7 @@ static int v9fs_reopen_fid(V9fsPDU *pdu, V9fsFidState *f)
} while (err == -EINTR && !pdu->cancelled);
}
} else if (f->fid_type == P9_FID_DIR) {
- if (f->fs.dir.stream == NULL) {
+ if (f->fs.dir == NULL) {
do {
err = v9fs_co_opendir(pdu, f);
} while (err == -EINTR && !pdu->cancelled);
@@ -300,9 +301,6 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
f->next = s->fid_list;
s->fid_list = f;
- v9fs_readdir_init(&f->fs.dir);
- v9fs_readdir_init(&f->fs_reclaim.dir);
-
return f;
}
@@ -348,7 +346,7 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp)
retval = v9fs_co_close(pdu, &fidp->fs);
}
} else if (fidp->fid_type == P9_FID_DIR) {
- if (fidp->fs.dir.stream != NULL) {
+ if (fidp->fs.dir != NULL) {
retval = v9fs_co_closedir(pdu, &fidp->fs);
}
} else if (fidp->fid_type == P9_FID_XATTR) {
@@ -446,7 +444,7 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
reclaim_count++;
}
} else if (f->fid_type == P9_FID_DIR) {
- if (f->fs.dir.stream != NULL) {
+ if (f->fs.dir != NULL) {
/*
* Up the reference count so that
* a clunk request won't free this fid
@@ -454,8 +452,8 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
f->ref++;
f->rclm_lst = reclaim_list;
reclaim_list = f;
- f->fs_reclaim.dir.stream = f->fs.dir.stream;
- f->fs.dir.stream = NULL;
+ f->fs_reclaim.dir = f->fs.dir;
+ f->fs.dir = NULL;
reclaim_count++;
}
}
@@ -1010,7 +1008,6 @@ static void v9fs_attach(void *opaque)
goto out;
}
err += offset;
- memcpy(&s->root_qid, &qid, sizeof(qid));
trace_v9fs_attach_return(pdu->tag, pdu->id,
qid.type, qid.version, qid.path);
/*
@@ -1257,19 +1254,6 @@ static int v9fs_walk_marshal(V9fsPDU *pdu, uint16_t nwnames, V9fsQID *qids)
return offset;
}
-static bool name_is_illegal(const char *name)
-{
- return !*name || strchr(name, '/') != NULL;
-}
-
-static bool not_same_qid(const V9fsQID *qid1, const V9fsQID *qid2)
-{
- return
- qid1->type != qid2->type ||
- qid1->version != qid2->version ||
- qid1->path != qid2->path;
-}
-
static void v9fs_walk(void *opaque)
{
int name_idx;
@@ -1285,7 +1269,6 @@ static void v9fs_walk(void *opaque)
V9fsFidState *newfidp = NULL;
V9fsPDU *pdu = opaque;
V9fsState *s = pdu->s;
- V9fsQID qid;
err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames);
if (err < 0) {
@@ -1304,10 +1287,6 @@ static void v9fs_walk(void *opaque)
if (err < 0) {
goto out_nofid;
}
- if (name_is_illegal(wnames[i].data)) {
- err = -ENOENT;
- goto out_nofid;
- }
offset += err;
}
} else if (nwnames > P9_MAXWELEM) {
@@ -1319,12 +1298,6 @@ static void v9fs_walk(void *opaque)
err = -ENOENT;
goto out_nofid;
}
-
- err = fid_to_qid(pdu, fidp, &qid);
- if (err < 0) {
- goto out;
- }
-
v9fs_path_init(&dpath);
v9fs_path_init(&path);
/*
@@ -1334,22 +1307,16 @@ static void v9fs_walk(void *opaque)
v9fs_path_copy(&dpath, &fidp->path);
v9fs_path_copy(&path, &fidp->path);
for (name_idx = 0; name_idx < nwnames; name_idx++) {
- if (not_same_qid(&pdu->s->root_qid, &qid) ||
- strcmp("..", wnames[name_idx].data)) {
- err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data,
- &path);
- if (err < 0) {
- goto out;
- }
-
- err = v9fs_co_lstat(pdu, &path, &stbuf);
- if (err < 0) {
- goto out;
- }
- stat_to_qid(&stbuf, &qid);
- v9fs_path_copy(&dpath, &path);
+ err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, &path);
+ if (err < 0) {
+ goto out;
}
- memcpy(&qids[name_idx], &qid, sizeof(qid));
+ err = v9fs_co_lstat(pdu, &path, &stbuf);
+ if (err < 0) {
+ goto out;
+ }
+ stat_to_qid(&stbuf, &qids[name_idx]);
+ v9fs_path_copy(&dpath, &path);
}
if (fid == newfid) {
BUG_ON(fidp->fid_type != P9_FID_NONE);
@@ -1514,16 +1481,6 @@ static void v9fs_lcreate(void *opaque)
}
trace_v9fs_lcreate(pdu->tag, pdu->id, dfid, flags, mode, gid);
- if (name_is_illegal(name.data)) {
- err = -ENOENT;
- goto out_nofid;
- }
-
- if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
- err = -EEXIST;
- goto out_nofid;
- }
-
fidp = get_fid(pdu, dfid);
if (fidp == NULL) {
err = -ENOENT;
@@ -1668,7 +1625,7 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
int32_t count = 0;
struct stat stbuf;
off_t saved_dir_pos;
- struct dirent *dent;
+ struct dirent *dent, *result;
/* save the directory position */
saved_dir_pos = v9fs_co_telldir(pdu, fidp);
@@ -1676,37 +1633,34 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
return saved_dir_pos;
}
+ dent = g_malloc(sizeof(struct dirent));
+
while (1) {
v9fs_path_init(&path);
-
- v9fs_readdir_lock(&fidp->fs.dir);
-
- err = v9fs_co_readdir(pdu, fidp, &dent);
- if (err || !dent) {
+ err = v9fs_co_readdir_r(pdu, fidp, dent, &result);
+ if (err || !result) {
break;
}
err = v9fs_co_name_to_path(pdu, &fidp->path, dent->d_name, &path);
if (err < 0) {
- break;
+ goto out;
}
err = v9fs_co_lstat(pdu, &path, &stbuf);
if (err < 0) {
- break;
+ goto out;
}
err = stat_to_v9stat(pdu, &path, &stbuf, &v9stat);
if (err < 0) {
- break;
+ goto out;
}
/* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */
len = pdu_marshal(pdu, 11 + count, "S", &v9stat);
-
- v9fs_readdir_unlock(&fidp->fs.dir);
-
if ((len != (v9stat.size + 2)) || ((count + len) > max_count)) {
/* Ran out of buffer. Set dir back to old position and return */
v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
v9fs_stat_free(&v9stat);
v9fs_path_free(&path);
+ g_free(dent);
return count;
}
count += len;
@@ -1714,9 +1668,8 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
v9fs_path_free(&path);
saved_dir_pos = dent->d_off;
}
-
- v9fs_readdir_unlock(&fidp->fs.dir);
-
+out:
+ g_free(dent);
v9fs_path_free(&path);
if (err < 0) {
return err;
@@ -1852,7 +1805,7 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
int len, err = 0;
int32_t count = 0;
off_t saved_dir_pos;
- struct dirent *dent;
+ struct dirent *dent, *result;
/* save the directory position */
saved_dir_pos = v9fs_co_telldir(pdu, fidp);
@@ -1860,21 +1813,20 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
return saved_dir_pos;
}
- while (1) {
- v9fs_readdir_lock(&fidp->fs.dir);
+ dent = g_malloc(sizeof(struct dirent));
- err = v9fs_co_readdir(pdu, fidp, &dent);
- if (err || !dent) {
+ while (1) {
+ err = v9fs_co_readdir_r(pdu, fidp, dent, &result);
+ if (err || !result) {
break;
}
v9fs_string_init(&name);
v9fs_string_sprintf(&name, "%s", dent->d_name);
if ((count + v9fs_readdir_data_size(&name)) > max_count) {
- v9fs_readdir_unlock(&fidp->fs.dir);
-
/* Ran out of buffer. Set dir back to old position and return */
v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
v9fs_string_free(&name);
+ g_free(dent);
return count;
}
/*
@@ -1892,21 +1844,17 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
len = pdu_marshal(pdu, 11 + count, "Qqbs",
&qid, dent->d_off,
dent->d_type, &name);
-
- v9fs_readdir_unlock(&fidp->fs.dir);
-
if (len < 0) {
v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
v9fs_string_free(&name);
+ g_free(dent);
return len;
}
count += len;
v9fs_string_free(&name);
saved_dir_pos = dent->d_off;
}
-
- v9fs_readdir_unlock(&fidp->fs.dir);
-
+ g_free(dent);
if (err < 0) {
return err;
}
@@ -1936,7 +1884,7 @@ static void v9fs_readdir(void *opaque)
retval = -EINVAL;
goto out_nofid;
}
- if (!fidp->fs.dir.stream) {
+ if (!fidp->fs.dir) {
retval = -EINVAL;
goto out;
}
@@ -2118,16 +2066,6 @@ static void v9fs_create(void *opaque)
}
trace_v9fs_create(pdu->tag, pdu->id, fid, name.data, perm, mode);
- if (name_is_illegal(name.data)) {
- err = -ENOENT;
- goto out_nofid;
- }
-
- if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
- err = -EEXIST;
- goto out_nofid;
- }
-
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -EINVAL;
@@ -2293,16 +2231,6 @@ static void v9fs_symlink(void *opaque)
}
trace_v9fs_symlink(pdu->tag, pdu->id, dfid, name.data, symname.data, gid);
- if (name_is_illegal(name.data)) {
- err = -ENOENT;
- goto out_nofid;
- }
-
- if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
- err = -EEXIST;
- goto out_nofid;
- }
-
dfidp = get_fid(pdu, dfid);
if (dfidp == NULL) {
err = -EINVAL;
@@ -2377,16 +2305,6 @@ static void v9fs_link(void *opaque)
}
trace_v9fs_link(pdu->tag, pdu->id, dfid, oldfid, name.data);
- if (name_is_illegal(name.data)) {
- err = -ENOENT;
- goto out_nofid;
- }
-
- if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
- err = -EEXIST;
- goto out_nofid;
- }
-
dfidp = get_fid(pdu, dfid);
if (dfidp == NULL) {
err = -ENOENT;
@@ -2469,22 +2387,6 @@ static void v9fs_unlinkat(void *opaque)
if (err < 0) {
goto out_nofid;
}
-
- if (name_is_illegal(name.data)) {
- err = -ENOENT;
- goto out_nofid;
- }
-
- if (!strcmp(".", name.data)) {
- err = -EINVAL;
- goto out_nofid;
- }
-
- if (!strcmp("..", name.data)) {
- err = -ENOTEMPTY;
- goto out_nofid;
- }
-
dfidp = get_fid(pdu, dfid);
if (dfidp == NULL) {
err = -EINVAL;
@@ -2591,17 +2493,6 @@ static void v9fs_rename(void *opaque)
if (err < 0) {
goto out_nofid;
}
-
- if (name_is_illegal(name.data)) {
- err = -ENOENT;
- goto out_nofid;
- }
-
- if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
- err = -EISDIR;
- goto out_nofid;
- }
-
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -ENOENT;
@@ -2714,17 +2605,6 @@ static void v9fs_renameat(void *opaque)
goto out_err;
}
- if (name_is_illegal(old_name.data) || name_is_illegal(new_name.data)) {
- err = -ENOENT;
- goto out_err;
- }
-
- if (!strcmp(".", old_name.data) || !strcmp("..", old_name.data) ||
- !strcmp(".", new_name.data) || !strcmp("..", new_name.data)) {
- err = -EISDIR;
- goto out_err;
- }
-
v9fs_path_write_lock(s);
err = v9fs_complete_renameat(pdu, olddirfid,
&old_name, newdirfid, &new_name);
@@ -2935,16 +2815,6 @@ static void v9fs_mknod(void *opaque)
}
trace_v9fs_mknod(pdu->tag, pdu->id, fid, mode, major, minor);
- if (name_is_illegal(name.data)) {
- err = -ENOENT;
- goto out_nofid;
- }
-
- if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
- err = -EEXIST;
- goto out_nofid;
- }
-
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -ENOENT;
@@ -3096,16 +2966,6 @@ static void v9fs_mkdir(void *opaque)
}
trace_v9fs_mkdir(pdu->tag, pdu->id, fid, name.data, mode, gid);
- if (name_is_illegal(name.data)) {
- err = -ENOENT;
- goto out_nofid;
- }
-
- if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
- err = -EEXIST;
- goto out_nofid;
- }
-
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -ENOENT;
@@ -3407,8 +3267,8 @@ void pdu_submit(V9fsPDU *pdu)
if (is_ro_export(&s->ctx) && !is_read_only_op(pdu)) {
handler = v9fs_fs_ro;
}
- co = qemu_coroutine_create(handler, pdu);
- qemu_coroutine_enter(co);
+ co = qemu_coroutine_create(handler);
+ qemu_coroutine_enter(co, pdu);
}
/* Returns 0 on success, 1 on failure. */
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index a38603398..1a19418a8 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -1,9 +1,12 @@
-#ifndef QEMU_9P_H
-#define QEMU_9P_H
+#ifndef _QEMU_9P_H
+#define _QEMU_9P_H
#include <dirent.h>
#include <utime.h>
#include <sys/resource.h>
+#include <glib.h>
+#include "standard-headers/linux/virtio_9p.h"
+#include "hw/virtio/virtio.h"
#include "fsdev/file-op-9p.h"
#include "fsdev/9p-iov-marshal.h"
#include "qemu/thread.h"
@@ -166,33 +169,13 @@ typedef struct V9fsXattr
int flags;
} V9fsXattr;
-typedef struct V9fsDir {
- DIR *stream;
- QemuMutex readdir_mutex;
-} V9fsDir;
-
-static inline void v9fs_readdir_lock(V9fsDir *dir)
-{
- qemu_mutex_lock(&dir->readdir_mutex);
-}
-
-static inline void v9fs_readdir_unlock(V9fsDir *dir)
-{
- qemu_mutex_unlock(&dir->readdir_mutex);
-}
-
-static inline void v9fs_readdir_init(V9fsDir *dir)
-{
- qemu_mutex_init(&dir->readdir_mutex);
-}
-
/*
* Filled by fs driver on open and other
* calls.
*/
union V9fsFidOpenState {
int fd;
- V9fsDir dir;
+ DIR *dir;
V9fsXattr xattr;
/*
* private pointer for fs drivers, that
@@ -236,7 +219,6 @@ typedef struct V9fsState
int32_t root_fid;
Error *migration_blocker;
V9fsConf fsconf;
- V9fsQID root_qid;
} V9fsState;
/* 9p2000.L open flags */
diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index d91f9ad6e..91df7f7a7 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -1,5 +1,6 @@
+
/*
- * 9p backend
+ * Virtio 9p backend
*
* Copyright IBM, Corp. 2011
*
@@ -17,7 +18,8 @@
#include "qemu/coroutine.h"
#include "coth.h"
-int v9fs_co_readdir(V9fsPDU *pdu, 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;
@@ -27,14 +29,11 @@ int v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent **dent)
}
v9fs_co_run_in_worker(
{
- struct dirent *entry;
-
errno = 0;
- entry = s->ops->readdir(&s->ctx, &fidp->fs);
- if (!entry && errno) {
+ err = s->ops->readdir_r(&s->ctx, &fidp->fs, dent, result);
+ if (!*result && errno) {
err = -errno;
} else {
- *dent = entry;
err = 0;
}
});
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 10343c0a9..293483e0c 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -1,5 +1,6 @@
+
/*
- * 9p backend
+ * Virtio 9p backend
*
* Copyright IBM, Corp. 2011
*
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 70f584fcb..18c81cb3d 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -1,5 +1,6 @@
+
/*
- * 9p backend
+ * Virtio 9p backend
*
* Copyright IBM, Corp. 2011
*
diff --git a/hw/9pfs/coth.c b/hw/9pfs/coth.c
index 89018de6b..464293ef2 100644
--- a/hw/9pfs/coth.c
+++ b/hw/9pfs/coth.c
@@ -16,20 +16,21 @@
#include "qemu-common.h"
#include "block/thread-pool.h"
#include "qemu/coroutine.h"
+#include "qemu/main-loop.h"
#include "coth.h"
/* Called from QEMU I/O thread. */
static void coroutine_enter_cb(void *opaque, int ret)
{
Coroutine *co = opaque;
- qemu_coroutine_enter(co);
+ qemu_coroutine_enter(co, NULL);
}
/* Called from worker thread. */
static int coroutine_enter_func(void *arg)
{
Coroutine *co = arg;
- qemu_coroutine_enter(co);
+ qemu_coroutine_enter(co, NULL);
return 0;
}
diff --git a/hw/9pfs/coth.h b/hw/9pfs/coth.h
index 3c7424e42..209fc6a9a 100644
--- a/hw/9pfs/coth.h
+++ b/hw/9pfs/coth.h
@@ -12,13 +12,12 @@
*
*/
-#ifndef QEMU_9P_COTH_H
-#define QEMU_9P_COTH_H
+#ifndef _QEMU_9P_COTH_H
+#define _QEMU_9P_COTH_H
#include "qemu/thread.h"
#include "qemu/coroutine.h"
-#include "qemu/main-loop.h"
-#include "9p.h"
+#include "virtio-9p.h"
/*
* we want to use bottom half because we want to make sure the below
@@ -48,8 +47,10 @@
} while (0)
extern void co_run_in_worker_bh(void *);
+extern int v9fs_init_worker_threads(void);
extern int v9fs_co_readlink(V9fsPDU *, V9fsPath *, V9fsString *);
-extern int v9fs_co_readdir(V9fsPDU *, V9fsFidState *, struct dirent **);
+extern int v9fs_co_readdir_r(V9fsPDU *, V9fsFidState *,
+ struct dirent *, struct dirent **result);
extern off_t v9fs_co_telldir(V9fsPDU *, V9fsFidState *);
extern void v9fs_co_seekdir(V9fsPDU *, V9fsFidState *, off_t);
extern void v9fs_co_rewinddir(V9fsPDU *, V9fsFidState *);
diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c
index 133c4ead3..6ad96ea9f 100644
--- a/hw/9pfs/coxattr.c
+++ b/hw/9pfs/coxattr.c
@@ -1,5 +1,6 @@
+
/*
- * 9p backend
+ * Virtio 9p backend
*
* Copyright IBM, Corp. 2011
*
diff --git a/hw/9pfs/trace-events b/hw/9pfs/trace-events
deleted file mode 100644
index 48d3d8abe..000000000
--- a/hw/9pfs/trace-events
+++ /dev/null
@@ -1,47 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/9pfs/virtio-9p.c
-v9fs_rerror(uint16_t tag, uint8_t id, int err) "tag %d id %d err %d"
-v9fs_version(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id %d msize %d version %s"
-v9fs_version_return(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id %d msize %d version %s"
-v9fs_attach(uint16_t tag, uint8_t id, int32_t fid, int32_t afid, char* uname, char* aname) "tag %u id %u fid %d afid %d uname %s aname %s"
-v9fs_attach_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d type %d version %d path %"PRId64
-v9fs_stat(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
-v9fs_stat_return(uint16_t tag, uint8_t id, int32_t mode, int32_t atime, int32_t mtime, int64_t length) "tag %d id %d stat={mode %d atime %d mtime %d length %"PRId64"}"
-v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask) "tag %d id %d fid %d request_mask %"PRIu64
-v9fs_getattr_return(uint16_t tag, uint8_t id, uint64_t result_mask, uint32_t mode, uint32_t uid, uint32_t gid) "tag %d id %d getattr={result_mask %"PRId64" mode %u uid %u gid %u}"
-v9fs_walk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, uint16_t nwnames) "tag %d id %d fid %d newfid %d nwnames %d"
-v9fs_walk_return(uint16_t tag, uint8_t id, uint16_t nwnames, void* qids) "tag %d id %d nwnames %d qids %p"
-v9fs_open(uint16_t tag, uint8_t id, int32_t fid, int32_t mode) "tag %d id %d fid %d mode %d"
-v9fs_open_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
-v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode, uint32_t gid) "tag %d id %d dfid %d flags %d mode %d gid %u"
-v9fs_lcreate_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int32_t iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
-v9fs_fsync(uint16_t tag, uint8_t id, int32_t fid, int datasync) "tag %d id %d fid %d datasync %d"
-v9fs_clunk(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
-v9fs_read(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t max_count) "tag %d id %d fid %d off %"PRIu64" max_count %u"
-v9fs_read_return(uint16_t tag, uint8_t id, int32_t count, ssize_t err) "tag %d id %d count %d err %zd"
-v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, uint64_t offset, uint32_t max_count) "tag %d id %d fid %d offset %"PRIu64" max_count %u"
-v9fs_readdir_return(uint16_t tag, uint8_t id, uint32_t count, ssize_t retval) "tag %d id %d count %u retval %zd"
-v9fs_write(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t count, int cnt) "tag %d id %d fid %d off %"PRIu64" count %u cnt %d"
-v9fs_write_return(uint16_t tag, uint8_t id, int32_t total, ssize_t err) "tag %d id %d total %d err %zd"
-v9fs_create(uint16_t tag, uint8_t id, int32_t fid, char* name, int32_t perm, int8_t mode) "tag %d id %d fid %d name %s perm %d mode %d"
-v9fs_create_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
-v9fs_symlink(uint16_t tag, uint8_t id, int32_t fid, char* name, char* symname, uint32_t gid) "tag %d id %d fid %d name %s symname %s gid %u"
-v9fs_symlink_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d qid={type %d version %d path %"PRId64"}"
-v9fs_flush(uint16_t tag, uint8_t id, int16_t flush_tag) "tag %d id %d flush_tag %d"
-v9fs_link(uint16_t tag, uint8_t id, int32_t dfid, int32_t oldfid, char* name) "tag %d id %d dfid %d oldfid %d name %s"
-v9fs_remove(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
-v9fs_wstat(uint16_t tag, uint8_t id, int32_t fid, int32_t mode, int32_t atime, int32_t mtime) "tag %u id %u fid %d stat={mode %d atime %d mtime %d}"
-v9fs_mknod(uint16_t tag, uint8_t id, int32_t fid, int mode, int major, int minor) "tag %d id %d fid %d mode %d major %d minor %d"
-v9fs_mknod_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d qid={type %d version %d path %"PRId64"}"
-v9fs_lock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length) "tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64
-v9fs_lock_return(uint16_t tag, uint8_t id, int8_t status) "tag %d id %d status %d"
-v9fs_getlock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length)"tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64
-v9fs_getlock_return(uint16_t tag, uint8_t id, uint8_t type, uint64_t start, uint64_t length, uint32_t proc_id) "tag %d id %d type %d start %"PRIu64" length %"PRIu64" proc_id %u"
-v9fs_mkdir(uint16_t tag, uint8_t id, int32_t fid, char* name, int mode, uint32_t gid) "tag %u id %u fid %d name %s mode %d gid %u"
-v9fs_mkdir_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int err) "tag %u id %u qid={type %d version %d path %"PRId64"} err %d"
-v9fs_xattrwalk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, char* name) "tag %d id %d fid %d newfid %d name %s"
-v9fs_xattrwalk_return(uint16_t tag, uint8_t id, int64_t size) "tag %d id %d size %"PRId64
-v9fs_xattrcreate(uint16_t tag, uint8_t id, int32_t fid, char* name, int64_t size, int flags) "tag %d id %d fid %d name %s size %"PRId64" flags %d"
-v9fs_readlink(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
-v9fs_readlink_return(uint16_t tag, uint8_t id, char* target) "tag %d id %d name %s"
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 009b43f6d..a38850ee8 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -13,9 +13,11 @@
#include "qemu/osdep.h"
#include "hw/virtio/virtio.h"
+#include "hw/i386/pc.h"
#include "qemu/sockets.h"
#include "virtio-9p.h"
#include "fsdev/qemu-fsdev.h"
+#include "9p-xattr.h"
#include "coth.h"
#include "hw/virtio/virtio-access.h"
#include "qemu/iov.h"
@@ -97,9 +99,14 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
g_free(cfg);
}
-static int virtio_9p_load(QEMUFile *f, void *opaque, size_t size)
+static void virtio_9p_save(QEMUFile *f, void *opaque)
{
- return virtio_load(VIRTIO_DEVICE(opaque), f, 1);
+ virtio_save(VIRTIO_DEVICE(opaque), f);
+}
+
+static int virtio_9p_load(QEMUFile *f, void *opaque, int version_id)
+{
+ return virtio_load(VIRTIO_DEVICE(opaque), f, version_id);
}
static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
@@ -115,6 +122,7 @@ static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
v->config_size = sizeof(struct virtio_9p_config) + strlen(s->fsconf.tag);
virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, v->config_size);
v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
+ register_savevm(dev, "virtio-9p", -1, 1, virtio_9p_save, virtio_9p_load, v);
out:
return;
@@ -127,6 +135,7 @@ static void virtio_9p_device_unrealize(DeviceState *dev, Error **errp)
V9fsState *s = &v->state;
virtio_cleanup(vdev);
+ unregister_savevm(dev, "virtio-9p", v);
v9fs_device_unrealize_common(s, errp);
}
@@ -168,8 +177,6 @@ void virtio_init_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,
/* virtio-9p device */
-VMSTATE_VIRTIO_DEVICE(9p, 1, virtio_9p_load, virtio_vmstate_save);
-
static Property virtio_9p_properties[] = {
DEFINE_PROP_STRING("mount_tag", V9fsVirtioState, state.fsconf.tag),
DEFINE_PROP_STRING("fsdev", V9fsVirtioState, state.fsconf.fsdev_id),
@@ -182,7 +189,6 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
dc->props = virtio_9p_properties;
- dc->vmsd = &vmstate_virtio_9p;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
vdc->realize = virtio_9p_device_realize;
vdc->unrealize = virtio_9p_device_unrealize;
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 7586b792d..7f6d88553 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -1,5 +1,5 @@
-#ifndef QEMU_VIRTIO_9P_H
-#define QEMU_VIRTIO_9P_H
+#ifndef _QEMU_VIRTIO_9P_H
+#define _QEMU_VIRTIO_9P_H
#include "standard-headers/linux/virtio_9p.h"
#include "hw/virtio/virtio.h"