VirtFS update:
Cleanups mostly isolating virtio related details into separate files. This is done to enable easy addition of Xen transport for VirtFS. The changes include: 1. Rename a bunch of files and functions to make clear they are generic. 2. disentangle virtio transport code and generic 9pfs code. 3. Some function name clean-up. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWlJdzAAoJEN5BpP4ExOI689QP/i4nPm/TFRlScnyXX6METu/E vDJv+9lWlJJ57len4MKDmGZYG+AbFzAY8BWtK4Ssr33aj/8GeNSq8u3rBJoE7SdJ BKQXAdP7mJRJOPh0WfCbeGaGa95hPzyOfZZs+IHXhulNFagraMrfWcNNdyNXsaw1 uhKZbB4QmM29vyj0Mp7/ynMP2WJbS2sxkoJDhOjelGxS0E2JdSE7UO0h6l2WUk5B OK7YdsaO8tge8/45ECD/veIwOex55OeKHbZyQjgx0MK7QLhowEGNyY2r7wpjJB8Z xicGpY9/iY/YHqJhtKTa8vrs3tUlPl669u3QqNpXDGpwYMkNwfvyljx2tr3t1Nn5 KSxfkYzOsf9TUnf+maMlFVJkMMQWshxR7zfr26+Fo/O+PJKsoF6Jdr63V/p3yNH8 G8QoLhWv1sQfV15sFGUSjbTeIfhOAXPE+tYnAg3tn+PEFMoROUAxvDDMFYQzuVtZ IfzdhgFTQUVNzWxsa20pVSJ36+z+3TFzdEnTyRKixreZSkrvDJ62RfPgjtfbZkf+ Of+TUvDmHiUcIexBZJeQhu/VcsLwuEAxOtomfsOxfrYVTmFWAoAmFzFn5Q6dr9Sd XV7/L0ApTnkFlQ9d2NgNkIKeMyL2BXQbAYSRs3bCIcvoSWctRa/Zx/L+BTp+iGwy 3FrR2/jpdXKPeFmz+iZ7 =ZBhb -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kvaneesh/tags/for-upstream-signed' into staging VirtFS update: Cleanups mostly isolating virtio related details into separate files. This is done to enable easy addition of Xen transport for VirtFS. The changes include: 1. Rename a bunch of files and functions to make clear they are generic. 2. disentangle virtio transport code and generic 9pfs code. 3. Some function name clean-up. # gpg: Signature made Tue 12 Jan 2016 06:04:35 GMT using RSA key ID 04C4E23A # gpg: Good signature from "Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 4846 9DE7 1860 360F A6E9 968C DE41 A4FE 04C4 E23A * remotes/kvaneesh/tags/for-upstream-signed: (25 commits) 9pfs: introduce V9fsVirtioState 9pfs: factor out v9fs_device_{,un}realize_common 9pfs: rename virtio-9p.c to 9p.c 9pfs: rename virtio_9p_set_fd_limit to use v9fs_ prefix 9pfs: move handle_9p_output and make it static function 9pfs: export pdu_{submit,alloc,free} 9pfs: factor out virtio_9p_push_and_notify 9pfs: break out 9p.h from virtio-9p.h 9pfs: break out virtio_init_iov_from_pdu 9pfs: factor out pdu_push_and_notify 9pfs: factor out virtio_pdu_{,un}marshal 9pfs: make pdu_{,un}marshal proper functions 9pfs: PDU processing functions should start pdu_ prefix 9pfs: PDU processing functions don't need to take V9fsState as argument fsdev: rename virtio-9p-marshal.{c,h} to 9p-iov-marshal.{c,h} fsdev: break out 9p-marshal.{c,h} from virtio-9p-marshal.{c,h} 9pfs: remove dead code 9pfs: merge hw/virtio/virtio-9p.h into hw/9pfs/virtio-9p.h 9pfs: rename virtio-9p-xattr{,-user}.{c,h} to 9p-xattr{,-user}.{c,h} 9pfs: rename virtio-9p-synth.{c,h} to 9p-synth.{c,h} ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
649a1bbaf9
2
Makefile
2
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
|
||||
|
@ -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, ...)
|
||||
{
|
||||
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;
|
||||
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': {
|
||||
@ -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;
|
||||
}
|
18
fsdev/9p-iov-marshal.h
Normal file
18
fsdev/9p-iov-marshal.h
Normal file
@ -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
|
56
fsdev/9p-marshal.c
Normal file
56
fsdev/9p-marshal.c
Normal file
@ -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);
|
||||
}
|
@ -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
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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>
|
@ -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>
|
@ -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"
|
@ -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;
|
@ -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;
|
@ -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>
|
@ -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>
|
@ -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,
|
@ -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,
|
@ -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"
|
||||
|
@ -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;
|
||||
|
||||
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;
|
||||
|
||||
pdu->s = s;
|
||||
BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0);
|
||||
QEMU_BUILD_BUG_ON(sizeof out != 7);
|
||||
|
||||
len = iov_to_buf(pdu->elem.out_sg, pdu->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);
|
||||
submit_pdu(s, pdu);
|
||||
/* 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;
|
||||
}
|
||||
free_pdu(s, pdu);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
s->tag = g_strdup(s->fsconf.tag);
|
||||
s->ctx.uid = -1;
|
||||
|
||||
s->ops = fse->ops;
|
||||
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
|
||||
rc = 0;
|
||||
out:
|
||||
if (rc) {
|
||||
g_free(s->ctx.fs_root);
|
||||
g_free(s->tag);
|
||||
v9fs_path_free(&path);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __attribute__((__constructor__)) virtio_9p_set_fd_limit(void)
|
||||
void v9fs_device_unrealize_common(V9fsState *s, Error **errp)
|
||||
{
|
||||
g_free(s->ctx.fs_root);
|
||||
g_free(s->tag);
|
||||
}
|
||||
|
||||
static void __attribute__((__constructor__)) v9fs_set_fd_limit(void)
|
||||
{
|
||||
struct rlimit rlim;
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
326
hw/9pfs/9p.h
Normal file
326
hw/9pfs/9p.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
@ -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"
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
V9fsVirtioState *v = VIRTIO_9P(dev);
|
||||
V9fsState *s = &v->state;
|
||||
|
||||
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");
|
||||
if (v9fs_device_realize_common(s, errp)) {
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
V9fsPDU pdus[MAX_REQ];
|
||||
VirtQueueElement elems[MAX_REQ];
|
||||
V9fsState state;
|
||||
} V9fsVirtioState;
|
||||
|
||||
typedef struct V9fsStatState {
|
||||
V9fsPDU *pdu;
|
||||
size_t offset;
|
||||
V9fsStat v9stat;
|
||||
V9fsFidState *fidp;
|
||||
struct stat stbuf;
|
||||
} V9fsStatState;
|
||||
extern void virtio_9p_push_and_notify(V9fsPDU *pdu);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
#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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user