From b28120343e545e9d5a50f3b05952f3faefbaa6ef Mon Sep 17 00:00:00 2001 From: Sooyoung Ha Date: Wed, 6 Jul 2016 15:37:19 +0900 Subject: [PATCH] virtfs: enable virtfs for qemu 2.6 Change-Id: I1b290381a46b7170dc0d356dd96df8defc97ef93 Signed-off-by: Sooyoung Ha --- configure | 10 +- fsdev/9p-iov-marshal.c | 4 + fsdev/9p-marshal.c | 3 + fsdev/file-op-9p.h | 27 ++ .../{virtio-9p-local-maru.c => 9p-local-maru.c} | 163 +++++------ hw/9pfs/{virtio-9p-maru.c => 9p-maru.c} | 304 ++++++++++++++------- hw/9pfs/9p.h | 22 ++ hw/9pfs/Makefile.objs | 17 ++ hw/9pfs/cofile.c | 15 - tizen/src/ecs/ecs_msg_injector.c | 5 +- tizen/src/emul_state.c | 2 +- tizen/src/util/device_hotplug.c | 17 +- 12 files changed, 380 insertions(+), 209 deletions(-) rename hw/9pfs/{virtio-9p-local-maru.c => 9p-local-maru.c} (93%) rename hw/9pfs/{virtio-9p-maru.c => 9p-maru.c} (94%) diff --git a/configure b/configure index e36f463..a3b12d7 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 fb40bdf..e5c44cc 100644 --- a/fsdev/9p-iov-marshal.c +++ b/fsdev/9p-iov-marshal.c @@ -12,10 +12,14 @@ */ #include "qemu/osdep.h" + #include #include #include + +#if !defined(CONFIG_MARU) || !defined(CONFIG_WIN32) #include +#endif #include "9p-iov-marshal.h" #include "qemu/bswap.h" diff --git a/fsdev/9p-marshal.c b/fsdev/9p-marshal.c index 183d366..3b67293 100644 --- a/fsdev/9p-marshal.c +++ b/fsdev/9p-marshal.c @@ -16,7 +16,10 @@ #include #include #include + +#if !defined(CONFIG_MARU) || !defined(CONFIG_WIN32) #include +#endif #include "9p-marshal.h" diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h index b8c2602..351d37e 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 #include #include #include +#else /* if defiend CONFIG_MARU */ + +#include +#include + +#ifndef CONFIG_WIN32 +#include +#endif + +#ifdef CONFIG_LINUX +#include +#endif + +#ifdef CONFIG_DARWIN +#include +#include +#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 similarity index 93% rename from hw/9pfs/virtio-9p-local-maru.c rename to hw/9pfs/9p-local-maru.c index 5d0e495..701cc12 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 #include #include @@ -38,6 +39,8 @@ #include #include "qemu/xattr.h" #endif +#include "qemu/cutils.h" +#include "qemu/error-report.h" #include #ifdef CONFIG_LINUX #include @@ -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 similarity index 94% rename from hw/9pfs/virtio-9p-maru.c rename to hw/9pfs/9p-maru.c index 85cf03e..24eaa75 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 1a19418..db3a753 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -3,7 +3,11 @@ #include #include + +#if !defined(CONFIG_MARU) || !defined(CONFIG_WIN32) #include +#endif + #include #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 da0ae0c..4fc48aa 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 9e8a457..1eec394 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 42be6a4..c80bace 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 90c7025..c591900 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 0a419f2..3f68802 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: -- 2.7.4