virtfs: enable virtfs for qemu 2.6
authorSooyoung Ha <yoosah.ha@samsung.com>
Wed, 6 Jul 2016 06:37:19 +0000 (15:37 +0900)
committerSooyoung Ha <yoosah.ha@samsung.com>
Mon, 11 Jul 2016 02:56:14 +0000 (11:56 +0900)
Change-Id: I1b290381a46b7170dc0d356dd96df8defc97ef93
Signed-off-by: Sooyoung Ha <yoosah.ha@samsung.com>
12 files changed:
configure
fsdev/9p-iov-marshal.c
fsdev/9p-marshal.c
fsdev/file-op-9p.h
hw/9pfs/9p-local-maru.c [moved from hw/9pfs/virtio-9p-local-maru.c with 93% similarity]
hw/9pfs/9p-maru.c [moved from hw/9pfs/virtio-9p-maru.c with 94% similarity]
hw/9pfs/9p.h
hw/9pfs/Makefile.objs
hw/9pfs/cofile.c
tizen/src/ecs/ecs_msg_injector.c
tizen/src/emul_state.c
tizen/src/util/device_hotplug.c

index e36f463..a3b12d7 100755 (executable)
--- 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"
index fb40bdf..e5c44cc 100644 (file)
  */
 
 #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"
index 183d366..3b67293 100644 (file)
 #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"
 
index b8c2602..351d37e 100644 (file)
  */
 #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
 
similarity index 93%
rename from hw/9pfs/virtio-9p-local-maru.c
rename to hw/9pfs/9p-local-maru.c
index 5d0e495..701cc12 100644 (file)
  *
  */
 
-#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);
similarity index 94%
rename from hw/9pfs/virtio-9p-maru.c
rename to hw/9pfs/9p-maru.c
index 85cf03e..24eaa75 100644 (file)
  *
  */
 
+#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);
index 1a19418..db3a753 100644 (file)
@@ -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
 }
 
 /*
index da0ae0c..4fc48aa 100644 (file)
@@ -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
index 9e8a457..1eec394 100644 (file)
 #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
index 42be6a4..c80bace 100644 (file)
@@ -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;
index 90c7025..c591900 100644 (file)
@@ -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);
index 0a419f2..3f68802 100644 (file)
@@ -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: