aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--fsdev/9p-iov-marshal.c (renamed from fsdev/virtio-9p-marshal.c)175
-rw-r--r--fsdev/9p-iov-marshal.h18
-rw-r--r--fsdev/9p-marshal.c56
-rw-r--r--fsdev/9p-marshal.h (renamed from fsdev/virtio-9p-marshal.h)12
-rw-r--r--fsdev/Makefile.objs2
-rw-r--r--fsdev/virtfs-proxy-helper.c6
-rw-r--r--hw/9pfs/9p-handle.c (renamed from hw/9pfs/virtio-9p-handle.c)7
-rw-r--r--hw/9pfs/9p-local.c (renamed from hw/9pfs/virtio-9p-local.c)7
-rw-r--r--hw/9pfs/9p-posix-acl.c (renamed from hw/9pfs/virtio-9p-posix-acl.c)7
-rw-r--r--hw/9pfs/9p-proxy.c (renamed from hw/9pfs/virtio-9p-proxy.c)7
-rw-r--r--hw/9pfs/9p-proxy.h (renamed from hw/9pfs/virtio-9p-proxy.h)10
-rw-r--r--hw/9pfs/9p-synth.c (renamed from hw/9pfs/virtio-9p-synth.c)6
-rw-r--r--hw/9pfs/9p-synth.h (renamed from hw/9pfs/virtio-9p-synth.h)6
-rw-r--r--hw/9pfs/9p-xattr-user.c (renamed from hw/9pfs/virtio-9p-xattr-user.c)7
-rw-r--r--hw/9pfs/9p-xattr.c (renamed from hw/9pfs/virtio-9p-xattr.c)7
-rw-r--r--hw/9pfs/9p-xattr.h (renamed from hw/9pfs/virtio-9p-xattr.h)6
-rw-r--r--hw/9pfs/9p.c (renamed from hw/9pfs/virtio-9p.c)260
-rw-r--r--hw/9pfs/9p.h326
-rw-r--r--hw/9pfs/Makefile.objs14
-rw-r--r--hw/9pfs/codir.c2
-rw-r--r--hw/9pfs/cofile.c2
-rw-r--r--hw/9pfs/cofs.c2
-rw-r--r--hw/9pfs/coth.c (renamed from hw/9pfs/virtio-9p-coth.c)4
-rw-r--r--hw/9pfs/coth.h (renamed from hw/9pfs/virtio-9p-coth.h)6
-rw-r--r--hw/9pfs/coxattr.c2
-rw-r--r--hw/9pfs/virtio-9p-device.c201
-rw-r--r--hw/9pfs/virtio-9p.h391
-rw-r--r--hw/s390x/virtio-ccw.h2
-rw-r--r--hw/virtio/virtio-pci.h3
-rw-r--r--include/hw/virtio/virtio-9p.h24
31 files changed, 835 insertions, 745 deletions
diff --git a/Makefile b/Makefile
index 82b2fc8b96..d0de2d46b6 100644
--- a/Makefile
+++ b/Makefile
@@ -240,7 +240,7 @@ qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(qom-obj-y) libqemuu
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
-fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o libqemuutil.a libqemustub.a
+fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/9p-marshal.o fsdev/9p-iov-marshal.o libqemuutil.a libqemustub.a
fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
diff --git a/fsdev/virtio-9p-marshal.c b/fsdev/9p-iov-marshal.c
index 7748d32075..08d783ca11 100644
--- a/fsdev/virtio-9p-marshal.c
+++ b/fsdev/9p-iov-marshal.c
@@ -1,5 +1,5 @@
/*
- * Virtio 9p backend
+ * 9p backend
*
* Copyright IBM, Corp. 2010
*
@@ -22,40 +22,9 @@
#include <errno.h>
#include "qemu/compiler.h"
-#include "virtio-9p-marshal.h"
+#include "9p-iov-marshal.h"
#include "qemu/bswap.h"
-void v9fs_string_free(V9fsString *str)
-{
- g_free(str->data);
- str->data = NULL;
- str->size = 0;
-}
-
-void v9fs_string_null(V9fsString *str)
-{
- v9fs_string_free(str);
-}
-
-void GCC_FMT_ATTR(2, 3)
-v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
-{
- va_list ap;
-
- v9fs_string_free(str);
-
- va_start(ap, fmt);
- str->size = g_vasprintf(&str->data, fmt, ap);
- va_end(ap);
-}
-
-void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs)
-{
- v9fs_string_free(lhs);
- v9fs_string_sprintf(lhs, "%s", rhs->data);
-}
-
-
static ssize_t v9fs_packunpack(void *addr, struct iovec *sg, int sg_count,
size_t offset, size_t size, int pack)
{
@@ -107,15 +76,13 @@ ssize_t v9fs_pack(struct iovec *in_sg, int in_num, size_t offset,
return v9fs_packunpack((void *)src, in_sg, in_num, offset, size, 1);
}
-ssize_t v9fs_unmarshal(struct iovec *out_sg, int out_num, size_t offset,
- int bswap, const char *fmt, ...)
+ssize_t v9fs_iov_vunmarshal(struct iovec *out_sg, int out_num, size_t offset,
+ int bswap, const char *fmt, va_list ap)
{
int i;
- va_list ap;
ssize_t copied = 0;
size_t old_offset = offset;
- va_start(ap, fmt);
for (i = 0; fmt[i]; i++) {
switch (fmt[i]) {
case 'b': {
@@ -158,8 +125,8 @@ ssize_t v9fs_unmarshal(struct iovec *out_sg, int out_num, size_t offset,
}
case 's': {
V9fsString *str = va_arg(ap, V9fsString *);
- copied = v9fs_unmarshal(out_sg, out_num, offset, bswap,
- "w", &str->size);
+ copied = v9fs_iov_unmarshal(out_sg, out_num, offset, bswap,
+ "w", &str->size);
if (copied > 0) {
offset += copied;
str->data = g_malloc(str->size + 1);
@@ -175,56 +142,70 @@ ssize_t v9fs_unmarshal(struct iovec *out_sg, int out_num, size_t offset,
}
case 'Q': {
V9fsQID *qidp = va_arg(ap, V9fsQID *);
- copied = v9fs_unmarshal(out_sg, out_num, offset, bswap, "bdq",
- &qidp->type, &qidp->version, &qidp->path);
+ copied = v9fs_iov_unmarshal(out_sg, out_num, offset, bswap,
+ "bdq", &qidp->type, &qidp->version,
+ &qidp->path);
break;
}
case 'S': {
V9fsStat *statp = va_arg(ap, V9fsStat *);
- copied = v9fs_unmarshal(out_sg, out_num, offset, bswap,
- "wwdQdddqsssssddd",
- &statp->size, &statp->type, &statp->dev,
- &statp->qid, &statp->mode, &statp->atime,
- &statp->mtime, &statp->length,
- &statp->name, &statp->uid, &statp->gid,
- &statp->muid, &statp->extension,
- &statp->n_uid, &statp->n_gid,
- &statp->n_muid);
+ copied = v9fs_iov_unmarshal(out_sg, out_num, offset, bswap,
+ "wwdQdddqsssssddd",
+ &statp->size, &statp->type,
+ &statp->dev, &statp->qid,
+ &statp->mode, &statp->atime,
+ &statp->mtime, &statp->length,
+ &statp->name, &statp->uid,
+ &statp->gid, &statp->muid,
+ &statp->extension,
+ &statp->n_uid, &statp->n_gid,
+ &statp->n_muid);
break;
}
case 'I': {
V9fsIattr *iattr = va_arg(ap, V9fsIattr *);
- copied = v9fs_unmarshal(out_sg, out_num, offset, bswap,
- "ddddqqqqq",
- &iattr->valid, &iattr->mode,
- &iattr->uid, &iattr->gid, &iattr->size,
- &iattr->atime_sec, &iattr->atime_nsec,
- &iattr->mtime_sec, &iattr->mtime_nsec);
+ copied = v9fs_iov_unmarshal(out_sg, out_num, offset, bswap,
+ "ddddqqqqq",
+ &iattr->valid, &iattr->mode,
+ &iattr->uid, &iattr->gid,
+ &iattr->size, &iattr->atime_sec,
+ &iattr->atime_nsec,
+ &iattr->mtime_sec,
+ &iattr->mtime_nsec);
break;
}
default:
break;
}
if (copied < 0) {
- va_end(ap);
return copied;
}
offset += copied;
}
- va_end(ap);
return offset - old_offset;
}
-ssize_t v9fs_marshal(struct iovec *in_sg, int in_num, size_t offset,
- int bswap, const char *fmt, ...)
+ssize_t v9fs_iov_unmarshal(struct iovec *out_sg, int out_num, size_t offset,
+ int bswap, const char *fmt, ...)
{
- int i;
+ ssize_t ret;
va_list ap;
+
+ va_start(ap, fmt);
+ ret = v9fs_iov_vunmarshal(out_sg, out_num, offset, bswap, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+ssize_t v9fs_iov_vmarshal(struct iovec *in_sg, int in_num, size_t offset,
+ int bswap, const char *fmt, va_list ap)
+{
+ int i;
ssize_t copied = 0;
size_t old_offset = offset;
- va_start(ap, fmt);
for (i = 0; fmt[i]; i++) {
switch (fmt[i]) {
case 'b': {
@@ -264,8 +245,8 @@ ssize_t v9fs_marshal(struct iovec *in_sg, int in_num, size_t offset,
}
case 's': {
V9fsString *str = va_arg(ap, V9fsString *);
- copied = v9fs_marshal(in_sg, in_num, offset, bswap,
- "w", str->size);
+ copied = v9fs_iov_marshal(in_sg, in_num, offset, bswap,
+ "w", str->size);
if (copied > 0) {
offset += copied;
copied = v9fs_pack(in_sg, in_num, offset, str->data, str->size);
@@ -274,49 +255,65 @@ ssize_t v9fs_marshal(struct iovec *in_sg, int in_num, size_t offset,
}
case 'Q': {
V9fsQID *qidp = va_arg(ap, V9fsQID *);
- copied = v9fs_marshal(in_sg, in_num, offset, bswap, "bdq",
- qidp->type, qidp->version, qidp->path);
+ copied = v9fs_iov_marshal(in_sg, in_num, offset, bswap, "bdq",
+ qidp->type, qidp->version,
+ qidp->path);
break;
}
case 'S': {
V9fsStat *statp = va_arg(ap, V9fsStat *);
- copied = v9fs_marshal(in_sg, in_num, offset, bswap,
- "wwdQdddqsssssddd",
- statp->size, statp->type, statp->dev,
- &statp->qid, statp->mode, statp->atime,
- statp->mtime, statp->length, &statp->name,
- &statp->uid, &statp->gid, &statp->muid,
- &statp->extension, statp->n_uid,
- statp->n_gid, statp->n_muid);
+ copied = v9fs_iov_marshal(in_sg, in_num, offset, bswap,
+ "wwdQdddqsssssddd",
+ statp->size, statp->type, statp->dev,
+ &statp->qid, statp->mode, statp->atime,
+ statp->mtime, statp->length,
+ &statp->name,
+ &statp->uid, &statp->gid, &statp->muid,
+ &statp->extension, statp->n_uid,
+ statp->n_gid, statp->n_muid);
break;
}
case 'A': {
V9fsStatDotl *statp = va_arg(ap, V9fsStatDotl *);
- copied = v9fs_marshal(in_sg, in_num, offset, bswap,
- "qQdddqqqqqqqqqqqqqqq",
- statp->st_result_mask,
- &statp->qid, statp->st_mode,
- statp->st_uid, statp->st_gid,
- statp->st_nlink, statp->st_rdev,
- statp->st_size, statp->st_blksize,
- statp->st_blocks, statp->st_atime_sec,
- statp->st_atime_nsec, statp->st_mtime_sec,
- statp->st_mtime_nsec, statp->st_ctime_sec,
- statp->st_ctime_nsec, statp->st_btime_sec,
- statp->st_btime_nsec, statp->st_gen,
- statp->st_data_version);
+ copied = v9fs_iov_marshal(in_sg, in_num, offset, bswap,
+ "qQdddqqqqqqqqqqqqqqq",
+ statp->st_result_mask,
+ &statp->qid, statp->st_mode,
+ statp->st_uid, statp->st_gid,
+ statp->st_nlink, statp->st_rdev,
+ statp->st_size, statp->st_blksize,
+ statp->st_blocks, statp->st_atime_sec,
+ statp->st_atime_nsec,
+ statp->st_mtime_sec,
+ statp->st_mtime_nsec,
+ statp->st_ctime_sec,
+ statp->st_ctime_nsec,
+ statp->st_btime_sec,
+ statp->st_btime_nsec, statp->st_gen,
+ statp->st_data_version);
break;
}
default:
break;
}
if (copied < 0) {
- va_end(ap);
return copied;
}
offset += copied;
}
- va_end(ap);
return offset - old_offset;
}
+
+ssize_t v9fs_iov_marshal(struct iovec *in_sg, int in_num, size_t offset,
+ int bswap, const char *fmt, ...)
+{
+ ssize_t ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = v9fs_iov_vmarshal(in_sg, in_num, offset, bswap, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
diff --git a/fsdev/9p-iov-marshal.h b/fsdev/9p-iov-marshal.h
new file mode 100644
index 0000000000..6bccbfb41a
--- /dev/null
+++ b/fsdev/9p-iov-marshal.h
@@ -0,0 +1,18 @@
+#ifndef _QEMU_9P_IOV_MARSHAL_H
+#define _QEMU_9P_IOV_MARSHAL_H
+
+#include "9p-marshal.h"
+
+
+ssize_t v9fs_pack(struct iovec *in_sg, int in_num, size_t offset,
+ const void *src, size_t size);
+ssize_t v9fs_iov_unmarshal(struct iovec *out_sg, int out_num, size_t offset,
+ int bswap, const char *fmt, ...);
+ssize_t v9fs_iov_marshal(struct iovec *in_sg, int in_num, size_t offset,
+ int bswap, const char *fmt, ...);
+
+ssize_t v9fs_iov_vunmarshal(struct iovec *out_sg, int out_num, size_t offset,
+ int bswap, const char *fmt, va_list ap);
+ssize_t v9fs_iov_vmarshal(struct iovec *in_sg, int in_num, size_t offset,
+ int bswap, const char *fmt, va_list ap);
+#endif
diff --git a/fsdev/9p-marshal.c b/fsdev/9p-marshal.c
new file mode 100644
index 0000000000..991e35d242
--- /dev/null
+++ b/fsdev/9p-marshal.c
@@ -0,0 +1,56 @@
+/*
+ * 9p backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/time.h>
+#include <utime.h>
+#include <sys/uio.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include "qemu/compiler.h"
+#include "9p-marshal.h"
+
+void v9fs_string_free(V9fsString *str)
+{
+ g_free(str->data);
+ str->data = NULL;
+ str->size = 0;
+}
+
+void v9fs_string_null(V9fsString *str)
+{
+ v9fs_string_free(str);
+}
+
+void GCC_FMT_ATTR(2, 3)
+v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
+{
+ va_list ap;
+
+ v9fs_string_free(str);
+
+ va_start(ap, fmt);
+ str->size = g_vasprintf(&str->data, fmt, ap);
+ va_end(ap);
+}
+
+void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs)
+{
+ v9fs_string_free(lhs);
+ v9fs_string_sprintf(lhs, "%s", rhs->data);
+}
diff --git a/fsdev/virtio-9p-marshal.h b/fsdev/9p-marshal.h
index 5df65a8357..e91b24e9ca 100644
--- a/fsdev/virtio-9p-marshal.h
+++ b/fsdev/9p-marshal.h
@@ -1,5 +1,5 @@
-#ifndef _QEMU_VIRTIO_9P_MARSHAL_H
-#define _QEMU_VIRTIO_9P_MARSHAL_H
+#ifndef _QEMU_9P_MARSHAL_H
+#define _QEMU_9P_MARSHAL_H
typedef struct V9fsString
{
@@ -30,7 +30,7 @@ typedef struct V9fsStat
V9fsString muid;
/* 9p2000.u */
V9fsString extension;
- int32_t n_uid;
+ int32_t n_uid;
int32_t n_gid;
int32_t n_muid;
} V9fsStat;
@@ -81,10 +81,4 @@ extern void v9fs_string_null(V9fsString *str);
extern void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...);
extern void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs);
-ssize_t v9fs_pack(struct iovec *in_sg, int in_num, size_t offset,
- const void *src, size_t size);
-ssize_t v9fs_unmarshal(struct iovec *out_sg, int out_num, size_t offset,
- int bswap, const char *fmt, ...);
-ssize_t v9fs_marshal(struct iovec *in_sg, int in_num, size_t offset,
- int bswap, const char *fmt, ...);
#endif
diff --git a/fsdev/Makefile.objs b/fsdev/Makefile.objs
index c27dad3f6d..1b120a4a7d 100644
--- a/fsdev/Makefile.objs
+++ b/fsdev/Makefile.objs
@@ -1,7 +1,7 @@
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
# Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add.
# only pull in the actual virtio-9p device if we also enabled virtio.
-common-obj-y = qemu-fsdev.o virtio-9p-marshal.o
+common-obj-y = qemu-fsdev.o 9p-marshal.o 9p-iov-marshal.o
else
common-obj-y = qemu-fsdev-dummy.o
endif
diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index ad1da0d6f5..44c7d88f1b 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -23,9 +23,9 @@
#include "qemu-common.h"
#include "qemu/sockets.h"
#include "qemu/xattr.h"
-#include "virtio-9p-marshal.h"
-#include "hw/9pfs/virtio-9p-proxy.h"
-#include "fsdev/virtio-9p-marshal.h"
+#include "9p-iov-marshal.h"
+#include "hw/9pfs/9p-proxy.h"
+#include "fsdev/9p-iov-marshal.h"
#define PROGNAME "virtfs-proxy-helper"
diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/9p-handle.c
index 13eabb98a4..58b77b4c94 100644
--- a/hw/9pfs/virtio-9p-handle.c
+++ b/hw/9pfs/9p-handle.c
@@ -1,5 +1,5 @@
/*
- * Virtio 9p handle callback
+ * 9p handle callback
*
* Copyright IBM, Corp. 2011
*
@@ -11,9 +11,8 @@
*
*/
-#include "hw/virtio/virtio.h"
-#include "virtio-9p.h"
-#include "virtio-9p-xattr.h"
+#include "9p.h"
+#include "9p-xattr.h"
#include <arpa/inet.h>
#include <pwd.h>
#include <grp.h>
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/9p-local.c
index f1f2e2573b..bf63eab729 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1,5 +1,5 @@
/*
- * Virtio 9p Posix callback
+ * 9p Posix callback
*
* Copyright IBM, Corp. 2010
*
@@ -11,9 +11,8 @@
*
*/
-#include "hw/virtio/virtio.h"
-#include "virtio-9p.h"
-#include "virtio-9p-xattr.h"
+#include "9p.h"
+#include "9p-xattr.h"
#include "fsdev/qemu-fsdev.h" /* local_ops */
#include <arpa/inet.h>
#include <pwd.h>
diff --git a/hw/9pfs/virtio-9p-posix-acl.c b/hw/9pfs/9p-posix-acl.c
index 09dad071e4..8df822833c 100644
--- a/hw/9pfs/virtio-9p-posix-acl.c
+++ b/hw/9pfs/9p-posix-acl.c
@@ -1,5 +1,5 @@
/*
- * Virtio 9p system.posix* xattr callback
+ * 9p system.posix* xattr callback
*
* Copyright IBM, Corp. 2010
*
@@ -13,10 +13,9 @@
#include <sys/types.h>
#include "qemu/xattr.h"
-#include "hw/virtio/virtio.h"
-#include "virtio-9p.h"
+#include "9p.h"
#include "fsdev/file-op-9p.h"
-#include "virtio-9p-xattr.h"
+#include "9p-xattr.h"
#define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access"
#define MAP_ACL_DEFAULT "user.virtfs.system.posix_acl_default"
diff --git a/hw/9pfs/virtio-9p-proxy.c b/hw/9pfs/9p-proxy.c
index 1bc7881f03..73d00dd74d 100644
--- a/hw/9pfs/virtio-9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -1,5 +1,5 @@
/*
- * Virtio 9p Proxy callback
+ * 9p Proxy callback
*
* Copyright IBM, Corp. 2011
*
@@ -11,11 +11,10 @@
*/
#include <sys/socket.h>
#include <sys/un.h>
-#include "hw/virtio/virtio.h"
-#include "virtio-9p.h"
+#include "9p.h"
#include "qemu/error-report.h"
#include "fsdev/qemu-fsdev.h"
-#include "virtio-9p-proxy.h"
+#include "9p-proxy.h"
typedef struct V9fsProxy {
int sockfd;
diff --git a/hw/9pfs/virtio-9p-proxy.h b/hw/9pfs/9p-proxy.h
index 005c1ad757..ba9ca203de 100644
--- a/hw/9pfs/virtio-9p-proxy.h
+++ b/hw/9pfs/9p-proxy.h
@@ -1,5 +1,5 @@
/*
- * Virtio 9p Proxy callback
+ * 9p Proxy callback
*
* Copyright IBM, Corp. 2011
*
@@ -9,8 +9,8 @@
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/
-#ifndef _QEMU_VIRTIO_9P_PROXY_H
-#define _QEMU_VIRTIO_9P_PROXY_H
+#ifndef _QEMU_9P_PROXY_H
+#define _QEMU_9P_PROXY_H
#define PROXY_MAX_IO_SZ (64 * 1024)
#define V9FS_FD_VALID INT_MAX
@@ -20,9 +20,9 @@
* marsha/unmarshal doesn't do little endian conversion.
*/
#define proxy_unmarshal(in_sg, offset, fmt, args...) \
- v9fs_unmarshal(in_sg, 1, offset, 0, fmt, ##args)
+ v9fs_iov_unmarshal(in_sg, 1, offset, 0, fmt, ##args)
#define proxy_marshal(out_sg, offset, fmt, args...) \
- v9fs_marshal(out_sg, 1, offset, 0, fmt, ##args)
+ v9fs_iov_marshal(out_sg, 1, offset, 0, fmt, ##args)
union MsgControl {
struct cmsghdr cmsg;
diff --git a/hw/9pfs/virtio-9p-synth.c b/hw/9pfs/9p-synth.c
index a0ab9a86a9..090ae0cd4c 100644
--- a/hw/9pfs/virtio-9p-synth.c
+++ b/hw/9pfs/9p-synth.c
@@ -13,10 +13,10 @@
*/
#include "hw/virtio/virtio.h"
-#include "virtio-9p.h"
-#include "virtio-9p-xattr.h"
+#include "9p.h"
+#include "9p-xattr.h"
#include "fsdev/qemu-fsdev.h"
-#include "virtio-9p-synth.h"
+#include "9p-synth.h"
#include "qemu/rcu.h"
#include "qemu/rcu_queue.h"
#include <sys/stat.h>
diff --git a/hw/9pfs/virtio-9p-synth.h b/hw/9pfs/9p-synth.h
index ab05a8e78c..eaf5a0c293 100644
--- a/hw/9pfs/virtio-9p-synth.h
+++ b/hw/9pfs/9p-synth.h
@@ -1,5 +1,5 @@
/*
- * Virtio 9p
+ * 9p
*
* Copyright IBM, Corp. 2011
*
@@ -10,8 +10,8 @@
* the COPYING file in the top-level directory.
*
*/
-#ifndef HW_9PFS_VIRTIO9P_SYNTH_H
-#define HW_9PFS_VIRTIO9P_SYNTH_H 1
+#ifndef HW_9PFS_SYNTH_H
+#define HW_9PFS_SYNTH_H 1
#include <unistd.h>
#include <sys/types.h>
diff --git a/hw/9pfs/virtio-9p-xattr-user.c b/hw/9pfs/9p-xattr-user.c
index 46133e06db..c490ec3bf0 100644
--- a/hw/9pfs/virtio-9p-xattr-user.c
+++ b/hw/9pfs/9p-xattr-user.c
@@ -1,5 +1,5 @@
/*
- * Virtio 9p user. xattr callback
+ * 9p user. xattr callback
*
* Copyright IBM, Corp. 2010
*
@@ -12,10 +12,9 @@
*/
#include <sys/types.h>
-#include "hw/virtio/virtio.h"
-#include "virtio-9p.h"
+#include "9p.h"
#include "fsdev/file-op-9p.h"
-#include "virtio-9p-xattr.h"
+#include "9p-xattr.h"
static ssize_t mp_user_getxattr(FsContext *ctx, const char *path,
diff --git a/hw/9pfs/virtio-9p-xattr.c b/hw/9pfs/9p-xattr.c
index 07183887c5..741dd03744 100644
--- a/hw/9pfs/virtio-9p-xattr.c
+++ b/hw/9pfs/9p-xattr.c
@@ -1,5 +1,5 @@
/*
- * Virtio 9p xattr callback
+ * 9p xattr callback
*
* Copyright IBM, Corp. 2010
*
@@ -11,10 +11,9 @@
*
*/
-#include "hw/virtio/virtio.h"
-#include "virtio-9p.h"
+#include "9p.h"
#include "fsdev/file-op-9p.h"
-#include "virtio-9p-xattr.h"
+#include "9p-xattr.h"
static XattrOperations *get_xattr_operations(XattrOperations **h,
diff --git a/hw/9pfs/virtio-9p-xattr.h b/hw/9pfs/9p-xattr.h
index 327b32b5aa..4d39a20262 100644
--- a/hw/9pfs/virtio-9p-xattr.h
+++ b/hw/9pfs/9p-xattr.h
@@ -1,5 +1,5 @@
/*
- * Virtio 9p
+ * 9p
*
* Copyright IBM, Corp. 2010
*
@@ -10,8 +10,8 @@
* the COPYING file in the top-level directory.
*
*/
-#ifndef _QEMU_VIRTIO_9P_XATTR_H
-#define _QEMU_VIRTIO_9P_XATTR_H
+#ifndef _QEMU_9P_XATTR_H
+#define _QEMU_9P_XATTR_H
#include "qemu/xattr.h"
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/9p.c
index f972731f5a..3ff310605c 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/9p.c
@@ -18,8 +18,8 @@
#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"
@@ -39,6 +39,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;
@@ -563,7 +592,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;
@@ -575,9 +604,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 .
@@ -594,9 +624,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) {
int err = -len;
@@ -627,16 +658,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);
}
static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension)
@@ -931,7 +958,7 @@ 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);
}
@@ -995,7 +1022,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);
}
@@ -1009,7 +1036,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) {
@@ -1042,7 +1068,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)
@@ -1105,7 +1131,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 */
@@ -1129,7 +1155,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) {
@@ -1203,7 +1228,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)
@@ -1245,7 +1270,7 @@ static void v9fs_walk(void *opaque)
err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames);
if (err < 0) {
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
return ;
}
offset += err;
@@ -1313,7 +1338,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]);
@@ -1430,7 +1455,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)
@@ -1487,7 +1512,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);
}
@@ -1499,7 +1524,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) {
@@ -1518,7 +1542,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)
@@ -1551,7 +1575,7 @@ static void v9fs_clunk(void *opaque)
err = offset;
}
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
}
static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
@@ -1561,6 +1585,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;
@@ -1577,7 +1603,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) {
@@ -1667,13 +1694,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);
@@ -1761,7 +1782,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)
@@ -1848,7 +1869,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);
@@ -1885,7 +1905,7 @@ static void v9fs_readdir(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, retval);
+ pdu_complete(pdu, retval);
}
static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
@@ -1952,7 +1972,7 @@ static void v9fs_write(void *opaque)
err = pdu_unmarshal(pdu, offset, "dqd", &fid, &off, &count);
if (err < 0) {
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
return;
}
offset += err;
@@ -2015,7 +2035,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)
@@ -2182,7 +2202,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);
@@ -2229,7 +2249,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);
}
@@ -2245,7 +2265,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);
@@ -2262,15 +2282,14 @@ 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);
+ pdu_complete(pdu, 7);
}
static void v9fs_link(void *opaque)
{
V9fsPDU *pdu = opaque;
- V9fsState *s = pdu->s;
int32_t dfid, oldfid;
V9fsFidState *dfidp, *oldfidp;
V9fsString name;
@@ -2303,7 +2322,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 */
@@ -2348,7 +2367,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)
@@ -2392,7 +2411,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);
}
@@ -2492,7 +2511,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);
}
@@ -2593,7 +2612,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);
}
@@ -2608,7 +2627,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);
@@ -2690,7 +2708,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)
@@ -2769,7 +2787,7 @@ static void v9fs_statfs(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
- complete_pdu(s, pdu, retval);
+ pdu_complete(pdu, retval);
}
static void v9fs_mknod(void *opaque)
@@ -2786,7 +2804,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,
@@ -2817,7 +2834,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);
}
@@ -2838,7 +2855,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);
@@ -2875,7 +2891,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);
}
@@ -2891,7 +2907,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,
@@ -2925,7 +2940,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);
}
@@ -2969,7 +2984,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);
}
@@ -3075,7 +3090,7 @@ out:
put_fid(pdu, xattr_fidp);
}
out_nofid:
- complete_pdu(s, pdu, err);
+ pdu_complete(pdu, err);
v9fs_string_free(&name);
}
@@ -3090,7 +3105,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);
@@ -3116,7 +3130,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);
}
@@ -3156,7 +3170,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[] = {
@@ -3199,13 +3213,13 @@ static CoroutineEntry *pdu_co_handlers[] = {
static void v9fs_op_not_supp(void *opaque)
{
V9fsPDU *pdu = opaque;
- complete_pdu(pdu->s, pdu, -EOPNOTSUPP);
+ pdu_complete(pdu, -EOPNOTSUPP);
}
static void v9fs_fs_ro(void *opaque)
{
V9fsPDU *pdu = opaque;
- complete_pdu(pdu->s, pdu, -EROFS);
+ pdu_complete(pdu, -EROFS);
}
static inline bool is_read_only_op(V9fsPDU *pdu)
@@ -3235,10 +3249,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)) {
@@ -3254,41 +3269,104 @@ 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;
+ 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) {
- struct {
- uint32_t size_le;
- uint8_t id;
- uint16_t tag_le;
- } QEMU_PACKED out;
- int len;
+ s->tag = g_strdup(s->fsconf.tag);
+ s->ctx.uid = -1;
- pdu->s = s;
- BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0);
- QEMU_BUILD_BUG_ON(sizeof out != 7);
+ s->ops = fse->ops;
- len = iov_to_buf(pdu->elem.out_sg, pdu->elem.out_num, 0,
- &out, sizeof out);
- BUG_ON(len != sizeof out);
+ s->fid_list = NULL;
+ qemu_co_rwlock_init(&s->rename_lock);
- pdu->size = le32_to_cpu(out.size_le);
+ 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;
+ }
- pdu->id = out.id;
- pdu->tag = le16_to_cpu(out.tag_le);
+ /*
+ * 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.
+ */
+ if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
+ 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;
+ }
+ v9fs_path_free(&path);
- qemu_co_queue_init(&pdu->complete);
- submit_pdu(s, pdu);
+ rc = 0;
+out:
+ if (rc) {
+ g_free(s->ctx.fs_root);
+ g_free(s->tag);
+ v9fs_path_free(&path);
}
- free_pdu(s, pdu);
+ return rc;
+}
+
+void v9fs_device_unrealize_common(V9fsState *s, Error **errp)
+{
+ 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)
{
struct rlimit rlim;
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
new file mode 100644
index 0000000000..edcd51be15
--- /dev/null
+++ b/hw/9pfs/9p.h
@@ -0,0 +1,326 @@
+#ifndef _QEMU_9P_H
+#define _QEMU_9P_H
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/time.h>
+#include <utime.h>
+#include <sys/resource.h>
+#include <glib.h>
+#include "standard-headers/linux/virtio_9p.h"
+#include "hw/virtio/virtio.h"
+#include "fsdev/file-op-9p.h"
+#include "fsdev/9p-iov-marshal.h"
+#include "qemu/thread.h"
+#include "qemu/coroutine.h"
+
+enum {
+ P9_TLERROR = 6,
+ P9_RLERROR,
+ P9_TSTATFS = 8,
+ P9_RSTATFS,
+ P9_TLOPEN = 12,
+ P9_RLOPEN,
+ P9_TLCREATE = 14,
+ P9_RLCREATE,
+ P9_TSYMLINK = 16,
+ P9_RSYMLINK,
+ P9_TMKNOD = 18,
+ P9_RMKNOD,
+ P9_TRENAME = 20,
+ P9_RRENAME,
+ P9_TREADLINK = 22,
+ P9_RREADLINK,
+ P9_TGETATTR = 24,
+ P9_RGETATTR,
+ P9_TSETATTR = 26,
+ P9_RSETATTR,
+ P9_TXATTRWALK = 30,
+ P9_RXATTRWALK,
+ P9_TXATTRCREATE = 32,
+ P9_RXATTRCREATE,
+ P9_TREADDIR = 40,
+ P9_RREADDIR,
+ P9_TFSYNC = 50,
+ P9_RFSYNC,
+ P9_TLOCK = 52,
+ P9_RLOCK,
+ P9_TGETLOCK = 54,
+ P9_RGETLOCK,
+ P9_TLINK = 70,
+ P9_RLINK,
+ P9_TMKDIR = 72,
+ P9_RMKDIR,
+ P9_TRENAMEAT = 74,
+ P9_RRENAMEAT,
+ P9_TUNLINKAT = 76,
+ P9_RUNLINKAT,
+ P9_TVERSION = 100,
+ P9_RVERSION,
+ P9_TAUTH = 102,
+ P9_RAUTH,
+ P9_TATTACH = 104,
+ P9_RATTACH,
+ P9_TERROR = 106,
+ P9_RERROR,
+ P9_TFLUSH = 108,
+ P9_RFLUSH,
+ P9_TWALK = 110,
+ P9_RWALK,
+ P9_TOPEN = 112,
+ P9_ROPEN,
+ P9_TCREATE = 114,
+ P9_RCREATE,
+ P9_TREAD = 116,
+ P9_RREAD,
+ P9_TWRITE = 118,
+ P9_RWRITE,
+ P9_TCLUNK = 120,
+ P9_RCLUNK,
+ P9_TREMOVE = 122,
+ P9_RREMOVE,
+ P9_TSTAT = 124,
+ P9_RSTAT,
+ P9_TWSTAT = 126,
+ P9_RWSTAT,
+};
+
+
+/* qid.types */
+enum {
+ P9_QTDIR = 0x80,
+ P9_QTAPPEND = 0x40,
+ P9_QTEXCL = 0x20,
+ P9_QTMOUNT = 0x10,
+ P9_QTAUTH = 0x08,
+ P9_QTTMP = 0x04,
+ P9_QTSYMLINK = 0x02,
+ P9_QTLINK = 0x01,
+ P9_QTFILE = 0x00,
+};
+
+enum p9_proto_version {
+ V9FS_PROTO_2000U = 0x01,
+ V9FS_PROTO_2000L = 0x02,
+};
+
+#define P9_NOTAG (u16)(~0)
+#define P9_NOFID (u32)(~0)
+#define P9_MAXWELEM 16
+
+#define FID_REFERENCED 0x1
+#define FID_NON_RECLAIMABLE 0x2
+static inline char *rpath(FsContext *ctx, const char *path)
+{
+ return g_strdup_printf("%s/%s", ctx->fs_root, path);
+}
+
+/*
+ * ample room for Twrite/Rread header
+ * size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4]
+ */
+#define P9_IOHDRSZ 24
+
+typedef struct V9fsPDU V9fsPDU;
+struct V9fsState;
+
+struct V9fsPDU
+{
+ uint32_t size;
+ uint16_t tag;
+ uint8_t id;
+ uint8_t cancelled;
+ CoQueue complete;
+ struct V9fsState *s;
+ QLIST_ENTRY(V9fsPDU) next;
+ uint32_t idx;
+};
+
+
+/* FIXME
+ * 1) change user needs to set groups and stuff
+ */
+
+#define MAX_REQ 128
+#define MAX_TAG_LEN 32
+
+#define BUG_ON(cond) assert(!(cond))
+
+typedef struct V9fsFidState V9fsFidState;
+
+enum {
+ P9_FID_NONE = 0,
+ P9_FID_FILE,
+ P9_FID_DIR,
+ P9_FID_XATTR,
+};
+
+typedef struct V9fsConf
+{
+ /* tag name for the device */
+ char *tag;
+ char *fsdev_id;
+} V9fsConf;
+
+typedef struct V9fsXattr
+{
+ int64_t copied_len;
+ int64_t len;
+ void *value;
+ V9fsString name;
+ int flags;
+} V9fsXattr;
+
+/*
+ * Filled by fs driver on open and other
+ * calls.
+ */
+union V9fsFidOpenState {
+ int fd;
+ DIR *dir;
+ V9fsXattr xattr;
+ /*
+ * private pointer for fs drivers, that
+ * have its own internal representation of
+ * open files.
+ */
+ void *private;
+};
+
+struct V9fsFidState
+{
+ int fid_type;
+ int32_t fid;
+ V9fsPath path;
+ V9fsFidOpenState fs;
+ V9fsFidOpenState fs_reclaim;
+ int flags;
+ int open_flags;
+ uid_t uid;
+ int ref;
+ int clunked;
+ V9fsFidState *next;
+ V9fsFidState *rclm_lst;
+};
+
+typedef struct V9fsState
+{
+ QLIST_HEAD(, V9fsPDU) free_list;
+ QLIST_HEAD(, V9fsPDU) active_list;
+ V9fsFidState *fid_list;
+ FileOperations *ops;
+ FsContext ctx;
+ char *tag;
+ enum p9_proto_version proto_version;
+ int32_t msize;
+ /*
+ * lock ensuring atomic path update
+ * on rename.
+ */
+ CoRwlock rename_lock;
+ int32_t root_fid;
+ Error *migration_blocker;
+ V9fsConf fsconf;
+} V9fsState;
+
+/* 9p2000.L open flags */
+#define P9_DOTL_RDONLY 00000000
+#define P9_DOTL_WRONLY 00000001
+#define P9_DOTL_RDWR 00000002
+#define P9_DOTL_NOACCESS 00000003
+#define P9_DOTL_CREATE 00000100
+#define P9_DOTL_EXCL 00000200
+#define P9_DOTL_NOCTTY 00000400
+#define P9_DOTL_TRUNC 00001000
+#define P9_DOTL_APPEND 00002000
+#define P9_DOTL_NONBLOCK 00004000
+#define P9_DOTL_DSYNC 00010000
+#define P9_DOTL_FASYNC 00020000
+#define P9_DOTL_DIRECT 00040000
+#define P9_DOTL_LARGEFILE 00100000
+#define P9_DOTL_DIRECTORY 00200000
+#define P9_DOTL_NOFOLLOW 00400000
+#define P9_DOTL_NOATIME 01000000
+#define P9_DOTL_CLOEXEC 02000000
+#define P9_DOTL_SYNC 04000000
+
+/* 9p2000.L at flags */
+#define P9_DOTL_AT_REMOVEDIR 0x200
+
+/* 9P2000.L lock type */
+#define P9_LOCK_TYPE_RDLCK 0
+#define P9_LOCK_TYPE_WRLCK 1
+#define P9_LOCK_TYPE_UNLCK 2
+
+#define P9_LOCK_SUCCESS 0
+#define P9_LOCK_BLOCKED 1
+#define P9_LOCK_ERROR 2
+#define P9_LOCK_GRACE 3
+
+#define P9_LOCK_FLAGS_BLOCK 1
+#define P9_LOCK_FLAGS_RECLAIM 2
+
+typedef struct V9fsFlock
+{
+ uint8_t type;
+ uint32_t flags;
+ uint64_t start; /* absolute offset */
+ uint64_t length;
+ uint32_t proc_id;
+ V9fsString client_id;
+} V9fsFlock;
+
+typedef struct V9fsGetlock
+{
+ uint8_t type;
+ uint64_t start; /* absolute offset */
+ uint64_t length;
+ uint32_t proc_id;
+ V9fsString client_id;
+} V9fsGetlock;
+
+extern int open_fd_hw;
+extern int total_open_fd;
+
+static inline void v9fs_path_write_lock(V9fsState *s)
+{
+ if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
+ qemu_co_rwlock_wrlock(&s->rename_lock);
+ }
+}
+
+static inline void v9fs_path_read_lock(V9fsState *s)
+{
+ if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
+ qemu_co_rwlock_rdlock(&s->rename_lock);
+ }
+}
+
+static inline void v9fs_path_unlock(V9fsState *s)
+{
+ if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
+ qemu_co_rwlock_unlock(&s->rename_lock);
+ }
+}
+
+static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu)
+{
+ return pdu->cancelled;
+}
+
+extern void v9fs_reclaim_fd(V9fsPDU *pdu);
+extern void v9fs_path_init(V9fsPath *path);
+extern void v9fs_path_free(V9fsPath *path);
+extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs);
+extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath,
+ const char *name, V9fsPath *path);
+extern int v9fs_device_realize_common(V9fsState *s, Error **errp);
+extern void v9fs_device_unrealize_common(V9fsState *s, Error **errp);
+
+ssize_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...);
+ssize_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...);
+V9fsPDU *pdu_alloc(V9fsState *s);
+void pdu_free(V9fsPDU *pdu);
+void pdu_submit(V9fsPDU *pdu);
+
+#endif
diff --git a/hw/9pfs/Makefile.objs b/hw/9pfs/Makefile.objs
index 1e9b595cb4..da0ae0cfdb 100644
--- a/hw/9pfs/Makefile.objs
+++ b/hw/9pfs/Makefile.objs
@@ -1,9 +1,9 @@
-common-obj-y = virtio-9p.o
-common-obj-y += virtio-9p-local.o virtio-9p-xattr.o
-common-obj-y += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
-common-obj-y += virtio-9p-coth.o cofs.o codir.o cofile.o
-common-obj-y += coxattr.o virtio-9p-synth.o
-common-obj-$(CONFIG_OPEN_BY_HANDLE) += virtio-9p-handle.o
-common-obj-y += virtio-9p-proxy.o
+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
+common-obj-y += coth.o cofs.o codir.o cofile.o
+common-obj-y += coxattr.o 9p-synth.o
+common-obj-$(CONFIG_OPEN_BY_HANDLE) += 9p-handle.o
+common-obj-y += 9p-proxy.o
obj-y += virtio-9p-device.o
diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index ec9cc7fb27..5a4f74d3e0 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -15,7 +15,7 @@
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
#include "qemu/coroutine.h"
-#include "virtio-9p-coth.h"
+#include "coth.h"
int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
struct dirent **result)
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 7cb55ee93a..893df2c422 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -15,7 +15,7 @@
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
#include "qemu/coroutine.h"
-#include "virtio-9p-coth.h"
+#include "coth.h"
int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
V9fsStatDotl *v9stat)
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index e1953a9aa1..7b4202bd77 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -15,7 +15,7 @@
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
#include "qemu/coroutine.h"
-#include "virtio-9p-coth.h"
+#include "coth.h"
static ssize_t __readlink(V9fsState *s, V9fsPath *path, V9fsString *buf)
{
diff --git a/hw/9pfs/virtio-9p-coth.c b/hw/9pfs/coth.c
index ab9425c60f..56772d66be 100644
--- a/hw/9pfs/virtio-9p-coth.c
+++ b/hw/9pfs/coth.c
@@ -1,5 +1,5 @@
/*
- * Virtio 9p backend
+ * 9p backend
*
* Copyright IBM, Corp. 2010
*
@@ -16,7 +16,7 @@
#include "block/thread-pool.h"
#include "qemu/coroutine.h"
#include "qemu/main-loop.h"
-#include "virtio-9p-coth.h"
+#include "coth.h"
/* Called from QEMU I/O thread. */
static void coroutine_enter_cb(void *opaque, int ret)
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/coth.h
index 4ac1aaf902..209fc6a9af 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/coth.h
@@ -1,5 +1,5 @@
/*
- * Virtio 9p backend
+ * 9p backend
*
* Copyright IBM, Corp. 2010
*
@@ -12,8 +12,8 @@
*
*/
-#ifndef _QEMU_VIRTIO_9P_COTH_H
-#define _QEMU_VIRTIO_9P_COTH_H
+#ifndef _QEMU_9P_COTH_H
+#define _QEMU_9P_COTH_H
#include "qemu/thread.h"
#include "qemu/coroutine.h"
diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c
index 55c0d231cb..0590cbf5c7 100644
--- a/hw/9pfs/coxattr.c
+++ b/hw/9pfs/coxattr.c
@@ -15,7 +15,7 @@
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
#include "qemu/coroutine.h"
-#include "virtio-9p-coth.h"
+#include "coth.h"
int v9fs_co_llistxattr(V9fsPDU *pdu, V9fsPath *path, void *value, size_t size)
{
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index b42d3b30a0..5643fd5b13 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -12,14 +12,65 @@
*/
#include "hw/virtio/virtio.h"
-#include "hw/virtio/virtio-9p.h"
#include "hw/i386/pc.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 "hw/virtio/virtio-access.h"
+#include "qemu/iov.h"
+
+void virtio_9p_push_and_notify(V9fsPDU *pdu)
+{
+ V9fsState *s = pdu->s;
+ V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
+ VirtQueueElement *elem = &v->elems[pdu->idx];
+
+ /* push onto queue and notify */
+ virtqueue_push(v->vq, elem, pdu->size);
+
+ /* FIXME: we should batch these completions */
+ virtio_notify(VIRTIO_DEVICE(v), v->vq);
+}
+
+static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+ V9fsVirtioState *v = (V9fsVirtioState *)vdev;
+ V9fsState *s = &v->state;
+ V9fsPDU *pdu;
+ ssize_t len;
+
+ while ((pdu = pdu_alloc(s))) {
+ struct {
+ uint32_t size_le;
+ uint8_t id;
+ uint16_t tag_le;
+ } QEMU_PACKED out;
+ VirtQueueElement *elem = &v->elems[pdu->idx];
+
+ len = virtqueue_pop(vq, elem);
+ if (!len) {
+ pdu_free(pdu);
+ break;
+ }
+
+ BUG_ON(elem->out_num == 0 || elem->in_num == 0);
+ QEMU_BUILD_BUG_ON(sizeof out != 7);
+
+ len = iov_to_buf(elem->out_sg, elem->out_num, 0,
+ &out, sizeof out);
+ BUG_ON(len != sizeof out);
+
+ pdu->size = le32_to_cpu(out.size_le);
+
+ pdu->id = out.id;
+ pdu->tag = le16_to_cpu(out.tag_le);
+
+ qemu_co_queue_init(&pdu->complete);
+ pdu_submit(pdu);
+ }
+}
static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features,
Error **errp)
@@ -32,14 +83,15 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
{
int len;
struct virtio_9p_config *cfg;
- V9fsState *s = VIRTIO_9P(vdev);
+ V9fsVirtioState *v = VIRTIO_9P(vdev);
+ V9fsState *s = &v->state;
len = strlen(s->tag);
cfg = g_malloc0(sizeof(struct virtio_9p_config) + len);
virtio_stw_p(vdev, &cfg->tag_len, len);
/* We don't copy the terminating null to config space */
memcpy(cfg->tag, s->tag, len);
- memcpy(config, cfg, s->config_size);
+ memcpy(config, cfg, v->config_size);
g_free(cfg);
}
@@ -56,111 +108,74 @@ static int virtio_9p_load(QEMUFile *f, void *opaque, int version_id)
static void virtio_9p_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- V9fsState *s = VIRTIO_9P(dev);
- int i, len;
- struct stat stat;
- FsDriverEntry *fse;
- V9fsPath path;
-
- virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P,
- sizeof(struct virtio_9p_config) + MAX_TAG_LEN);
-
- /* 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, &s->pdus[i], next);
- }
-
- s->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
-
- 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, "Virtio-9p 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;
- }
+ V9fsVirtioState *v = VIRTIO_9P(dev);
+ V9fsState *s = &v->state;
- s->tag = g_strdup(s->fsconf.tag);
- s->ctx.uid = -1;
-
- s->ops = fse->ops;
- s->config_size = sizeof(struct virtio_9p_config) + len;
- s->fid_list = NULL;
- qemu_co_rwlock_init(&s->rename_lock);
-
- if (s->ops->init(&s->ctx) < 0) {
- error_setg(errp, "Virtio-9p Failed to initialize fs-driver with id:%s"
- " and export path:%s", s->fsconf.fsdev_id, s->ctx.fs_root);
+ if (v9fs_device_realize_common(s, errp)) {
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.
- */
- if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
- 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;
- }
- v9fs_path_free(&path);
+ v->config_size = sizeof(struct virtio_9p_config) + strlen(s->fsconf.tag);
+ virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, v->config_size);
+ v->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
+ register_savevm(dev, "virtio-9p", -1, 1, virtio_9p_save, virtio_9p_load, v);
- register_savevm(dev, "virtio-9p", -1, 1, virtio_9p_save, virtio_9p_load, s);
- return;
out:
- g_free(s->ctx.fs_root);
- g_free(s->tag);
- virtio_cleanup(vdev);
- v9fs_path_free(&path);
+ return;
}
static void virtio_9p_device_unrealize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- V9fsState *s = VIRTIO_9P(dev);
+ V9fsVirtioState *v = VIRTIO_9P(dev);
+ V9fsState *s = &v->state;
virtio_cleanup(vdev);
- unregister_savevm(dev, "virtio-9p", s);
- g_free(s->ctx.fs_root);
- g_free(s->tag);
+ unregister_savevm(dev, "virtio-9p", v);
+ v9fs_device_unrealize_common(s, errp);
+}
+
+ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset,
+ const char *fmt, va_list ap)
+{
+ V9fsState *s = pdu->s;
+ V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
+ VirtQueueElement *elem = &v->elems[pdu->idx];
+
+ return v9fs_iov_vmarshal(elem->in_sg, elem->in_num, offset, 1, fmt, ap);
+}
+
+ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset,
+ const char *fmt, va_list ap)
+{
+ V9fsState *s = pdu->s;
+ V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
+ VirtQueueElement *elem = &v->elems[pdu->idx];
+
+ return v9fs_iov_vunmarshal(elem->out_sg, elem->out_num, offset, 1, fmt, ap);
+}
+
+void virtio_init_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,
+ unsigned int *pniov, bool is_write)
+{
+ V9fsState *s = pdu->s;
+ V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
+ VirtQueueElement *elem = &v->elems[pdu->idx];
+
+ if (is_write) {
+ *piov = elem->out_sg;
+ *pniov = elem->out_num;
+ } else {
+ *piov = elem->in_sg;
+ *pniov = elem->in_num;
+ }
}
/* virtio-9p device */
static Property virtio_9p_properties[] = {
- DEFINE_PROP_STRING("mount_tag", V9fsState, fsconf.tag),
- DEFINE_PROP_STRING("fsdev", V9fsState, fsconf.fsdev_id),
+ DEFINE_PROP_STRING("mount_tag", V9fsVirtioState, state.fsconf.tag),
+ DEFINE_PROP_STRING("fsdev", V9fsVirtioState, state.fsconf.fsdev_id),
DEFINE_PROP_END_OF_LIST(),
};
@@ -180,7 +195,7 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
static const TypeInfo virtio_device_info = {
.name = TYPE_VIRTIO_9P,
.parent = TYPE_VIRTIO_DEVICE,
- .instance_size = sizeof(V9fsState),
+ .instance_size = sizeof(V9fsVirtioState),
.class_init = virtio_9p_class_init,
};
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index d7a4dc1e9a..1cdf0a2d65 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -1,394 +1,31 @@
#ifndef _QEMU_VIRTIO_9P_H
#define _QEMU_VIRTIO_9P_H
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/time.h>
-#include <utime.h>
-#include <sys/resource.h>
-#include <glib.h>
#include "standard-headers/linux/virtio_9p.h"
#include "hw/virtio/virtio.h"
-#include "hw/virtio/virtio-9p.h"
-#include "fsdev/file-op-9p.h"
-#include "fsdev/virtio-9p-marshal.h"
-#include "qemu/thread.h"
-#include "qemu/coroutine.h"
+#include "9p.h"
-enum {
- P9_TLERROR = 6,
- P9_RLERROR,
- P9_TSTATFS = 8,
- P9_RSTATFS,
- P9_TLOPEN = 12,
- P9_RLOPEN,
- P9_TLCREATE = 14,
- P9_RLCREATE,
- P9_TSYMLINK = 16,
- P9_RSYMLINK,
- P9_TMKNOD = 18,
- P9_RMKNOD,
- P9_TRENAME = 20,
- P9_RRENAME,
- P9_TREADLINK = 22,
- P9_RREADLINK,
- P9_TGETATTR = 24,
- P9_RGETATTR,
- P9_TSETATTR = 26,
- P9_RSETATTR,
- P9_TXATTRWALK = 30,
- P9_RXATTRWALK,
- P9_TXATTRCREATE = 32,
- P9_RXATTRCREATE,
- P9_TREADDIR = 40,
- P9_RREADDIR,
- P9_TFSYNC = 50,
- P9_RFSYNC,
- P9_TLOCK = 52,
- P9_RLOCK,
- P9_TGETLOCK = 54,
- P9_RGETLOCK,
- P9_TLINK = 70,
- P9_RLINK,
- P9_TMKDIR = 72,
- P9_RMKDIR,
- P9_TRENAMEAT = 74,
- P9_RRENAMEAT,
- P9_TUNLINKAT = 76,
- P9_RUNLINKAT,
- P9_TVERSION = 100,
- P9_RVERSION,
- P9_TAUTH = 102,
- P9_RAUTH,
- P9_TATTACH = 104,
- P9_RATTACH,
- P9_TERROR = 106,
- P9_RERROR,
- P9_TFLUSH = 108,
- P9_RFLUSH,
- P9_TWALK = 110,
- P9_RWALK,
- P9_TOPEN = 112,
- P9_ROPEN,
- P9_TCREATE = 114,
- P9_RCREATE,
- P9_TREAD = 116,
- P9_RREAD,
- P9_TWRITE = 118,
- P9_RWRITE,
- P9_TCLUNK = 120,
- P9_RCLUNK,
- P9_TREMOVE = 122,
- P9_RREMOVE,
- P9_TSTAT = 124,
- P9_RSTAT,
- P9_TWSTAT = 126,
- P9_RWSTAT,
-};
-
-
-/* qid.types */
-enum {
- P9_QTDIR = 0x80,
- P9_QTAPPEND = 0x40,
- P9_QTEXCL = 0x20,
- P9_QTMOUNT = 0x10,
- P9_QTAUTH = 0x08,
- P9_QTTMP = 0x04,
- P9_QTSYMLINK = 0x02,
- P9_QTLINK = 0x01,
- P9_QTFILE = 0x00,
-};
-
-enum p9_proto_version {
- V9FS_PROTO_2000U = 0x01,
- V9FS_PROTO_2000L = 0x02,
-};
-
-#define P9_NOTAG (u16)(~0)
-#define P9_NOFID (u32)(~0)
-#define P9_MAXWELEM 16
-
-#define FID_REFERENCED 0x1
-#define FID_NON_RECLAIMABLE 0x2
-static inline char *rpath(FsContext *ctx, const char *path)
-{
- return g_strdup_printf("%s/%s", ctx->fs_root, path);
-}
-
-/*
- * ample room for Twrite/Rread header
- * size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4]
- */
-#define P9_IOHDRSZ 24
-
-typedef struct V9fsPDU V9fsPDU;
-struct V9fsState;
-
-struct V9fsPDU
-{
- uint32_t size;
- uint16_t tag;
- uint8_t id;
- uint8_t cancelled;
- CoQueue complete;
- VirtQueueElement elem;
- struct V9fsState *s;
- QLIST_ENTRY(V9fsPDU) next;
-};
-
-
-/* FIXME
- * 1) change user needs to set groups and stuff
- */
-
-#define MAX_REQ 128
-#define MAX_TAG_LEN 32
-
-#define BUG_ON(cond) assert(!(cond))
-
-typedef struct V9fsFidState V9fsFidState;
-
-enum {
- P9_FID_NONE = 0,
- P9_FID_FILE,
- P9_FID_DIR,
- P9_FID_XATTR,
-};
-
-typedef struct V9fsXattr
-{
- int64_t copied_len;
- int64_t len;
- void *value;
- V9fsString name;
- int flags;
-} V9fsXattr;
-
-/*
- * Filled by fs driver on open and other
- * calls.
- */
-union V9fsFidOpenState {
- int fd;
- DIR *dir;
- V9fsXattr xattr;
- /*
- * private pointer for fs drivers, that
- * have its own internal representation of
- * open files.
- */
- void *private;
-};
-
-struct V9fsFidState
-{
- int fid_type;
- int32_t fid;
- V9fsPath path;
- V9fsFidOpenState fs;
- V9fsFidOpenState fs_reclaim;
- int flags;
- int open_flags;
- uid_t uid;
- int ref;
- int clunked;
- V9fsFidState *next;
- V9fsFidState *rclm_lst;
-};
-
-typedef struct V9fsState
+typedef struct V9fsVirtioState
{
VirtIODevice parent_obj;
VirtQueue *vq;
- V9fsPDU pdus[MAX_REQ];
- QLIST_HEAD(, V9fsPDU) free_list;
- QLIST_HEAD(, V9fsPDU) active_list;
- V9fsFidState *fid_list;
- FileOperations *ops;
- FsContext ctx;
- char *tag;
size_t config_size;
- enum p9_proto_version proto_version;
- int32_t msize;
- /*
- * lock ensuring atomic path update
- * on rename.
- */
- CoRwlock rename_lock;
- int32_t root_fid;
- Error *migration_blocker;
- V9fsConf fsconf;
-} V9fsState;
-
-typedef struct V9fsStatState {
- V9fsPDU *pdu;
- size_t offset;
- V9fsStat v9stat;
- V9fsFidState *fidp;
- struct stat stbuf;
-} V9fsStatState;
-
-typedef struct V9fsOpenState {
- V9fsPDU *pdu;
- size_t offset;
- int32_t mode;
- V9fsFidState *fidp;
- V9fsQID qid;
- struct stat stbuf;
- int iounit;
-} V9fsOpenState;
-
-typedef struct V9fsReadState {
- V9fsPDU *pdu;
- size_t offset;
- int32_t count;
- int32_t total;
- int64_t off;
- V9fsFidState *fidp;
- struct iovec iov[128]; /* FIXME: bad, bad, bad */
- struct iovec *sg;
- off_t dir_pos;
- struct dirent *dent;
- struct stat stbuf;
- V9fsString name;
- V9fsStat v9stat;
- int32_t len;
- int32_t cnt;
- int32_t max_count;
-} V9fsReadState;
-
-typedef struct V9fsWriteState {
- V9fsPDU *pdu;
- size_t offset;
- int32_t len;
- int32_t count;
- int32_t total;
- int64_t off;
- V9fsFidState *fidp;
- struct iovec iov[128]; /* FIXME: bad, bad, bad */
- struct iovec *sg;
- int cnt;
-} V9fsWriteState;
-
-typedef struct V9fsMkState {
- V9fsPDU *pdu;
- size_t offset;
- V9fsQID qid;
- struct stat stbuf;
- V9fsString name;
- V9fsString fullname;
-} V9fsMkState;
-
-/* 9p2000.L open flags */
-#define P9_DOTL_RDONLY 00000000
-#define P9_DOTL_WRONLY 00000001
-#define P9_DOTL_RDWR 00000002
-#define P9_DOTL_NOACCESS 00000003
-#define P9_DOTL_CREATE 00000100
-#define P9_DOTL_EXCL 00000200
-#define P9_DOTL_NOCTTY 00000400
-#define P9_DOTL_TRUNC 00001000
-#define P9_DOTL_APPEND 00002000
-#define P9_DOTL_NONBLOCK 00004000
-#define P9_DOTL_DSYNC 00010000
-#define P9_DOTL_FASYNC 00020000
-#define P9_DOTL_DIRECT 00040000
-#define P9_DOTL_LARGEFILE 00100000
-#define P9_DOTL_DIRECTORY 00200000
-#define P9_DOTL_NOFOLLOW 00400000
-#define P9_DOTL_NOATIME 01000000
-#define P9_DOTL_CLOEXEC 02000000
-#define P9_DOTL_SYNC 04000000
-
-/* 9p2000.L at flags */
-#define P9_DOTL_AT_REMOVEDIR 0x200
-
-/* 9P2000.L lock type */
-#define P9_LOCK_TYPE_RDLCK 0
-#define P9_LOCK_TYPE_WRLCK 1
-#define P9_LOCK_TYPE_UNLCK 2
-
-#define P9_LOCK_SUCCESS 0
-#define P9_LOCK_BLOCKED 1
-#define P9_LOCK_ERROR 2
-#define P9_LOCK_GRACE 3
-
-#define P9_LOCK_FLAGS_BLOCK 1
-#define P9_LOCK_FLAGS_RECLAIM 2
-
-typedef struct V9fsFlock
-{
- uint8_t type;
- uint32_t flags;
- uint64_t start; /* absolute offset */
- uint64_t length;
- uint32_t proc_id;
- V9fsString client_id;
-} V9fsFlock;
-
-typedef struct V9fsGetlock
-{
- uint8_t type;
- uint64_t start; /* absolute offset */
- uint64_t length;
- uint32_t proc_id;
- V9fsString client_id;
-} V9fsGetlock;
-
-extern int open_fd_hw;
-extern int total_open_fd;
-
-size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
- size_t offset, size_t size, int pack);
-
-static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
- size_t offset, size_t size)
-{
- return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
-}
-
-static inline void v9fs_path_write_lock(V9fsState *s)
-{
- if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
- qemu_co_rwlock_wrlock(&s->rename_lock);
- }
-}
-
-static inline void v9fs_path_read_lock(V9fsState *s)
-{
- if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
- qemu_co_rwlock_rdlock(&s->rename_lock);
- }
-}
-
-static inline void v9fs_path_unlock(V9fsState *s)
-{
- if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
- qemu_co_rwlock_unlock(&s->rename_lock);
- }
-}
-
-static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu)
-{
- return pdu->cancelled;
-}
+ V9fsPDU pdus[MAX_REQ];
+ VirtQueueElement elems[MAX_REQ];
+ V9fsState state;
+} V9fsVirtioState;
-extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
-extern void v9fs_reclaim_fd(V9fsPDU *pdu);
-extern void v9fs_path_init(V9fsPath *path);
-extern void v9fs_path_free(V9fsPath *path);
-extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs);
-extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath,
- const char *name, V9fsPath *path);
+extern void virtio_9p_push_and_notify(V9fsPDU *pdu);
-#define pdu_marshal(pdu, offset, fmt, args...) \
- v9fs_marshal(pdu->elem.in_sg, pdu->elem.in_num, offset, 1, fmt, ##args)
-#define pdu_unmarshal(pdu, offset, fmt, args...) \
- v9fs_unmarshal(pdu->elem.out_sg, pdu->elem.out_num, offset, 1, fmt, ##args)
+ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset,
+ const char *fmt, va_list ap);
+ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset,
+ const char *fmt, va_list ap);
+void virtio_init_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,
+ unsigned int *pniov, bool is_write);
#define TYPE_VIRTIO_9P "virtio-9p-device"
#define VIRTIO_9P(obj) \
- OBJECT_CHECK(V9fsState, (obj), TYPE_VIRTIO_9P)
+ OBJECT_CHECK(V9fsVirtioState, (obj), TYPE_VIRTIO_9P)
#endif
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 7ab8367baa..a526d2f2ae 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -210,7 +210,7 @@ VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch);
typedef struct V9fsCCWState {
VirtioCcwDevice parent_obj;
- V9fsState vdev;
+ V9fsVirtioState vdev;
} V9fsCCWState;
#endif /* CONFIG_VIRTFS */
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index a104ff2072..e096e989c0 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -23,7 +23,6 @@
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/virtio-balloon.h"
#include "hw/virtio/virtio-bus.h"
-#include "hw/virtio/virtio-9p.h"
#include "hw/virtio/virtio-input.h"
#include "hw/virtio/virtio-gpu.h"
#ifdef CONFIG_VIRTFS
@@ -243,7 +242,7 @@ struct VirtIONetPCI {
typedef struct V9fsPCIState {
VirtIOPCIProxy parent_obj;
- V9fsState vdev;
+ V9fsVirtioState vdev;
} V9fsPCIState;
#endif
diff --git a/include/hw/virtio/virtio-9p.h b/include/hw/virtio/virtio-9p.h
deleted file mode 100644
index 65789db131..0000000000
--- a/include/hw/virtio/virtio-9p.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Virtio 9p
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_VIRTIO_9P_DEVICE_H
-#define QEMU_VIRTIO_9P_DEVICE_H
-
-typedef struct V9fsConf
-{
- /* tag name for the device */
- char *tag;
- char *fsdev_id;
-} V9fsConf;
-
-#endif