summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSooyoung Ha <yoosah.ha@samsung.com>2016-07-06 15:37:19 +0900
committerSooyoung Ha <yoosah.ha@samsung.com>2016-07-11 11:56:14 +0900
commitb28120343e545e9d5a50f3b05952f3faefbaa6ef (patch)
treebae948441fe6ad4ee1dbfae67db9a916be94d108
parent4875fd78bfeab06790761c3cea222d7b6820a4dd (diff)
downloadqemu-b28120343e545e9d5a50f3b05952f3faefbaa6ef.tar.gz
qemu-b28120343e545e9d5a50f3b05952f3faefbaa6ef.tar.bz2
qemu-b28120343e545e9d5a50f3b05952f3faefbaa6ef.zip
virtfs: enable virtfs for qemu 2.6
Change-Id: I1b290381a46b7170dc0d356dd96df8defc97ef93 Signed-off-by: Sooyoung Ha <yoosah.ha@samsung.com>
-rwxr-xr-xconfigure10
-rw-r--r--fsdev/9p-iov-marshal.c4
-rw-r--r--fsdev/9p-marshal.c3
-rw-r--r--fsdev/file-op-9p.h27
-rw-r--r--hw/9pfs/9p-local-maru.c (renamed from hw/9pfs/virtio-9p-local-maru.c)163
-rw-r--r--hw/9pfs/9p-maru.c (renamed from hw/9pfs/virtio-9p-maru.c)304
-rw-r--r--hw/9pfs/9p.h22
-rw-r--r--hw/9pfs/Makefile.objs17
-rw-r--r--hw/9pfs/cofile.c15
-rw-r--r--tizen/src/ecs/ecs_msg_injector.c5
-rw-r--r--tizen/src/emul_state.c2
-rw-r--r--tizen/src/util/device_hotplug.c17
12 files changed, 380 insertions, 209 deletions
diff --git a/configure b/configure
index e36f46348b..a3b12d7353 100755
--- a/configure
+++ b/configure
@@ -4919,14 +4919,12 @@ if test "$softmmu" = yes ; then
if test "$cap" = yes && test "$linux" = yes && test "$attr" = yes ; then
virtfs=yes
tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)"
- elif test "$darwin" = yes ; then
+ elif test "$maru" = yes && test "$darwin" = yes ; then
echo "Enable VirtFS on Darwin"
-# virtfs=yes
- virtfs=no
- elif test "$mingw32" = yes ; then
+ virtfs=yes
+ elif test "$maru" = yes && test "$mingw32" = yes ; then
echo "Enable VirtFS on Windows"
-# virtfs=yes
- virtfs=no
+ virtfs=yes
else
if test "$virtfs" = yes; then
error_exit "VirtFS is supported only on Linux and requires libcap-devel and libattr-devel"
diff --git a/fsdev/9p-iov-marshal.c b/fsdev/9p-iov-marshal.c
index fb40bdf0d5..e5c44cc5e6 100644
--- a/fsdev/9p-iov-marshal.c
+++ b/fsdev/9p-iov-marshal.c
@@ -12,10 +12,14 @@
*/
#include "qemu/osdep.h"
+
#include <glib.h>
#include <glib/gprintf.h>
#include <utime.h>
+
+#if !defined(CONFIG_MARU) || !defined(CONFIG_WIN32)
#include <sys/uio.h>
+#endif
#include "9p-iov-marshal.h"
#include "qemu/bswap.h"
diff --git a/fsdev/9p-marshal.c b/fsdev/9p-marshal.c
index 183d3667c6..3b672931d9 100644
--- a/fsdev/9p-marshal.c
+++ b/fsdev/9p-marshal.c
@@ -16,7 +16,10 @@
#include <glib/gprintf.h>
#include <dirent.h>
#include <utime.h>
+
+#if !defined(CONFIG_MARU) || !defined(CONFIG_WIN32)
#include <sys/uio.h>
+#endif
#include "9p-marshal.h"
diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
index b8c26024a9..351d37edfc 100644
--- a/fsdev/file-op-9p.h
+++ b/fsdev/file-op-9p.h
@@ -12,11 +12,38 @@
*/
#ifndef _FILEOP_H
#define _FILEOP_H
+
+#ifndef CONFIG_MARU
+
#include <dirent.h>
#include <utime.h>
#include <sys/uio.h>
#include <sys/vfs.h>
+#else /* if defiend CONFIG_MARU */
+
+#include <dirent.h>
+#include <utime.h>
+
+#ifndef CONFIG_WIN32
+#include <sys/uio.h>
+#endif
+
+#ifdef CONFIG_LINUX
+#include <sys/vfs.h>
+#endif
+
+#ifdef CONFIG_DARWIN
+#include <sys/param.h>
+#include <sys/mount.h>
+#endif
+
+#ifdef CONFIG_WIN32
+#include "tizen/src/resources_win32.h"
+#endif
+
+#endif /* CONFIG_MARU */
+
#define SM_LOCAL_MODE_BITS 0600
#define SM_LOCAL_DIR_MODE_BITS 0700
diff --git a/hw/9pfs/virtio-9p-local-maru.c b/hw/9pfs/9p-local-maru.c
index 5d0e495d5b..701cc121a6 100644
--- a/hw/9pfs/virtio-9p-local-maru.c
+++ b/hw/9pfs/9p-local-maru.c
@@ -27,10 +27,11 @@
*
*/
-#include "hw/virtio/virtio.h"
-#include "virtio-9p.h"
+#include "qemu/osdep.h"
+#include "9p.h"
+#include "fsdev/qemu-fsdev.h" /* local_ops */
#ifndef CONFIG_WIN32
-#include "virtio-9p-xattr.h"
+#include "9p-xattr.h"
#include <arpa/inet.h>
#include <pwd.h>
#include <grp.h>
@@ -38,6 +39,8 @@
#include <sys/un.h>
#include "qemu/xattr.h"
#endif
+#include "qemu/cutils.h"
+#include "qemu/error-report.h"
#include <libgen.h>
#ifdef CONFIG_LINUX
#include <linux/fs.h>
@@ -84,27 +87,26 @@ uint64_t hostBytesPerSector = -1;
static char *local_mapped_attr_path(FsContext *ctx, const char *path)
{
- char *dir_name;
- char *tmp_path = g_strdup(path);
- char *base_name = basename(tmp_path);
- char *buffer;
-
- /* NULL terminate the directory */
- dir_name = tmp_path;
- *(base_name - 1) = '\0';
-
+ int dirlen;
+ const char *name = strrchr(path, '/');
+ if (name) {
+ dirlen = name - path;
+ ++name;
+ } else {
+ name = path;
+ dirlen = 0;
+ }
#ifndef CONFIG_WIN32
- buffer = g_strdup_printf("%s/%s/%s/%s",
- ctx->fs_root, dir_name, VIRTFS_META_DIR, base_name);
+ return g_strdup_printf("%s/%.*s/%s/%s", ctx->fs_root,
+ dirlen, path, VIRTFS_META_DIR, name);
#else
- buffer = g_strdup_printf("%s\\%s\\%s\\%s",
- ctx->fs_root, dir_name, VIRTFS_META_DIR, base_name);
+ char *buffer = g_strdup_printf("%s\\%.*s\\%s\\%s", ctx->fs_root,
+ dirlen, path, VIRTFS_META_DIR, name);
while(buffer[strlen(buffer)-1] == '\\'){
buffer[strlen(buffer)-1] = '\0';
}
-#endif
- g_free(tmp_path);
return buffer;
+#endif
}
static FILE *local_fopen(const char *path, const char *mode)
@@ -198,17 +200,17 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
dev_t tmp_dev;
#ifdef CONFIG_LINUX
if (getxattr(buffer, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) {
- stbuf->st_uid = tmp_uid;
+ stbuf->st_uid = le32_to_cpu(tmp_uid);
}
if (getxattr(buffer, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) {
- stbuf->st_gid = tmp_gid;
+ stbuf->st_gid = le32_to_cpu(tmp_gid);
}
if (getxattr(buffer, "user.virtfs.mode",
&tmp_mode, sizeof(mode_t)) > 0) {
- stbuf->st_mode = tmp_mode;
+ stbuf->st_mode = le32_to_cpu(tmp_mode);
}
if (getxattr(buffer, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) {
- stbuf->st_rdev = tmp_dev;
+ stbuf->st_rdev = le64_to_cpu(tmp_dev);
}
#else
/*
@@ -220,16 +222,16 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
* (XATTR_NOFOLLOW, XATTR_SHOWCOMPRESSION)
*/
if (getxattr(buffer, "user.virtfs.uid", &tmp_uid, sizeof(uid_t), 0, 0) > 0) {
- stbuf->st_uid = tmp_uid;
+ stbuf->st_uid = le32_to_cpu(tmp_uid);
}
if (getxattr(buffer, "user.virtfs.gid", &tmp_gid, sizeof(gid_t), 0, 0) > 0) {
- stbuf->st_gid = tmp_gid;
+ stbuf->st_gid = le32_to_cpu(tmp_gid);
}
if (getxattr(buffer, "user.virtfs.mode", &tmp_mode, sizeof(mode_t), 0, 0) > 0) {
- stbuf->st_mode = tmp_mode;
+ stbuf->st_mode = le32_to_cpu(tmp_mode);
}
if (getxattr(buffer, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t), 0, 0) > 0) {
- stbuf->st_rdev = tmp_dev;
+ stbuf->st_rdev = le64_to_cpu(tmp_dev);
}
#endif
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
@@ -375,29 +377,29 @@ static int local_set_xattr(const char *path, FsCred *credp)
#ifdef CONFIG_LINUX
if (credp->fc_uid != -1) {
- err = setxattr(path, "user.virtfs.uid", &credp->fc_uid, sizeof(uid_t),
- 0);
+ uint32_t tmp_uid = cpu_to_le32(credp->fc_uid);
+ err = setxattr(path, "user.virtfs.uid", &tmp_uid, sizeof(uid_t), 0);
if (err) {
return err;
}
}
if (credp->fc_gid != -1) {
- err = setxattr(path, "user.virtfs.gid", &credp->fc_gid, sizeof(gid_t),
- 0);
+ uint32_t tmp_gid = cpu_to_le32(credp->fc_gid);
+ err = setxattr(path, "user.virtfs.gid", &tmp_gid, sizeof(gid_t), 0);
if (err) {
return err;
}
}
if (credp->fc_mode != -1) {
- err = setxattr(path, "user.virtfs.mode", &credp->fc_mode,
- sizeof(mode_t), 0);
+ uint32_t tmp_mode = cpu_to_le32(credp->fc_mode);
+ err = setxattr(path, "user.virtfs.mode", &tmp_mode, sizeof(mode_t), 0);
if (err) {
return err;
}
}
if (credp->fc_rdev != -1) {
- err = setxattr(path, "user.virtfs.rdev", &credp->fc_rdev,
- sizeof(dev_t), 0);
+ uint64_t tmp_rdev = cpu_to_le64(credp->fc_rdev);
+ err = setxattr(path, "user.virtfs.rdev", &tmp_rdev, sizeof(dev_t), 0);
if (err) {
return err;
}
@@ -497,7 +499,6 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
tsize = read(fd, (void *)buf, bufsz);
} while (tsize == -1 && errno == EINTR);
close(fd);
- return tsize;
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
(fs_ctx->export_flags & V9FS_SM_NONE)) {
buffer = rpath(fs_ctx, path);
@@ -555,7 +556,7 @@ static int local_opendir(FsContext *ctx,
static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
{
LOG_TRACE("[%d][ Enter >> %s]\n", __LINE__, __func__);
- return rewinddir(fs->dir);
+ rewinddir(fs->dir);
}
static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
@@ -574,12 +575,15 @@ static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
again:
#ifndef CONFIG_WIN32
ret = readdir_r(fs->dir, entry, result);
- if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+ if (ctx->export_flags & V9FS_SM_MAPPED) {
+ entry->d_type = DT_UNKNOWN;
+ } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
if (!ret && *result != NULL &&
!strcmp(entry->d_name, VIRTFS_META_DIR)) {
/* skp the meta data directory */
goto again;
}
+ entry->d_type = DT_UNKNOWN;
}
#else
ret = errno;
@@ -588,7 +592,7 @@ again:
entry = *result;
if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
if (!ret && *result != NULL &&
- !strcmp(entry->d_name, VIRTFS_META_DIR)) {
+ !strcmp(entry->d_name, VIRTFS_META_DIR)) {
/* skp the meta data directory */
goto again;
}
@@ -600,7 +604,7 @@ again:
static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
{
LOG_TRACE("[%d][ Enter >> %s]\n", __LINE__, __func__);
- return seekdir(fs->dir, off);
+ seekdir(fs->dir, off);
}
static ssize_t local_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@@ -684,7 +688,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
int err = -1;
int serrno = 0;
V9fsString fullname;
- char *buffer;
+ char *buffer = NULL;
v9fs_string_init(&fullname);
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
@@ -695,7 +699,6 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
buffer = rpath(fs_ctx, path);
err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0);
if (err == -1) {
- g_free(buffer);
goto out;
}
err = local_set_xattr(buffer, credp);
@@ -708,7 +711,6 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
buffer = rpath(fs_ctx, path);
err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0);
if (err == -1) {
- g_free(buffer);
goto out;
}
err = local_set_mapped_file_attr(fs_ctx, path, credp);
@@ -721,7 +723,6 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
buffer = rpath(fs_ctx, path);
err = mknod(buffer, credp->fc_mode, credp->fc_rdev);
if (err == -1) {
- g_free(buffer);
goto out;
}
err = local_post_create_passthrough(fs_ctx, path, credp);
@@ -735,8 +736,8 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
err_end:
remove(buffer);
errno = serrno;
- g_free(buffer);
out:
+ g_free(buffer);
v9fs_string_free(&fullname);
return err;
#else
@@ -754,7 +755,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
int serrno = 0;
#endif
V9fsString fullname;
- char *buffer;
+ char *buffer = NULL;
v9fs_string_init(&fullname);
#ifndef CONFIG_WIN32
@@ -773,7 +774,6 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
buffer = rpath(fs_ctx, path);
err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS);
if (err == -1) {
- g_free(buffer);
goto out;
}
credp->fc_mode = credp->fc_mode|S_IFDIR;
@@ -782,12 +782,10 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
serrno = errno;
goto err_end;
}
- g_free(buffer);
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
buffer = rpath(fs_ctx, path);
err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS);
if (err == -1) {
- g_free(buffer);
goto out;
}
credp->fc_mode = credp->fc_mode|S_IFDIR;
@@ -796,13 +794,11 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
serrno = errno;
goto err_end;
}
- g_free(buffer);
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
(fs_ctx->export_flags & V9FS_SM_NONE)) {
buffer = rpath(fs_ctx, path);
err = mkdir(buffer, credp->fc_mode);
if (err == -1) {
- g_free(buffer);
goto out;
}
err = local_post_create_passthrough(fs_ctx, path, credp);
@@ -810,12 +806,10 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
serrno = errno;
goto err_end;
}
- g_free(buffer);
}
#else
buffer = rpath(fs_ctx, path);
err = mkdir(buffer);
- g_free(buffer);
#endif
goto out;
@@ -823,9 +817,9 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
err_end:
remove(buffer);
errno = serrno;
- g_free(buffer);
#endif
out:
+ g_free(buffer);
v9fs_string_free(&fullname);
return err;
}
@@ -859,38 +853,34 @@ static int local_fstat(FsContext *fs_ctx, int fid_type,
dev_t tmp_dev;
#ifdef CONFIG_LINUX
- if (fgetxattr(fd, "user.virtfs.uid",
- &tmp_uid, sizeof(uid_t)) > 0) {
- stbuf->st_uid = tmp_uid;
+ if (fgetxattr(fd, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) {
+ stbuf->st_uid = le32_to_cpu(tmp_uid);
}
- if (fgetxattr(fd, "user.virtfs.gid",
- &tmp_gid, sizeof(gid_t)) > 0) {
- stbuf->st_gid = tmp_gid;
+ if (fgetxattr(fd, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) {
+ stbuf->st_gid = le32_to_cpu(tmp_gid);
}
- if (fgetxattr(fd, "user.virtfs.mode",
- &tmp_mode, sizeof(mode_t)) > 0) {
- stbuf->st_mode = tmp_mode;
+ if (fgetxattr(fd, "user.virtfs.mode", &tmp_mode, sizeof(mode_t)) > 0) {
+ stbuf->st_mode = le32_to_cpu(tmp_mode);
}
- if (fgetxattr(fd, "user.virtfs.rdev",
- &tmp_dev, sizeof(dev_t)) > 0) {
- stbuf->st_rdev = tmp_dev;
+ if (fgetxattr(fd, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) {
+ stbuf->st_rdev = le64_to_cpu(tmp_dev);
}
#else
if (fgetxattr(fd, "user.virtfs.uid",
&tmp_uid, sizeof(uid_t), 0, 0) > 0) {
- stbuf->st_uid = tmp_uid;
+ stbuf->st_uid = le32_to_cpu(tmp_uid);
}
if (fgetxattr(fd, "user.virtfs.gid",
&tmp_gid, sizeof(gid_t), 0, 0) > 0) {
- stbuf->st_gid = tmp_gid;
+ stbuf->st_gid = le32_to_cpu(tmp_gid);
}
if (fgetxattr(fd, "user.virtfs.mode",
&tmp_mode, sizeof(mode_t), 0, 0) > 0) {
- stbuf->st_mode = tmp_mode;
+ stbuf->st_mode = le32_to_cpu(tmp_mode);
}
if (fgetxattr(fd, "user.virtfs.rdev",
&tmp_dev, sizeof(dev_t), 0, 0) > 0) {
- stbuf->st_rdev = tmp_dev;
+ stbuf->st_rdev = le64_to_cpu(tmp_dev);
}
#endif
#endif
@@ -910,7 +900,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
int err = -1;
int serrno = 0;
V9fsString fullname;
- char *buffer;
+ char *buffer = NULL;
/*
* Mark all the open to not follow symlinks
@@ -931,7 +921,6 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
buffer = rpath(fs_ctx, path);
fd = open(buffer, flags, SM_LOCAL_MODE_BITS);
if (fd == -1) {
- g_free(buffer);
err = fd;
goto out;
}
@@ -948,7 +937,6 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
buffer = rpath(fs_ctx, path);
fd = open(buffer, flags, SM_LOCAL_MODE_BITS);
if (fd == -1) {
- g_free(buffer);
err = fd;
goto out;
}
@@ -964,7 +952,6 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
buffer = rpath(fs_ctx, path);
fd = open(buffer, flags, credp->fc_mode);
if (fd == -1) {
- g_free(buffer);
err = fd;
goto out;
}
@@ -982,8 +969,8 @@ err_end:
close(fd);
remove(buffer);
errno = serrno;
- g_free(buffer);
out:
+ g_free(buffer);
v9fs_string_free(&fullname);
return err;
}
@@ -998,7 +985,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
int serrno = 0;
char *newpath;
V9fsString fullname;
- char *buffer;
+ char *buffer = NULL;
v9fs_string_init(&fullname);
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
@@ -1011,7 +998,6 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
buffer = rpath(fs_ctx, newpath);
fd = open(buffer, O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW, SM_LOCAL_MODE_BITS);
if (fd == -1) {
- g_free(buffer);
err = fd;
goto out;
}
@@ -1041,7 +1027,6 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
buffer = rpath(fs_ctx, newpath);
fd = open(buffer, O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW, SM_LOCAL_MODE_BITS);
if (fd == -1) {
- g_free(buffer);
err = fd;
goto out;
}
@@ -1070,7 +1055,6 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
buffer = rpath(fs_ctx, newpath);
err = symlink(oldpath, buffer);
if (err) {
- g_free(buffer);
goto out;
}
err = lchown(buffer, credp->fc_uid, credp->fc_gid);
@@ -1091,8 +1075,8 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
err_end:
remove(buffer);
errno = serrno;
- g_free(buffer);
out:
+ g_free(buffer);
v9fs_string_free(&fullname);
#endif
return err;
@@ -1694,12 +1678,12 @@ err_out:
return ret;
}
-#ifndef CONFIG_WIN32
#ifdef FS_IOC_GETVERSION
static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
mode_t st_mode, uint64_t *st_gen)
{
LOG_TRACE("[%d][ Enter >> %s]\n", __LINE__, __func__);
+#ifndef CONFIG_WIN32
int err;
V9fsFidOpenState fid_open;
@@ -1719,8 +1703,11 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
local_close(ctx, &fid_open);
return err;
-}
+#else
+ errno = ENOTTY;
+ return -1;
#endif
+}
#endif
static int local_init(FsContext *ctx)
@@ -1775,9 +1762,9 @@ static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
const char *path = qemu_opt_get(opts, "path");
if (!sec_model) {
- fprintf(stderr, "security model not specified, "
- "local fs needs security model\nvalid options are:"
- "\tsecurity_model=[passthrough|mapped|none]\n");
+ error_report("Security model not specified, local fs needs security model");
+ error_printf("valid options are:"
+ "\tsecurity_model=[passthrough|mapped-xattr|mapped-file|none]\n");
return -1;
}
@@ -1791,14 +1778,14 @@ static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
} else if (!strcmp(sec_model, "mapped-file")) {
fse->export_flags |= V9FS_SM_MAPPED_FILE;
} else {
- fprintf(stderr, "Invalid security model %s specified, valid options are"
- "\n\t [passthrough|mapped-xattr|mapped-file|none]\n",
- sec_model);
+ error_report("Invalid security model %s specified", sec_model);
+ error_printf("valid options are:"
+ "\t[passthrough|mapped-xattr|mapped-file|none]\n");
return -1;
}
if (!path) {
- fprintf(stderr, "fsdev: No path specified.\n");
+ error_report("fsdev: No path specified");
return -1;
}
fse->path = g_strdup(path);
diff --git a/hw/9pfs/virtio-9p-maru.c b/hw/9pfs/9p-maru.c
index 85cf03e500..24eaa753f3 100644
--- a/hw/9pfs/virtio-9p-maru.c
+++ b/hw/9pfs/9p-maru.c
@@ -27,14 +27,17 @@
*
*/
+#include "qemu/osdep.h"
#include "hw/virtio/virtio.h"
#include "hw/i386/pc.h"
-#include "qemu/sockets.h"
+#include "qapi/error.h"
#include "qemu/error-report.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
#include "virtio-9p.h"
#include "fsdev/qemu-fsdev.h"
-#include "virtio-9p-xattr.h"
-#include "virtio-9p-coth.h"
+#include "9p-xattr.h"
+#include "coth.h"
#include "trace.h"
#include "migration/migration.h"
@@ -76,6 +79,35 @@ enum {
Oappend = 0x80,
};
+ssize_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
+{
+ ssize_t ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = virtio_pdu_vmarshal(pdu, offset, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+ssize_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
+{
+ ssize_t ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = virtio_pdu_vunmarshal(pdu, offset, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+static void pdu_push_and_notify(V9fsPDU *pdu)
+{
+ virtio_9p_push_and_notify(pdu);
+}
+
static int omode_to_uflags(int8_t mode)
{
int ret = 0;
@@ -170,7 +202,6 @@ static int get_dotl_openflags(V9fsState *s, int oflags)
* Ignore direct disk access hint until the server supports it.
*/
flags &= ~O_DIRECT;
-
return flags;
}
@@ -350,9 +381,7 @@ static int v9fs_xattr_fid_clunk(V9fsPDU *pdu, V9fsFidState *fidp)
free_out:
v9fs_string_free(&fidp->fs.xattr.name);
free_value:
- if (fidp->fs.xattr.value) {
- g_free(fidp->fs.xattr.value);
- }
+ g_free(fidp->fs.xattr.value);
return retval;
}
#endif
@@ -564,7 +593,6 @@ static void virtfs_reset(V9fsPDU *pdu)
error_report("9pfs:%s: One or more uncluncked fids "
"found during reset", __func__);
}
- return;
}
#define P9_QID_TYPE_DIR 0x80
@@ -628,7 +656,7 @@ static int fid_to_qid(V9fsPDU *pdu, V9fsFidState *fidp, V9fsQID *qidp)
return 0;
}
-static V9fsPDU *alloc_pdu(V9fsState *s)
+V9fsPDU *pdu_alloc(V9fsState *s)
{
V9fsPDU *pdu = NULL;
@@ -640,9 +668,10 @@ static V9fsPDU *alloc_pdu(V9fsState *s)
return pdu;
}
-static void free_pdu(V9fsState *s, V9fsPDU *pdu)
+void pdu_free(V9fsPDU *pdu)
{
if (pdu) {
+ V9fsState *s = pdu->s;
/*
* Cancelled pdu are added back to the freelist
* by flush request .
@@ -659,9 +688,10 @@ static void free_pdu(V9fsState *s, V9fsPDU *pdu)
* because we always expect to have enough space to encode
* error details
*/
-static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len)
+static void pdu_complete(V9fsPDU *pdu, ssize_t len)
{
int8_t id = pdu->id + 1; /* Response */
+ V9fsState *s = pdu->s;
if (len < 0) {
WARN("[%d][ >> %s]\n", __LINE__, __func__);
@@ -693,16 +723,12 @@ static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len)
pdu->size = len;
pdu->id = id;
- /* push onto queue and notify */
- virtqueue_push(s->vq, &pdu->elem, len);
-
- /* FIXME: we should batch these completions */
- virtio_notify(VIRTIO_DEVICE(s), s->vq);
+ pdu_push_and_notify(pdu);
/* Now wakeup anybody waiting in flush for this request */
qemu_co_queue_next(&pdu->complete);
- free_pdu(s, pdu);
+ pdu_free(pdu);
}
#ifndef CONFIG_WIN32
@@ -745,6 +771,7 @@ static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension)
if (mode & P9_STAT_MODE_SETVTX) {
ret |= S_ISVTX;
}
+
return ret;
}
#endif
@@ -828,6 +855,7 @@ static uint32_t stat_to_v9mode(const struct stat *stbuf)
if (stbuf->st_mode & S_ISVTX) {
mode |= P9_STAT_MODE_SETVTX;
}
+
#endif
return mode;
}
@@ -1026,9 +1054,8 @@ static void v9fs_version(void *opaque)
offset += err;
trace_v9fs_version_return(pdu->tag, pdu->id, s->msize, version.data);
out:
- complete_pdu(s, pdu, offset);
+ pdu_complete(pdu, offset);
v9fs_string_free(&version);
- return;
}
static void v9fs_attach(void *opaque)
@@ -1096,7 +1123,7 @@ static void v9fs_attach(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&uname);
v9fs_string_free(&aname);
}
@@ -1111,7 +1138,6 @@ static void v9fs_stat(void *opaque)
struct stat stbuf;
V9fsFidState *fidp;
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
err = pdu_unmarshal(pdu, offset, "d", &fid);
if (err < 0) {
@@ -1144,7 +1170,7 @@ static void v9fs_stat(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
static void v9fs_getattr(void *opaque)
@@ -1184,10 +1210,18 @@ static void v9fs_getattr(void *opaque)
/* fill st_gen if requested and supported by underlying fs */
if (request_mask & P9_STATS_GEN) {
retval = v9fs_co_st_gen(pdu, &fidp->path, stbuf.st_mode, &v9stat_dotl);
- if (retval < 0) {
+ switch (retval) {
+ case 0:
+ /* we have valid st_gen: update result mask */
+ v9stat_dotl.st_result_mask |= P9_STATS_GEN;
+ break;
+ case -EINTR:
+ /* request cancelled, e.g. by Tflush */
goto out;
+ default:
+ /* failed to get st_gen: not fatal, ignore */
+ break;
}
- v9stat_dotl.st_result_mask |= P9_STATS_GEN;
}
retval = pdu_marshal(pdu, offset, "A", &v9stat_dotl);
if (retval < 0) {
@@ -1200,7 +1234,7 @@ static void v9fs_getattr(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, retval);
+ pdu_complete(pdu, retval);
}
/* Attribute flags */
@@ -1225,7 +1259,6 @@ static void v9fs_setattr(void *opaque)
size_t offset = 7;
V9fsIattr v9iattr;
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
err = pdu_unmarshal(pdu, offset, "dI", &fid, &v9iattr);
if (err < 0) {
@@ -1307,7 +1340,7 @@ static void v9fs_setattr(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
static int v9fs_walk_marshal(V9fsPDU *pdu, uint16_t nwnames, V9fsQID *qids)
@@ -1353,7 +1386,7 @@ static void v9fs_walk(void *opaque)
err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames);
if (err < 0) {
ERR("[%d][ >> %s]\n", __LINE__, __func__);
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
return ;
}
offset += err;
@@ -1427,7 +1460,7 @@ out:
v9fs_path_free(&dpath);
v9fs_path_free(&path);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
if (nwnames && nwnames <= P9_MAXWELEM) {
for (name_idx = 0; name_idx < nwnames; name_idx++) {
v9fs_string_free(&wnames[name_idx]);
@@ -1435,7 +1468,6 @@ out_nofid:
g_free(wnames);
g_free(qids);
}
- return;
}
static int32_t get_iounit(V9fsPDU *pdu, V9fsPath *path)
@@ -1554,7 +1586,7 @@ static void v9fs_open(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
static void v9fs_lcreate(void *opaque)
@@ -1616,7 +1648,7 @@ static void v9fs_lcreate(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(pdu->s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
}
@@ -1629,7 +1661,6 @@ static void v9fs_fsync(void *opaque)
size_t offset = 7;
V9fsFidState *fidp;
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
err = pdu_unmarshal(pdu, offset, "dd", &fid, &datasync);
if (err < 0) {
@@ -1650,7 +1681,7 @@ static void v9fs_fsync(void *opaque)
}
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
static void v9fs_clunk(void *opaque)
@@ -1683,7 +1714,7 @@ static void v9fs_clunk(void *opaque)
err = offset;
}
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
#ifndef CONFIG_WIN32
@@ -1694,6 +1725,8 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
size_t offset = 7;
int read_count;
int64_t xattr_len;
+ V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
+ VirtQueueElement *elem = v->elems[pdu->idx];
xattr_len = fidp->fs.xattr.len;
read_count = xattr_len - off;
@@ -1710,7 +1743,8 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
return err;
}
offset += err;
- err = v9fs_pack(pdu->elem.in_sg, pdu->elem.in_num, offset,
+
+ err = v9fs_pack(elem->in_sg, elem->in_num, offset,
((char *)fidp->fs.xattr.value) + off,
read_count);
if (err < 0) {
@@ -1744,6 +1778,9 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
while (1) {
v9fs_path_init(&path);
err = v9fs_co_readdir_r(pdu, fidp, dent, &result);
+#ifdef CONFIG_WIN32
+ dent = result;
+#endif
if (err || !result) {
ERR("[%d][ >> %s]\n", __LINE__, __func__);
break;
@@ -1810,13 +1847,7 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,
struct iovec *iov;
unsigned int niov;
- if (is_write) {
- iov = pdu->elem.out_sg;
- niov = pdu->elem.out_num;
- } else {
- iov = pdu->elem.in_sg;
- niov = pdu->elem.in_num;
- }
+ virtio_init_iov_from_pdu(pdu, &iov, &niov, is_write);
qemu_iovec_init_external(&elem, iov, niov);
qemu_iovec_init(qiov, niov);
@@ -1834,7 +1865,9 @@ static void v9fs_read(void *opaque)
uint32_t max_count;
V9fsFidState *fidp;
V9fsPDU *pdu = opaque;
+#ifndef CONFIG_WIN32
V9fsState *s = pdu->s;
+#endif
err = pdu_unmarshal(pdu, offset, "dqd", &fid, &off, &max_count);
if (err < 0) {
@@ -1914,7 +1947,7 @@ static void v9fs_read(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
static size_t v9fs_readdir_data_size(V9fsString *name)
@@ -1951,7 +1984,9 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
while (1) {
err = v9fs_co_readdir_r(pdu, fidp, dent, &result);
+#ifdef CONFIG_WIN32
dent = result;
+#endif
if (err) {
ERR("[%d][ >> %s]\n", __LINE__, __func__);
break;
@@ -2031,7 +2066,6 @@ static void v9fs_readdir(void *opaque)
int32_t count;
uint32_t max_count;
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
retval = pdu_unmarshal(pdu, offset, "dqd", &fid,
&initial_offset, &max_count);
@@ -2073,7 +2107,7 @@ static void v9fs_readdir(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, retval);
+ pdu_complete(pdu, retval);
}
#ifndef CONFIG_WIN32
@@ -2124,6 +2158,7 @@ out:
return err;
}
#endif
+
static void v9fs_write(void *opaque)
{
TRACE("[%d][ Enter >> %s]\n", __LINE__, __func__);
@@ -2136,14 +2171,17 @@ static void v9fs_write(void *opaque)
size_t offset = 7;
V9fsFidState *fidp;
V9fsPDU *pdu = opaque;
+#ifndef CONFIG_WIN32
V9fsState *s = pdu->s;
+#endif
QEMUIOVector qiov_full;
QEMUIOVector qiov;
err = pdu_unmarshal(pdu, offset, "dqd", &fid, &off, &count);
if (err < 0) {
ERR("[%d][ >> %s]\n", __LINE__, __func__);
- return complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
+ return;
}
offset += err;
v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset, count, true);
@@ -2212,7 +2250,7 @@ out:
put_fid(pdu, fidp);
out_nofid:
qemu_iovec_destroy(&qiov_full);
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
static void v9fs_create(void *opaque)
@@ -2402,7 +2440,7 @@ static void v9fs_create(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(pdu->s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
v9fs_string_free(&extension);
v9fs_path_free(&path);
@@ -2454,7 +2492,7 @@ static void v9fs_symlink(void *opaque)
out:
put_fid(pdu, dfidp);
out_nofid:
- complete_pdu(pdu->s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
v9fs_string_free(&symname);
}
@@ -2471,7 +2509,7 @@ static void v9fs_flush(void *opaque)
err = pdu_unmarshal(pdu, offset, "w", &tag);
if (err < 0) {
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
return;
}
trace_v9fs_flush(pdu->tag, pdu->id, tag);
@@ -2488,17 +2526,15 @@ static void v9fs_flush(void *opaque)
*/
qemu_co_queue_wait(&cancel_pdu->complete);
cancel_pdu->cancelled = 0;
- free_pdu(pdu->s, cancel_pdu);
+ pdu_free(cancel_pdu);
}
- complete_pdu(s, pdu, 7);
- return;
+ pdu_complete(pdu, 7);
}
static void v9fs_link(void *opaque)
{
TRACE("[%d][ Enter >> %s]\n", __LINE__, __func__);
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
int32_t dfid, oldfid;
V9fsFidState *dfidp, *oldfidp;
V9fsString name;
@@ -2531,7 +2567,7 @@ out:
put_fid(pdu, dfidp);
out_nofid:
v9fs_string_free(&name);
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
/* Only works with path name based fid */
@@ -2577,7 +2613,7 @@ out_err:
clunk_fid(pdu->s, fidp->fid);
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(pdu->s, pdu, err);
+ pdu_complete(pdu, err);
}
static void v9fs_unlinkat(void *opaque)
@@ -2622,7 +2658,7 @@ out_err:
put_fid(pdu, dfidp);
v9fs_path_free(&path);
out_nofid:
- complete_pdu(pdu->s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
}
@@ -2723,7 +2759,7 @@ static void v9fs_rename(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
}
@@ -2826,7 +2862,7 @@ static void v9fs_renameat(void *opaque)
}
out_err:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&old_name);
v9fs_string_free(&new_name);
}
@@ -2842,7 +2878,6 @@ static void v9fs_wstat(void *opaque)
struct stat stbuf;
V9fsFidState *fidp;
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
v9fs_stat_init(&v9stat);
err = pdu_unmarshal(pdu, offset, "dwS", &fid, &unused, &v9stat);
@@ -2932,7 +2967,7 @@ out:
put_fid(pdu, fidp);
out_nofid:
v9fs_stat_free(&v9stat);
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
static int v9fs_fill_statfs(V9fsState *s, V9fsPDU *pdu, struct statfs *stbuf)
@@ -3018,8 +3053,7 @@ static void v9fs_statfs(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, retval);
- return;
+ pdu_complete(pdu, retval);
}
static void v9fs_mknod(void *opaque)
@@ -3037,7 +3071,6 @@ static void v9fs_mknod(void *opaque)
struct stat stbuf;
V9fsFidState *fidp;
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
v9fs_string_init(&name);
err = pdu_unmarshal(pdu, offset, "dsdddd", &fid, &name, &mode,
@@ -3072,7 +3105,7 @@ static void v9fs_mknod(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
}
@@ -3094,7 +3127,6 @@ static void v9fs_lock(void *opaque)
V9fsFidState *fidp;
int32_t fid, err = 0;
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
status = P9_LOCK_ERROR;
v9fs_string_init(&flock.client_id);
@@ -3131,7 +3163,7 @@ out_nofid:
err += offset;
}
trace_v9fs_lock_return(pdu->tag, pdu->id, status);
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&flock.client_id);
}
@@ -3148,7 +3180,6 @@ static void v9fs_getlock(void *opaque)
V9fsGetlock glock;
int32_t fid, err = 0;
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
v9fs_string_init(&glock.client_id);
err = pdu_unmarshal(pdu, offset, "dbqqds", &fid, &glock.type,
@@ -3182,7 +3213,7 @@ static void v9fs_getlock(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&glock.client_id);
}
@@ -3227,7 +3258,7 @@ static void v9fs_mkdir(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(pdu->s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
}
@@ -3334,7 +3365,7 @@ out:
put_fid(pdu, xattr_fidp);
}
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
}
@@ -3349,7 +3380,6 @@ static void v9fs_xattrcreate(void *opaque)
V9fsFidState *file_fidp;
V9fsFidState *xattr_fidp;
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
v9fs_string_init(&name);
err = pdu_unmarshal(pdu, offset, "dsqd", &fid, &name, &size, &flags);
@@ -3375,7 +3405,7 @@ static void v9fs_xattrcreate(void *opaque)
err = offset;
put_fid(pdu, file_fidp);
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
}
#endif
@@ -3417,7 +3447,7 @@ static void v9fs_readlink(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(pdu->s, pdu, err);
+ pdu_complete(pdu, err);
}
static CoroutineEntry *pdu_co_handlers[] = {
@@ -3463,14 +3493,14 @@ static void v9fs_op_not_supp(void *opaque)
{
WARN("[%d][%s] >> This operation is not supported.\n", __LINE__, __func__);
V9fsPDU *pdu = opaque;
- complete_pdu(pdu->s, pdu, -EOPNOTSUPP);
+ pdu_complete(pdu, -EOPNOTSUPP);
}
static void v9fs_fs_ro(void *opaque)
{
WARN("[%d][%s] >> This is the read-only operation.\n", __LINE__, __func__);
V9fsPDU *pdu = opaque;
- complete_pdu(pdu->s, pdu, -EROFS);
+ pdu_complete(pdu, -EROFS);
}
static inline bool is_read_only_op(V9fsPDU *pdu)
@@ -3500,10 +3530,11 @@ static inline bool is_read_only_op(V9fsPDU *pdu)
}
}
-static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
+void pdu_submit(V9fsPDU *pdu)
{
Coroutine *co;
CoroutineEntry *handler;
+ V9fsState *s = pdu->s;
if (pdu->id >= ARRAY_SIZE(pdu_co_handlers) ||
(pdu_co_handlers[pdu->id] == NULL)) {
@@ -3519,36 +3550,115 @@ static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
qemu_coroutine_enter(co, pdu);
}
-void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
+/* Returns 0 on success, 1 on failure. */
+int v9fs_device_realize_common(V9fsState *s, Error **errp)
{
- V9fsState *s = (V9fsState *)vdev;
- V9fsPDU *pdu;
- ssize_t len;
+ TRACE("[%d][ Enter >> %s]\n", __LINE__, __func__);
+ V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
+ int i, len;
+ struct stat stat;
+ FsDriverEntry *fse;
+ V9fsPath path;
+ int rc = 1;
+
+ /* initialize pdu allocator */
+ QLIST_INIT(&s->free_list);
+ QLIST_INIT(&s->active_list);
+ for (i = 0; i < (MAX_REQ - 1); i++) {
+ QLIST_INSERT_HEAD(&s->free_list, &v->pdus[i], next);
+ v->pdus[i].s = s;
+ v->pdus[i].idx = i;
+ }
+
+ v9fs_path_init(&path);
+
+ fse = get_fsdev_fsentry(s->fsconf.fsdev_id);
+
+ if (!fse) {
+ /* We don't have a fsdev identified by fsdev_id */
+ error_setg(errp, "9pfs device couldn't find fsdev with the "
+ "id = %s",
+ s->fsconf.fsdev_id ? s->fsconf.fsdev_id : "NULL");
+ goto out;
+ }
+
+ if (!s->fsconf.tag) {
+ /* we haven't specified a mount_tag */
+ error_setg(errp, "fsdev with id %s needs mount_tag arguments",
+ s->fsconf.fsdev_id);
+ goto out;
+ }
+
+ s->ctx.export_flags = fse->export_flags;
+ s->ctx.fs_root = g_strdup(fse->path);
+ s->ctx.exops.get_st_gen = NULL;
+ len = strlen(s->fsconf.tag);
+ if (len > MAX_TAG_LEN - 1) {
+ error_setg(errp, "mount tag '%s' (%d bytes) is longer than "
+ "maximum (%d bytes)", s->fsconf.tag, len, MAX_TAG_LEN - 1);
+ goto out;
+ }
- while ((pdu = alloc_pdu(s)) &&
- (len = virtqueue_pop(vq, &pdu->elem)) != 0) {
- uint8_t *ptr;
- pdu->s = s;
- BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0);
- BUG_ON(pdu->elem.out_sg[0].iov_len < 7);
+ s->tag = g_strdup(s->fsconf.tag);
+ s->ctx.uid = -1;
- ptr = pdu->elem.out_sg[0].iov_base;
+ s->ops = fse->ops;
- pdu->size = le32_to_cpu(*(uint32_t *)ptr);
- pdu->id = ptr[4];
- pdu->tag = le16_to_cpu(*(uint16_t *)(ptr + 5));
- qemu_co_queue_init(&pdu->complete);
- submit_pdu(s, pdu);
+ s->fid_list = NULL;
+ qemu_co_rwlock_init(&s->rename_lock);
+
+ if (s->ops->init(&s->ctx) < 0) {
+ error_setg(errp, "9pfs Failed to initialize fs-driver with id:%s"
+ " and export path:%s", s->fsconf.fsdev_id, s->ctx.fs_root);
+ goto out;
+ }
+
+ /*
+ * Check details of export path, We need to use fs driver
+ * call back to do that. Since we are in the init path, we don't
+ * use co-routines here.
+ */
+#ifndef CONFIG_WIN32
+ if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
+#else
+ if (s->ops->name_to_path(&s->ctx, NULL, "\\", &path) < 0) {
+#endif
+ error_setg(errp,
+ "error in converting name to path %s", strerror(errno));
+ goto out;
+ }
+ if (s->ops->lstat(&s->ctx, &path, &stat)) {
+ error_setg(errp, "share path %s does not exist", fse->path);
+ goto out;
+ } else if (!S_ISDIR(stat.st_mode)) {
+ error_setg(errp, "share path %s is not a directory", fse->path);
+ goto out;
}
- free_pdu(s, pdu);
+ v9fs_path_free(&path);
+
+ rc = 0;
+out:
+ if (rc) {
+ g_free(s->ctx.fs_root);
+ g_free(s->tag);
+ v9fs_path_free(&path);
+ }
+ return rc;
+}
+
+void v9fs_device_unrealize_common(V9fsState *s, Error **errp)
+{
+ TRACE("[%d][ Enter >> %s]\n", __LINE__, __func__);
+ g_free(s->ctx.fs_root);
+ g_free(s->tag);
}
-static void __attribute__((__constructor__)) virtio_9p_set_fd_limit(void)
+static void __attribute__((__constructor__)) v9fs_set_fd_limit(void)
{
#ifndef CONFIG_WIN32
struct rlimit rlim;
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
- fprintf(stderr, "Failed to get the resource limit\n");
+ error_report("Failed to get the resource limit");
exit(1);
}
open_fd_hw = rlim.rlim_cur - MIN(400, rlim.rlim_cur/3);
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index 1a19418a8c..db3a7530b1 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -3,7 +3,11 @@
#include <dirent.h>
#include <utime.h>
+
+#if !defined(CONFIG_MARU) || !defined(CONFIG_WIN32)
#include <sys/resource.h>
+#endif
+
#include <glib.h>
#include "standard-headers/linux/virtio_9p.h"
#include "hw/virtio/virtio.h"
@@ -110,7 +114,25 @@ enum p9_proto_version {
#define FID_NON_RECLAIMABLE 0x2
static inline char *rpath(FsContext *ctx, const char *path)
{
+#if defined(CONFIG_MARU) && defined(CONFIG_WIN32)
+ char *buffer;
+ unsigned int len;
+
+ buffer = g_strdup_printf("%s\\%s", ctx->fs_root, path);
+ len = strlen(buffer);
+
+ // TODO : need to remove backslash??
+ while (len && buffer[len-1] == '\\') {
+ if (len > 1 && buffer[len-2] == ':') {
+ return buffer;
+ }
+ buffer[--len] = '\0';
+
+ }
+ return buffer;
+#else
return g_strdup_printf("%s/%s", ctx->fs_root, path);
+#endif
}
/*
diff --git a/hw/9pfs/Makefile.objs b/hw/9pfs/Makefile.objs
index da0ae0cfdb..4fc48aa111 100644
--- a/hw/9pfs/Makefile.objs
+++ b/hw/9pfs/Makefile.objs
@@ -1,3 +1,5 @@
+ifneq ($(CONFIG_MARU),y)
+
common-obj-y = 9p.o
common-obj-y += 9p-local.o 9p-xattr.o
common-obj-y += 9p-xattr-user.o 9p-posix-acl.o
@@ -6,4 +8,19 @@ common-obj-y += coxattr.o 9p-synth.o
common-obj-$(CONFIG_OPEN_BY_HANDLE) += 9p-handle.o
common-obj-y += 9p-proxy.o
+else
+
+common-obj-y = 9p-maru.o
+common-obj-y += 9p-local-maru.o
+common-obj-y += coth.o cofs.o codir.o cofile.o
+ifneq ($(CONFIG_WIN32),y)
+common-obj-y += coxattr.o 9p-xattr.o
+common-obj-y += 9p-xattr-user.o 9p-posix-acl.o
+endif
+common-obj-$(CONFIG_OPEN_BY_HANDLE) += 9p-handle.o
+common-obj-$(CONFIG_LINUX) += 9p-synth.o
+common-obj-$(CONFIG_LINUX) += 9p-proxy.o
+
+endif
+
obj-y += virtio-9p-device.o
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 9e8a457f8e..1eec3945fe 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -18,14 +18,6 @@
#include "qemu/coroutine.h"
#include "coth.h"
-#ifdef CONFIG_MARU
-#ifdef CONFIG_WIN32
-#ifdef fsync
-#undef fsync
-#endif
-#endif
-#endif
-
int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
V9fsStatDotl *v9stat)
{
@@ -283,10 +275,3 @@ int v9fs_co_preadv(V9fsPDU *pdu, V9fsFidState *fidp,
return err;
}
-#ifdef CONFIG_MARU
-#ifdef CONFIG_WIN32
-#ifndef fsync
-#define fsync _commit
-#endif
-#endif
-#endif
diff --git a/tizen/src/ecs/ecs_msg_injector.c b/tizen/src/ecs/ecs_msg_injector.c
index 42be6a4f34..c80bace52b 100644
--- a/tizen/src/ecs/ecs_msg_injector.c
+++ b/tizen/src/ecs/ecs_msg_injector.c
@@ -458,8 +458,11 @@ static bool injector_req_handle(char *cat, type_action action, const char *data)
} else if (!strcmp(cat, "hds")) {
#ifdef CONFIG_VIRTFS
msgproc_injector_do_hds(cat, action, data);
-#endif
return true;
+#else
+ LOG_WARNING("VirtFS is not enabled.\n");
+ return false;
+#endif
} else if (!strcmp(cat, MSG_TYPE_PACKAGE)) {
do_package(cat, action, data);
return true;
diff --git a/tizen/src/emul_state.c b/tizen/src/emul_state.c
index 90c70258bc..c591900bb0 100644
--- a/tizen/src/emul_state.c
+++ b/tizen/src/emul_state.c
@@ -710,7 +710,7 @@ const char* get_platform_default_home(void)
void set_platform_default_home(const char *path)
{
if (!platform_default_home) {
- platform_default_home = g_strdup(path);
+ platform_default_home = g_strdup(path);
} else {
LOG_INFO("platform home path is already set : %s\n",
platform_default_home);
diff --git a/tizen/src/util/device_hotplug.c b/tizen/src/util/device_hotplug.c
index 0a419f22ba..3f688028a7 100644
--- a/tizen/src/util/device_hotplug.c
+++ b/tizen/src/util/device_hotplug.c
@@ -88,7 +88,6 @@ static bool do_host_keyboard_detach(void)
LOG_INFO("%s\n", __func__);
QDict *qdict = qdict_new();
- LOG_INFO("%s\n", __func__);
qdict_put(qdict, "id", qstring_from_str(HOST_KEYBOARD_DEFAULT_ID));
qmp_marshal_device_del(qdict, NULL, &error_abort);
@@ -238,6 +237,18 @@ static bool do_hds_detach(const char * const id)
return true;
}
+#else
+static bool do_hds_attach(const char * const id)
+{
+ LOG_WARNING("VirtFS is not enabled.\n");
+ return false;
+}
+
+static bool do_hds_detach(const char * const id)
+{
+ LOG_WARNING("VirtFS is not enabled.\n");
+ return false;
+}
#endif
void do_hotplug(int command, void *opaque, size_t size)
@@ -271,11 +282,15 @@ static void device_hotplug_handler(EventNotifier *e)
case ATTACH_HDS:
#ifdef CONFIG_VIRTFS
do_hds_attach(state->opaque);
+#else
+ LOG_WARNING("VirtFS is not enabled.\n");
#endif
break;
case DETACH_HDS:
#ifdef CONFIG_VIRTFS
do_hds_detach(state->opaque);
+#else
+ LOG_WARNING("VirtFS is not enabled.\n");
#endif
break;
default: