aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/cofile.c24
-rw-r--r--hw/9pfs/cofs.c2
-rw-r--r--hw/9pfs/virtio-9p-coth.h3
-rw-r--r--hw/9pfs/virtio-9p-debug.c646
-rw-r--r--hw/9pfs/virtio-9p-debug.h6
-rw-r--r--hw/9pfs/virtio-9p-device.c70
-rw-r--r--hw/9pfs/virtio-9p-handle.c120
-rw-r--r--hw/9pfs/virtio-9p-local.c126
-rw-r--r--hw/9pfs/virtio-9p.c170
-rw-r--r--hw/9pfs/virtio-9p.h35
-rw-r--r--hw/virtio-pci.c5
-rw-r--r--hw/virtio-pci.h5
12 files changed, 439 insertions, 773 deletions
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 7ad4bec005..692811e5ab 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -17,6 +17,30 @@
#include "qemu-coroutine.h"
#include "virtio-9p-coth.h"
+int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
+ V9fsStatDotl *v9stat)
+{
+ int err = 0;
+ V9fsState *s = pdu->s;
+
+ if (v9fs_request_cancelled(pdu)) {
+ return -EINTR;
+ }
+ if (s->ctx.exops.get_st_gen) {
+ v9fs_path_read_lock(s);
+ v9fs_co_run_in_worker(
+ {
+ err = s->ctx.exops.get_st_gen(&s->ctx, path, st_mode,
+ &v9stat->st_gen);
+ if (err < 0) {
+ err = -errno;
+ }
+ });
+ v9fs_path_unlock(s);
+ }
+ return err;
+}
+
int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf)
{
int err;
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 68745add1e..83f125bd47 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -323,7 +323,7 @@ int v9fs_co_name_to_path(V9fsPDU *pdu, V9fsPath *dirpath,
int err;
V9fsState *s = pdu->s;
- if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+ if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
err = s->ops->name_to_path(&s->ctx, dirpath, name, path);
if (err < 0) {
err = -errno;
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 4630080e53..ca96b9cf2f 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -101,4 +101,7 @@ extern int v9fs_co_preadv(V9fsPDU *, V9fsFidState *,
struct iovec *, int, int64_t);
extern int v9fs_co_name_to_path(V9fsPDU *, V9fsPath *,
const char *, V9fsPath *);
+extern int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t,
+ V9fsStatDotl *v9stat);
+
#endif
diff --git a/hw/9pfs/virtio-9p-debug.c b/hw/9pfs/virtio-9p-debug.c
deleted file mode 100644
index 96925f04a4..0000000000
--- a/hw/9pfs/virtio-9p-debug.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Virtio 9p PDU debug
- *
- * 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 "hw/virtio.h"
-#include "hw/pc.h"
-#include "virtio-9p.h"
-#include "virtio-9p-debug.h"
-
-#define BUG_ON(cond) assert(!(cond))
-
-static FILE *llogfile;
-
-static struct iovec *get_sg(V9fsPDU *pdu, int rx)
-{
- if (rx) {
- return pdu->elem.in_sg;
- }
- return pdu->elem.out_sg;
-}
-
-static int get_sg_count(V9fsPDU *pdu, int rx)
-{
- if (rx) {
- return pdu->elem.in_num;
- }
- return pdu->elem.out_num;
-
-}
-
-static void pprint_int8(V9fsPDU *pdu, int rx, size_t *offsetp,
- const char *name)
-{
- size_t copied;
- int count = get_sg_count(pdu, rx);
- size_t offset = *offsetp;
- struct iovec *sg = get_sg(pdu, rx);
- int8_t value;
-
- copied = do_pdu_unpack(&value, sg, count, offset, sizeof(value));
-
- BUG_ON(copied != sizeof(value));
- offset += sizeof(value);
- fprintf(llogfile, "%s=0x%x", name, value);
- *offsetp = offset;
-}
-
-static void pprint_int16(V9fsPDU *pdu, int rx, size_t *offsetp,
- const char *name)
-{
- size_t copied;
- int count = get_sg_count(pdu, rx);
- struct iovec *sg = get_sg(pdu, rx);
- size_t offset = *offsetp;
- int16_t value;
-
-
- copied = do_pdu_unpack(&value, sg, count, offset, sizeof(value));
-
- BUG_ON(copied != sizeof(value));
- offset += sizeof(value);
- fprintf(llogfile, "%s=0x%x", name, value);
- *offsetp = offset;
-}
-
-static void pprint_int32(V9fsPDU *pdu, int rx, size_t *offsetp,
- const char *name)
-{
- size_t copied;
- int count = get_sg_count(pdu, rx);
- struct iovec *sg = get_sg(pdu, rx);
- size_t offset = *offsetp;
- int32_t value;
-
-
- copied = do_pdu_unpack(&value, sg, count, offset, sizeof(value));
-
- BUG_ON(copied != sizeof(value));
- offset += sizeof(value);
- fprintf(llogfile, "%s=0x%x", name, value);
- *offsetp = offset;
-}
-
-static void pprint_int64(V9fsPDU *pdu, int rx, size_t *offsetp,
- const char *name)
-{
- size_t copied;
- int count = get_sg_count(pdu, rx);
- struct iovec *sg = get_sg(pdu, rx);
- size_t offset = *offsetp;
- int64_t value;
-
-
- copied = do_pdu_unpack(&value, sg, count, offset, sizeof(value));
-
- BUG_ON(copied != sizeof(value));
- offset += sizeof(value);
- fprintf(llogfile, "%s=0x%" PRIx64, name, value);
- *offsetp = offset;
-}
-
-static void pprint_str(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name)
-{
- int sg_count = get_sg_count(pdu, rx);
- struct iovec *sg = get_sg(pdu, rx);
- size_t offset = *offsetp;
- uint16_t tmp_size, size;
- size_t result;
- size_t copied = 0;
- int i = 0;
-
- /* get the size */
- copied = do_pdu_unpack(&tmp_size, sg, sg_count, offset, sizeof(tmp_size));
- BUG_ON(copied != sizeof(tmp_size));
- size = le16_to_cpupu(&tmp_size);
- offset += copied;
-
- fprintf(llogfile, "%s=", name);
- for (i = 0; size && i < sg_count; i++) {
- size_t len;
- if (offset >= sg[i].iov_len) {
- /* skip this sg */
- offset -= sg[i].iov_len;
- continue;
- } else {
- len = MIN(sg[i].iov_len - offset, size);
- result = fwrite(sg[i].iov_base + offset, 1, len, llogfile);
- BUG_ON(result != len);
- size -= len;
- copied += len;
- if (size) {
- offset = 0;
- continue;
- }
- }
- }
- *offsetp += copied;
-}
-
-static void pprint_qid(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name)
-{
- fprintf(llogfile, "%s={", name);
- pprint_int8(pdu, rx, offsetp, "type");
- pprint_int32(pdu, rx, offsetp, ", version");
- pprint_int64(pdu, rx, offsetp, ", path");
- fprintf(llogfile, "}");
-}
-
-static void pprint_stat(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name)
-{
- fprintf(llogfile, "%s={", name);
- pprint_int16(pdu, rx, offsetp, "size");
- pprint_int16(pdu, rx, offsetp, ", type");
- pprint_int32(pdu, rx, offsetp, ", dev");
- pprint_qid(pdu, rx, offsetp, ", qid");
- pprint_int32(pdu, rx, offsetp, ", mode");
- pprint_int32(pdu, rx, offsetp, ", atime");
- pprint_int32(pdu, rx, offsetp, ", mtime");
- pprint_int64(pdu, rx, offsetp, ", length");
- pprint_str(pdu, rx, offsetp, ", name");
- pprint_str(pdu, rx, offsetp, ", uid");
- pprint_str(pdu, rx, offsetp, ", gid");
- pprint_str(pdu, rx, offsetp, ", muid");
- pprint_str(pdu, rx, offsetp, ", extension");
- pprint_int32(pdu, rx, offsetp, ", uid");
- pprint_int32(pdu, rx, offsetp, ", gid");
- pprint_int32(pdu, rx, offsetp, ", muid");
- fprintf(llogfile, "}");
-}
-
-static void pprint_stat_dotl(V9fsPDU *pdu, int rx, size_t *offsetp,
- const char *name)
-{
- fprintf(llogfile, "%s={", name);
- pprint_qid(pdu, rx, offsetp, "qid");
- pprint_int32(pdu, rx, offsetp, ", st_mode");
- pprint_int64(pdu, rx, offsetp, ", st_nlink");
- pprint_int32(pdu, rx, offsetp, ", st_uid");
- pprint_int32(pdu, rx, offsetp, ", st_gid");
- pprint_int64(pdu, rx, offsetp, ", st_rdev");
- pprint_int64(pdu, rx, offsetp, ", st_size");
- pprint_int64(pdu, rx, offsetp, ", st_blksize");
- pprint_int64(pdu, rx, offsetp, ", st_blocks");
- pprint_int64(pdu, rx, offsetp, ", atime");
- pprint_int64(pdu, rx, offsetp, ", atime_nsec");
- pprint_int64(pdu, rx, offsetp, ", mtime");
- pprint_int64(pdu, rx, offsetp, ", mtime_nsec");
- pprint_int64(pdu, rx, offsetp, ", ctime");
- pprint_int64(pdu, rx, offsetp, ", ctime_nsec");
- fprintf(llogfile, "}");
-}
-
-
-
-static void pprint_strs(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name)
-{
- int sg_count = get_sg_count(pdu, rx);
- struct iovec *sg = get_sg(pdu, rx);
- size_t offset = *offsetp;
- uint16_t tmp_count, count, i;
- size_t copied = 0;
-
- fprintf(llogfile, "%s={", name);
-
- /* Get the count */
- copied = do_pdu_unpack(&tmp_count, sg, sg_count, offset, sizeof(tmp_count));
- BUG_ON(copied != sizeof(tmp_count));
- count = le16_to_cpupu(&tmp_count);
- offset += copied;
-
- for (i = 0; i < count; i++) {
- char str[512];
- if (i) {
- fprintf(llogfile, ", ");
- }
- snprintf(str, sizeof(str), "[%d]", i);
- pprint_str(pdu, rx, &offset, str);
- }
-
- fprintf(llogfile, "}");
-
- *offsetp = offset;
-}
-
-static void pprint_qids(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name)
-{
- int sg_count = get_sg_count(pdu, rx);
- struct iovec *sg = get_sg(pdu, rx);
- size_t offset = *offsetp;
- uint16_t tmp_count, count, i;
- size_t copied = 0;
-
- fprintf(llogfile, "%s={", name);
-
- copied = do_pdu_unpack(&tmp_count, sg, sg_count, offset, sizeof(tmp_count));
- BUG_ON(copied != sizeof(tmp_count));
- count = le16_to_cpupu(&tmp_count);
- offset += copied;
-
- for (i = 0; i < count; i++) {
- char str[512];
- if (i) {
- fprintf(llogfile, ", ");
- }
- snprintf(str, sizeof(str), "[%d]", i);
- pprint_qid(pdu, rx, &offset, str);
- }
-
- fprintf(llogfile, "}");
-
- *offsetp = offset;
-}
-
-static void pprint_sg(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name)
-{
- struct iovec *sg = get_sg(pdu, rx);
- unsigned int count;
- int i;
-
- if (rx) {
- count = pdu->elem.in_num;
- } else {
- count = pdu->elem.out_num;
- }
-
- fprintf(llogfile, "%s={", name);
- for (i = 0; i < count; i++) {
- if (i) {
- fprintf(llogfile, ", ");
- }
- fprintf(llogfile, "(%p, 0x%zx)", sg[i].iov_base, sg[i].iov_len);
- }
- fprintf(llogfile, "}");
-}
-
-/* FIXME: read from a directory fid returns serialized stat_t's */
-#ifdef DEBUG_DATA
-static void pprint_data(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name)
-{
- struct iovec *sg = get_sg(pdu, rx);
- size_t offset = *offsetp;
- unsigned int count;
- int32_t size;
- int total, i, j;
- ssize_t len;
-
- if (rx) {
- count = pdu->elem.in_num;
- } else {
- count = pdu->elem.out_num;
- }
-
- BUG_ON((offset + sizeof(size)) > sg[0].iov_len);
-
- memcpy(&size, sg[0].iov_base + offset, sizeof(size));
- offset += sizeof(size);
-
- fprintf(llogfile, "size: %x\n", size);
-
- sg[0].iov_base += 11; /* skip header */
- sg[0].iov_len -= 11;
-
- total = 0;
- for (i = 0; i < count; i++) {
- total += sg[i].iov_len;
- if (total >= size) {
- /* trim sg list so writev does the right thing */
- sg[i].iov_len -= (total - size);
- i++;
- break;
- }
- }
-
- fprintf(llogfile, "%s={\"", name);
- fflush(llogfile);
- for (j = 0; j < i; j++) {
- if (j) {
- fprintf(llogfile, "\", \"");
- fflush(llogfile);
- }
-
- do {
- len = writev(fileno(llogfile), &sg[j], 1);
- } while (len == -1 && errno == EINTR);
- fprintf(llogfile, "len == %ld: %m\n", len);
- BUG_ON(len != sg[j].iov_len);
- }
- fprintf(llogfile, "\"}");
-
- sg[0].iov_base -= 11;
- sg[0].iov_len += 11;
-
-}
-#endif
-
-void pprint_pdu(V9fsPDU *pdu)
-{
- size_t offset = 7;
-
- if (llogfile == NULL) {
- llogfile = fopen("/tmp/pdu.log", "w");
- }
-
- BUG_ON(!llogfile);
-
- switch (pdu->id) {
- case P9_TREADDIR:
- fprintf(llogfile, "TREADDIR: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_int64(pdu, 0, &offset, ", initial offset");
- pprint_int32(pdu, 0, &offset, ", max count");
- break;
- case P9_RREADDIR:
- fprintf(llogfile, "RREADDIR: (");
- pprint_int32(pdu, 1, &offset, "count");
-#ifdef DEBUG_DATA
- pprint_data(pdu, 1, &offset, ", data");
-#endif
- break;
- case P9_TMKDIR:
- fprintf(llogfile, "TMKDIR: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_str(pdu, 0, &offset, "name");
- pprint_int32(pdu, 0, &offset, "mode");
- pprint_int32(pdu, 0, &offset, "gid");
- break;
- case P9_RMKDIR:
- fprintf(llogfile, "RMKDIR: (");
- pprint_qid(pdu, 0, &offset, "qid");
- break;
- case P9_TVERSION:
- fprintf(llogfile, "TVERSION: (");
- pprint_int32(pdu, 0, &offset, "msize");
- pprint_str(pdu, 0, &offset, ", version");
- break;
- case P9_RVERSION:
- fprintf(llogfile, "RVERSION: (");
- pprint_int32(pdu, 1, &offset, "msize");
- pprint_str(pdu, 1, &offset, ", version");
- break;
- case P9_TGETATTR:
- fprintf(llogfile, "TGETATTR: (");
- pprint_int32(pdu, 0, &offset, "fid");
- break;
- case P9_RGETATTR:
- fprintf(llogfile, "RGETATTR: (");
- pprint_stat_dotl(pdu, 1, &offset, "getattr");
- break;
- case P9_TAUTH:
- fprintf(llogfile, "TAUTH: (");
- pprint_int32(pdu, 0, &offset, "afid");
- pprint_str(pdu, 0, &offset, ", uname");
- pprint_str(pdu, 0, &offset, ", aname");
- pprint_int32(pdu, 0, &offset, ", n_uname");
- break;
- case P9_RAUTH:
- fprintf(llogfile, "RAUTH: (");
- pprint_qid(pdu, 1, &offset, "qid");
- break;
- case P9_TATTACH:
- fprintf(llogfile, "TATTACH: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_int32(pdu, 0, &offset, ", afid");
- pprint_str(pdu, 0, &offset, ", uname");
- pprint_str(pdu, 0, &offset, ", aname");
- pprint_int32(pdu, 0, &offset, ", n_uname");
- break;
- case P9_RATTACH:
- fprintf(llogfile, "RATTACH: (");
- pprint_qid(pdu, 1, &offset, "qid");
- break;
- case P9_TERROR:
- fprintf(llogfile, "TERROR: (");
- break;
- case P9_RERROR:
- fprintf(llogfile, "RERROR: (");
- pprint_str(pdu, 1, &offset, "ename");
- pprint_int32(pdu, 1, &offset, ", ecode");
- break;
- case P9_TFLUSH:
- fprintf(llogfile, "TFLUSH: (");
- pprint_int16(pdu, 0, &offset, "oldtag");
- break;
- case P9_RFLUSH:
- fprintf(llogfile, "RFLUSH: (");
- break;
- case P9_TWALK:
- fprintf(llogfile, "TWALK: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_int32(pdu, 0, &offset, ", newfid");
- pprint_strs(pdu, 0, &offset, ", wnames");
- break;
- case P9_RWALK:
- fprintf(llogfile, "RWALK: (");
- pprint_qids(pdu, 1, &offset, "wqids");
- break;
- case P9_TOPEN:
- fprintf(llogfile, "TOPEN: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_int8(pdu, 0, &offset, ", mode");
- break;
- case P9_ROPEN:
- fprintf(llogfile, "ROPEN: (");
- pprint_qid(pdu, 1, &offset, "qid");
- pprint_int32(pdu, 1, &offset, ", iounit");
- break;
- case P9_TCREATE:
- fprintf(llogfile, "TCREATE: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_str(pdu, 0, &offset, ", name");
- pprint_int32(pdu, 0, &offset, ", perm");
- pprint_int8(pdu, 0, &offset, ", mode");
- pprint_str(pdu, 0, &offset, ", extension");
- break;
- case P9_RCREATE:
- fprintf(llogfile, "RCREATE: (");
- pprint_qid(pdu, 1, &offset, "qid");
- pprint_int32(pdu, 1, &offset, ", iounit");
- break;
- case P9_TSYMLINK:
- fprintf(llogfile, "TSYMLINK: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_str(pdu, 0, &offset, ", name");
- pprint_str(pdu, 0, &offset, ", symname");
- pprint_int32(pdu, 0, &offset, ", gid");
- break;
- case P9_RSYMLINK:
- fprintf(llogfile, "RSYMLINK: (");
- pprint_qid(pdu, 1, &offset, "qid");
- break;
- case P9_TLCREATE:
- fprintf(llogfile, "TLCREATE: (");
- pprint_int32(pdu, 0, &offset, "dfid");
- pprint_str(pdu, 0, &offset, ", name");
- pprint_int32(pdu, 0, &offset, ", flags");
- pprint_int32(pdu, 0, &offset, ", mode");
- pprint_int32(pdu, 0, &offset, ", gid");
- break;
- case P9_RLCREATE:
- fprintf(llogfile, "RLCREATE: (");
- pprint_qid(pdu, 1, &offset, "qid");
- pprint_int32(pdu, 1, &offset, ", iounit");
- break;
- case P9_TMKNOD:
- fprintf(llogfile, "TMKNOD: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_str(pdu, 0, &offset, "name");
- pprint_int32(pdu, 0, &offset, "mode");
- pprint_int32(pdu, 0, &offset, "major");
- pprint_int32(pdu, 0, &offset, "minor");
- pprint_int32(pdu, 0, &offset, "gid");
- break;
- case P9_RMKNOD:
- fprintf(llogfile, "RMKNOD: )");
- pprint_qid(pdu, 0, &offset, "qid");
- break;
- case P9_TREADLINK:
- fprintf(llogfile, "TREADLINK: (");
- pprint_int32(pdu, 0, &offset, "fid");
- break;
- case P9_RREADLINK:
- fprintf(llogfile, "RREADLINK: (");
- pprint_str(pdu, 0, &offset, "target");
- break;
- case P9_TREAD:
- fprintf(llogfile, "TREAD: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_int64(pdu, 0, &offset, ", offset");
- pprint_int32(pdu, 0, &offset, ", count");
- pprint_sg(pdu, 0, &offset, ", sg");
- break;
- case P9_RREAD:
- fprintf(llogfile, "RREAD: (");
- pprint_int32(pdu, 1, &offset, "count");
- pprint_sg(pdu, 1, &offset, ", sg");
- offset = 7;
-#ifdef DEBUG_DATA
- pprint_data(pdu, 1, &offset, ", data");
-#endif
- break;
- case P9_TWRITE:
- fprintf(llogfile, "TWRITE: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_int64(pdu, 0, &offset, ", offset");
- pprint_int32(pdu, 0, &offset, ", count");
- break;
- case P9_RWRITE:
- fprintf(llogfile, "RWRITE: (");
- pprint_int32(pdu, 1, &offset, "count");
- break;
- case P9_TCLUNK:
- fprintf(llogfile, "TCLUNK: (");
- pprint_int32(pdu, 0, &offset, "fid");
- break;
- case P9_RCLUNK:
- fprintf(llogfile, "RCLUNK: (");
- break;
- case P9_TFSYNC:
- fprintf(llogfile, "TFSYNC: (");
- pprint_int32(pdu, 0, &offset, "fid");
- break;
- case P9_RFSYNC:
- fprintf(llogfile, "RFSYNC: (");
- break;
- case P9_TLINK:
- fprintf(llogfile, "TLINK: (");
- pprint_int32(pdu, 0, &offset, "dfid");
- pprint_int32(pdu, 0, &offset, ", fid");
- pprint_str(pdu, 0, &offset, ", newpath");
- break;
- case P9_RLINK:
- fprintf(llogfile, "RLINK: (");
- break;
- case P9_TREMOVE:
- fprintf(llogfile, "TREMOVE: (");
- pprint_int32(pdu, 0, &offset, "fid");
- break;
- case P9_RREMOVE:
- fprintf(llogfile, "RREMOVE: (");
- break;
- case P9_TSTAT:
- fprintf(llogfile, "TSTAT: (");
- pprint_int32(pdu, 0, &offset, "fid");
- break;
- case P9_RSTAT:
- fprintf(llogfile, "RSTAT: (");
- offset += 2; /* ignored */
- pprint_stat(pdu, 1, &offset, "stat");
- break;
- case P9_TWSTAT:
- fprintf(llogfile, "TWSTAT: (");
- pprint_int32(pdu, 0, &offset, "fid");
- offset += 2; /* ignored */
- pprint_stat(pdu, 0, &offset, ", stat");
- break;
- case P9_RWSTAT:
- fprintf(llogfile, "RWSTAT: (");
- break;
- case P9_TXATTRWALK:
- fprintf(llogfile, "TXATTRWALK: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_int32(pdu, 0, &offset, ", newfid");
- pprint_str(pdu, 0, &offset, ", xattr name");
- break;
- case P9_RXATTRWALK:
- fprintf(llogfile, "RXATTRWALK: (");
- pprint_int64(pdu, 1, &offset, "xattrsize");
- case P9_TXATTRCREATE:
- fprintf(llogfile, "TXATTRCREATE: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_str(pdu, 0, &offset, ", name");
- pprint_int64(pdu, 0, &offset, ", xattrsize");
- pprint_int32(pdu, 0, &offset, ", flags");
- break;
- case P9_RXATTRCREATE:
- fprintf(llogfile, "RXATTRCREATE: (");
- break;
- case P9_TLOCK:
- fprintf(llogfile, "TLOCK: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_int8(pdu, 0, &offset, ", type");
- pprint_int32(pdu, 0, &offset, ", flags");
- pprint_int64(pdu, 0, &offset, ", start");
- pprint_int64(pdu, 0, &offset, ", length");
- pprint_int32(pdu, 0, &offset, ", proc_id");
- pprint_str(pdu, 0, &offset, ", client_id");
- break;
- case P9_RLOCK:
- fprintf(llogfile, "RLOCK: (");
- pprint_int8(pdu, 0, &offset, "status");
- break;
- case P9_TGETLOCK:
- fprintf(llogfile, "TGETLOCK: (");
- pprint_int32(pdu, 0, &offset, "fid");
- pprint_int8(pdu, 0, &offset, ", type");
- pprint_int64(pdu, 0, &offset, ", start");
- pprint_int64(pdu, 0, &offset, ", length");
- pprint_int32(pdu, 0, &offset, ", proc_id");
- pprint_str(pdu, 0, &offset, ", client_id");
- break;
- case P9_RGETLOCK:
- fprintf(llogfile, "RGETLOCK: (");
- pprint_int8(pdu, 0, &offset, "type");
- pprint_int64(pdu, 0, &offset, ", start");
- pprint_int64(pdu, 0, &offset, ", length");
- pprint_int32(pdu, 0, &offset, ", proc_id");
- pprint_str(pdu, 0, &offset, ", client_id");
- break;
- default:
- fprintf(llogfile, "unknown(%d): (", pdu->id);
- break;
- }
-
- fprintf(llogfile, ")\n");
- /* Flush the log message out */
- fflush(llogfile);
-}
diff --git a/hw/9pfs/virtio-9p-debug.h b/hw/9pfs/virtio-9p-debug.h
deleted file mode 100644
index d9a249118d..0000000000
--- a/hw/9pfs/virtio-9p-debug.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _QEMU_VIRTIO_9P_DEBUG_H
-#define _QEMU_VIRTIO_9P_DEBUG_H
-
-void pprint_pdu(V9fsPDU *pdu);
-
-#endif
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 513e181c82..bba4c54762 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -49,7 +49,8 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
V9fsState *s;
int i, len;
struct stat stat;
- FsTypeEntry *fse;
+ FsDriverEntry *fse;
+ V9fsPath path;
s = (V9fsState *)virtio_common_init("virtio-9p",
VIRTIO_ID_9P,
@@ -82,55 +83,33 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
exit(1);
}
- if (!strcmp(fse->security_model, "passthrough")) {
- /* Files on the Fileserver set to client user credentials */
- s->ctx.fs_sm = SM_PASSTHROUGH;
+ s->ctx.export_flags = fse->export_flags;
+ s->ctx.fs_root = g_strdup(fse->path);
+ s->ctx.exops.get_st_gen = NULL;
+
+ if (fse->export_flags & V9FS_SM_PASSTHROUGH) {
s->ctx.xops = passthrough_xattr_ops;
- } else if (!strcmp(fse->security_model, "mapped")) {
- /* Files on the fileserver are set to QEMU credentials.
- * Client user credentials are saved in extended attributes.
- */
- s->ctx.fs_sm = SM_MAPPED;
+ } else if (fse->export_flags & V9FS_SM_MAPPED) {
s->ctx.xops = mapped_xattr_ops;
- } else if (!strcmp(fse->security_model, "none")) {
- /*
- * Files on the fileserver are set to QEMU credentials.
- */
- s->ctx.fs_sm = SM_NONE;
- s->ctx.xops = none_xattr_ops;
- } else {
- fprintf(stderr, "Default to security_model=none. You may want"
- " enable advanced security model using "
- "security option:\n\t security_model=passthrough\n\t "
- "security_model=mapped\n");
- s->ctx.fs_sm = SM_NONE;
+ } else if (fse->export_flags & V9FS_SM_NONE) {
s->ctx.xops = none_xattr_ops;
}
- if (lstat(fse->path, &stat)) {
- fprintf(stderr, "share path %s does not exist\n", fse->path);
- exit(1);
- } else if (!S_ISDIR(stat.st_mode)) {
- fprintf(stderr, "share path %s is not a directory\n", fse->path);
- exit(1);
- }
-
- s->ctx.fs_root = g_strdup(fse->path);
len = strlen(conf->tag);
if (len > MAX_TAG_LEN) {
- len = MAX_TAG_LEN;
+ fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
+ "maximum (%d bytes)", conf->tag, len, MAX_TAG_LEN);
+ exit(1);
}
/* s->tag is non-NULL terminated string */
s->tag = g_malloc(len);
memcpy(s->tag, conf->tag, len);
s->tag_len = len;
s->ctx.uid = -1;
- s->ctx.flags = 0;
s->ops = fse->ops;
s->vdev.get_features = virtio_9p_get_features;
- s->config_size = sizeof(struct virtio_9p_config) +
- s->tag_len;
+ s->config_size = sizeof(struct virtio_9p_config) + s->tag_len;
s->vdev.get_config = virtio_9p_get_config;
s->fid_list = NULL;
qemu_co_rwlock_init(&s->rename_lock);
@@ -144,6 +123,27 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
fprintf(stderr, "worker thread initialization failed\n");
exit(1);
}
+
+ /*
+ * 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.
+ */
+ v9fs_path_init(&path);
+ if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
+ fprintf(stderr,
+ "error in converting name to path %s", strerror(errno));
+ exit(1);
+ }
+ if (s->ops->lstat(&s->ctx, &path, &stat)) {
+ fprintf(stderr, "share path %s does not exist\n", fse->path);
+ exit(1);
+ } else if (!S_ISDIR(stat.st_mode)) {
+ fprintf(stderr, "share path %s is not a directory\n", fse->path);
+ exit(1);
+ }
+ v9fs_path_free(&path);
+
return &s->vdev;
}
@@ -169,6 +169,8 @@ static PCIDeviceInfo virtio_9p_info = {
.revision = VIRTIO_PCI_ABI_VERSION,
.class_id = 0x2,
.qdev.props = (Property[]) {
+ DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
+ VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c
index 5c8b5ed471..98809f1642 100644
--- a/hw/9pfs/virtio-9p-handle.c
+++ b/hw/9pfs/virtio-9p-handle.c
@@ -21,49 +21,56 @@
#include <sys/un.h>
#include <attr/xattr.h>
#include <unistd.h>
-
-struct handle_data {
- int mountfd;
- int handle_bytes;
-};
-
-#if __GLIBC__ <= 2 && __GLIBC_MINOR__ < 14
-struct file_handle {
- unsigned int handle_bytes;
- int handle_type;
- unsigned char handle[0];
-};
+#include <linux/fs.h>
+#ifdef CONFIG_LINUX_MAGIC_H
+#include <linux/magic.h>
#endif
+#include <sys/ioctl.h>
-#ifndef AT_EMPTY_PATH
-#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
+#ifndef XFS_SUPER_MAGIC
+#define XFS_SUPER_MAGIC 0x58465342
#endif
-#ifndef O_PATH
-#define O_PATH 010000000
+#ifndef EXT2_SUPER_MAGIC
+#define EXT2_SUPER_MAGIC 0xEF53
#endif
-
-#ifndef __NR_name_to_handle_at
-#if defined(__i386__)
-#define __NR_name_to_handle_at 341
-#define __NR_open_by_handle_at 342
-#elif defined(__x86_64__)
-#define __NR_name_to_handle_at 303
-#define __NR_open_by_handle_at 304
+#ifndef REISERFS_SUPER_MAGIC
+#define REISERFS_SUPER_MAGIC 0x52654973
#endif
+#ifndef BTRFS_SUPER_MAGIC
+#define BTRFS_SUPER_MAGIC 0x9123683E
#endif
-#ifdef __NR_name_to_handle_at
+struct handle_data {
+ int mountfd;
+ int handle_bytes;
+};
+
+#ifdef CONFIG_OPEN_BY_HANDLE
static inline int name_to_handle(int dirfd, const char *name,
struct file_handle *fh, int *mnt_id, int flags)
{
- return syscall(__NR_name_to_handle_at, dirfd, name, fh, mnt_id, flags);
+ return name_to_handle_at(dirfd, name, fh, mnt_id, flags);
}
static inline int open_by_handle(int mountfd, const char *fh, int flags)
{
- return syscall(__NR_open_by_handle_at, mountfd, fh, flags);
+ return open_by_handle_at(mountfd, (struct file_handle *)fh, flags);
}
#else
+
+struct file_handle {
+ unsigned int handle_bytes;
+ int handle_type;
+ unsigned char handle[0];
+};
+
+#ifndef AT_EMPTY_PATH
+#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
+#endif
+#ifndef O_PATH
+#define O_PATH 010000000
+#endif
+
static inline int name_to_handle(int dirfd, const char *name,
struct file_handle *fh, int *mnt_id, int flags)
{
@@ -192,16 +199,29 @@ static ssize_t handle_preadv(FsContext *ctx, int fd, const struct iovec *iov,
static ssize_t handle_pwritev(FsContext *ctx, int fd, const struct iovec *iov,
int iovcnt, off_t offset)
{
+ ssize_t ret;
#ifdef CONFIG_PREADV
- return pwritev(fd, iov, iovcnt, offset);
+ ret = pwritev(fd, iov, iovcnt, offset);
#else
int err = lseek(fd, offset, SEEK_SET);
if (err == -1) {
return err;
} else {
- return writev(fd, iov, iovcnt);
+ ret = writev(fd, iov, iovcnt);
}
#endif
+#ifdef CONFIG_SYNC_FILE_RANGE
+ if (ret > 0 && ctx->export_flags & V9FS_IMMEDIATE_WRITEOUT) {
+ /*
+ * Initiate a writeback. This is not a data integrity sync.
+ * We want to ensure that we don't leave dirty pages in the cache
+ * after write when writeout=immediate is sepcified.
+ */
+ sync_file_range(fd, offset, ret,
+ SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE);
+ }
+#endif
+ return ret;
}
static int handle_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
@@ -367,7 +387,9 @@ static int handle_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
static int handle_utimensat(FsContext *ctx, V9fsPath *fs_path,
const struct timespec *buf)
{
- int fd, ret;
+ int ret;
+#ifdef CONFIG_UTIMENSAT
+ int fd;
struct handle_data *data = (struct handle_data *)ctx->private;
fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK);
@@ -376,6 +398,10 @@ static int handle_utimensat(FsContext *ctx, V9fsPath *fs_path,
}
ret = futimens(fd, buf);
close(fd);
+#else
+ ret = -1;
+ errno = ENOSYS;
+#endif
return ret;
}
@@ -546,16 +572,50 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir,
return ret;
}
+static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
+ mode_t st_mode, uint64_t *st_gen)
+{
+ int err, fd;
+
+ /*
+ * Do not try to open special files like device nodes, fifos etc
+ * We can get fd for regular files and directories only
+ */
+ if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
+ return 0;
+ }
+ fd = handle_open(ctx, path, O_RDONLY);
+ if (fd < 0) {
+ return fd;
+ }
+ err = ioctl(fd, FS_IOC_GETVERSION, st_gen);
+ handle_close(ctx, fd);
+ return err;
+}
+
static int handle_init(FsContext *ctx)
{
int ret, mnt_id;
+ struct statfs stbuf;
struct file_handle fh;
struct handle_data *data = g_malloc(sizeof(struct handle_data));
+
data->mountfd = open(ctx->fs_root, O_DIRECTORY);
if (data->mountfd < 0) {
ret = data->mountfd;
goto err_out;
}
+ ret = statfs(ctx->fs_root, &stbuf);
+ if (!ret) {
+ switch (stbuf.f_type) {
+ case EXT2_SUPER_MAGIC:
+ case BTRFS_SUPER_MAGIC:
+ case REISERFS_SUPER_MAGIC:
+ case XFS_SUPER_MAGIC:
+ ctx->exops.get_st_gen = handle_ioc_getversion;
+ break;
+ }
+ }
memset(&fh, 0, sizeof(struct file_handle));
ret = name_to_handle(data->mountfd, ".", &fh, &mnt_id, 0);
if (ret && errno == EOVERFLOW) {
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 9559ff6550..d561de88f0 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -20,6 +20,24 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <attr/xattr.h>
+#include <linux/fs.h>
+#ifdef CONFIG_LINUX_MAGIC_H
+#include <linux/magic.h>
+#endif
+#include <sys/ioctl.h>
+
+#ifndef XFS_SUPER_MAGIC
+#define XFS_SUPER_MAGIC 0x58465342
+#endif
+#ifndef EXT2_SUPER_MAGIC
+#define EXT2_SUPER_MAGIC 0xEF53
+#endif
+#ifndef REISERFS_SUPER_MAGIC
+#define REISERFS_SUPER_MAGIC 0x52654973
+#endif
+#ifndef BTRFS_SUPER_MAGIC
+#define BTRFS_SUPER_MAGIC 0x9123683E
+#endif
static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
{
@@ -31,7 +49,7 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
if (err) {
return err;
}
- if (fs_ctx->fs_sm == SM_MAPPED) {
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
/* Actual credentials are part of extended attrs */
uid_t tmp_uid;
gid_t tmp_gid;
@@ -106,7 +124,7 @@ static int local_post_create_passthrough(FsContext *fs_ctx, const char *path,
* If we fail to change ownership and if we are
* using security model none. Ignore the error
*/
- if (fs_ctx->fs_sm != SM_NONE) {
+ if ((fs_ctx->export_flags & V9FS_SEC_MASK) != V9FS_SM_NONE) {
return -1;
}
}
@@ -120,7 +138,7 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
char buffer[PATH_MAX];
char *path = fs_path->data;
- if (fs_ctx->fs_sm == SM_MAPPED) {
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
int fd;
fd = open(rpath(fs_ctx, path, buffer), O_RDONLY);
if (fd == -1) {
@@ -131,8 +149,8 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
} while (tsize == -1 && errno == EINTR);
close(fd);
return tsize;
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
+ } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+ (fs_ctx->export_flags & V9FS_SM_NONE)) {
tsize = readlink(rpath(fs_ctx, path, buffer), buf, bufsz);
}
return tsize;
@@ -203,16 +221,30 @@ static ssize_t local_preadv(FsContext *ctx, int fd, const struct iovec *iov,
static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov,
int iovcnt, off_t offset)
{
+ ssize_t ret
+;
#ifdef CONFIG_PREADV
- return pwritev(fd, iov, iovcnt, offset);
+ ret = pwritev(fd, iov, iovcnt, offset);
#else
int err = lseek(fd, offset, SEEK_SET);
if (err == -1) {
return err;
} else {
- return writev(fd, iov, iovcnt);
+ ret = writev(fd, iov, iovcnt);
}
#endif
+#ifdef CONFIG_SYNC_FILE_RANGE
+ if (ret > 0 && ctx->export_flags & V9FS_IMMEDIATE_WRITEOUT) {
+ /*
+ * Initiate a writeback. This is not a data integrity sync.
+ * We want to ensure that we don't leave dirty pages in the cache
+ * after write when writeout=immediate is sepcified.
+ */
+ sync_file_range(fd, offset, ret,
+ SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE);
+ }
+#endif
+ return ret;
}
static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
@@ -220,10 +252,10 @@ static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
char buffer[PATH_MAX];
char *path = fs_path->data;
- if (fs_ctx->fs_sm == SM_MAPPED) {
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
return local_set_xattr(rpath(fs_ctx, path, buffer), credp);
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
+ } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+ (fs_ctx->export_flags & V9FS_SM_NONE)) {
return chmod(rpath(fs_ctx, path, buffer), credp->fc_mode);
}
return -1;
@@ -243,7 +275,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
path = fullname.data;
/* Determine the security model */
- if (fs_ctx->fs_sm == SM_MAPPED) {
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
err = mknod(rpath(fs_ctx, path, buffer),
SM_LOCAL_MODE_BITS|S_IFREG, 0);
if (err == -1) {
@@ -254,8 +286,8 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
serrno = errno;
goto err_end;
}
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
+ } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+ (fs_ctx->export_flags & V9FS_SM_NONE)) {
err = mknod(rpath(fs_ctx, path, buffer), credp->fc_mode,
credp->fc_rdev);
if (err == -1) {
@@ -291,7 +323,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
path = fullname.data;
/* Determine the security model */
- if (fs_ctx->fs_sm == SM_MAPPED) {
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
err = mkdir(rpath(fs_ctx, path, buffer), SM_LOCAL_DIR_MODE_BITS);
if (err == -1) {
goto out;
@@ -302,8 +334,8 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
serrno = errno;
goto err_end;
}
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
+ } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+ (fs_ctx->export_flags & V9FS_SM_NONE)) {
err = mkdir(rpath(fs_ctx, path, buffer), credp->fc_mode);
if (err == -1) {
goto out;
@@ -331,7 +363,7 @@ static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf)
if (err) {
return err;
}
- if (fs_ctx->fs_sm == SM_MAPPED) {
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
/* Actual credentials are part of extended attrs */
uid_t tmp_uid;
gid_t tmp_gid;
@@ -369,7 +401,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
path = fullname.data;
/* Determine the security model */
- if (fs_ctx->fs_sm == SM_MAPPED) {
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
fd = open(rpath(fs_ctx, path, buffer), flags, SM_LOCAL_MODE_BITS);
if (fd == -1) {
err = fd;
@@ -382,8 +414,8 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
serrno = errno;
goto err_end;
}
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
+ } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+ (fs_ctx->export_flags & V9FS_SM_NONE)) {
fd = open(rpath(fs_ctx, path, buffer), flags, credp->fc_mode);
if (fd == -1) {
err = fd;
@@ -422,7 +454,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
newpath = fullname.data;
/* Determine the security model */
- if (fs_ctx->fs_sm == SM_MAPPED) {
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
int fd;
ssize_t oldpath_size, write_size;
fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,
@@ -451,8 +483,8 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
serrno = errno;
goto err_end;
}
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
+ } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+ (fs_ctx->export_flags & V9FS_SM_NONE)) {
err = symlink(oldpath, rpath(fs_ctx, newpath, buffer));
if (err) {
goto out;
@@ -464,7 +496,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
* If we fail to change ownership and if we are
* using security model none. Ignore the error
*/
- if (fs_ctx->fs_sm != SM_NONE) {
+ if ((fs_ctx->export_flags & V9FS_SEC_MASK) != V9FS_SM_NONE) {
serrno = errno;
goto err_end;
} else
@@ -519,13 +551,13 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
char *path = fs_path->data;
if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
- (fs_ctx->fs_sm == SM_PASSTHROUGH)) {
+ (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH)) {
return lchown(rpath(fs_ctx, path, buffer), credp->fc_uid,
credp->fc_gid);
- } else if (fs_ctx->fs_sm == SM_MAPPED) {
+ } else if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
return local_set_xattr(rpath(fs_ctx, path, buffer), credp);
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
+ } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+ (fs_ctx->export_flags & V9FS_SM_NONE)) {
return lchown(rpath(fs_ctx, path, buffer), credp->fc_uid,
credp->fc_gid);
}
@@ -645,10 +677,44 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
return ret;
}
+static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
+ mode_t st_mode, uint64_t *st_gen)
+{
+ int err, fd;
+ /*
+ * Do not try to open special files like device nodes, fifos etc
+ * We can get fd for regular files and directories only
+ */
+ if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
+ return 0;
+ }
+ fd = local_open(ctx, path, O_RDONLY);
+ if (fd < 0) {
+ return fd;
+ }
+ err = ioctl(fd, FS_IOC_GETVERSION, st_gen);
+ local_close(ctx, fd);
+ return err;
+}
+
static int local_init(FsContext *ctx)
{
- ctx->flags |= PATHNAME_FSCONTEXT;
- return 0;
+ int err;
+ struct statfs stbuf;
+
+ ctx->export_flags |= V9FS_PATHNAME_FSCONTEXT;
+ err = statfs(ctx->fs_root, &stbuf);
+ if (!err) {
+ switch (stbuf.f_type) {
+ case EXT2_SUPER_MAGIC:
+ case BTRFS_SUPER_MAGIC:
+ case REISERFS_SUPER_MAGIC:
+ case XFS_SUPER_MAGIC:
+ ctx->exops.get_st_gen = local_ioc_getversion;
+ break;
+ }
+ }
+ return err;
}
FileOperations local_ops = {
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index c01c31aa25..aab3bebcc7 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -17,11 +17,10 @@
#include "hw/virtio-pci.h"
#include "virtio-9p.h"
#include "fsdev/qemu-fsdev.h"
-#include "virtio-9p-debug.h"
#include "virtio-9p-xattr.h"
#include "virtio-9p-coth.h"
+#include "trace.h"
-int debug_9p_pdu;
int open_fd_hw;
int total_open_fd;
static int open_fd_rc;
@@ -72,6 +71,55 @@ static int omode_to_uflags(int8_t mode)
return ret;
}
+static int dotl_to_at_flags(int flags)
+{
+ int rflags = 0;
+ if (flags & P9_DOTL_AT_REMOVEDIR) {
+ rflags |= AT_REMOVEDIR;
+ }
+ return rflags;
+}
+
+struct dotl_openflag_map {
+ int dotl_flag;
+ int open_flag;
+};
+
+static int dotl_to_open_flags(int flags)
+{
+ int i;
+ /*
+ * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
+ * and P9_DOTL_NOACCESS
+ */
+ int oflags = flags & O_ACCMODE;
+
+ struct dotl_openflag_map dotl_oflag_map[] = {
+ { P9_DOTL_CREATE, O_CREAT },
+ { P9_DOTL_EXCL, O_EXCL },
+ { P9_DOTL_NOCTTY , O_NOCTTY },
+ { P9_DOTL_TRUNC, O_TRUNC },
+ { P9_DOTL_APPEND, O_APPEND },
+ { P9_DOTL_NONBLOCK, O_NONBLOCK } ,
+ { P9_DOTL_DSYNC, O_DSYNC },
+ { P9_DOTL_FASYNC, FASYNC },
+ { P9_DOTL_DIRECT, O_DIRECT },
+ { P9_DOTL_LARGEFILE, O_LARGEFILE },
+ { P9_DOTL_DIRECTORY, O_DIRECTORY },
+ { P9_DOTL_NOFOLLOW, O_NOFOLLOW },
+ { P9_DOTL_NOATIME, O_NOATIME },
+ { P9_DOTL_SYNC, O_SYNC },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
+ if (flags & dotl_oflag_map[i].dotl_flag) {
+ oflags |= dotl_oflag_map[i].open_flag;
+ }
+ }
+
+ return oflags;
+}
+
void cred_init(FsCred *credp)
{
credp->fc_uid = -1;
@@ -80,6 +128,21 @@ void cred_init(FsCred *credp)
credp->fc_rdev = -1;
}
+static int get_dotl_openflags(V9fsState *s, int oflags)
+{
+ int flags;
+ /*
+ * Filter the client open flags
+ */
+ flags = dotl_to_open_flags(oflags);
+ flags &= ~(O_NOCTTY | O_ASYNC | O_CREAT);
+ /*
+ * Ignore direct disk access hint until the server supports it.
+ */
+ flags &= ~O_DIRECT;
+ return flags;
+}
+
void v9fs_string_init(V9fsString *str)
{
str->data = NULL;
@@ -621,9 +684,6 @@ static V9fsPDU *alloc_pdu(V9fsState *s)
static void free_pdu(V9fsState *s, V9fsPDU *pdu)
{
if (pdu) {
- if (debug_9p_pdu) {
- pprint_pdu(pdu);
- }
/*
* Cancelled pdu are added back to the freelist
* by flush request .
@@ -909,6 +969,7 @@ static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len)
if (s->proto_version == V9FS_PROTO_2000L) {
id = P9_RLERROR;
}
+ trace_complete_pdu(pdu->tag, pdu->id, err); /* Trace ERROR */
}
/* fill out the header */
@@ -1218,6 +1279,7 @@ static void v9fs_version(void *opaque)
size_t offset = 7;
pdu_unmarshal(pdu, offset, "ds", &s->msize, &version);
+ trace_v9fs_version(pdu->tag, pdu->id, s->msize, version.data);
if (!strcmp(version.data, "9P2000.u")) {
s->proto_version = V9FS_PROTO_2000U;
@@ -1228,6 +1290,8 @@ static void v9fs_version(void *opaque)
}
offset += pdu_marshal(pdu, offset, "ds", s->msize, &version);
+ trace_v9fs_version_return(pdu->tag, pdu->id, s->msize, version.data);
+
complete_pdu(s, pdu, offset);
v9fs_string_free(&version);
@@ -1246,6 +1310,7 @@ static void v9fs_attach(void *opaque)
ssize_t err;
pdu_unmarshal(pdu, offset, "ddssd", &fid, &afid, &uname, &aname, &n_uname);
+ trace_v9fs_attach(pdu->tag, pdu->id, fid, afid, uname.data, aname.data);
fidp = alloc_fid(s, fid);
if (fidp == NULL) {
@@ -1270,6 +1335,8 @@ static void v9fs_attach(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_attach_return(pdu->tag, pdu->id,
+ qid.type, qid.version, qid.path);
complete_pdu(s, pdu, err);
v9fs_string_free(&uname);
v9fs_string_free(&aname);
@@ -1287,6 +1354,7 @@ static void v9fs_stat(void *opaque)
V9fsState *s = pdu->s;
pdu_unmarshal(pdu, offset, "d", &fid);
+ trace_v9fs_stat(pdu->tag, pdu->id, fid);
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
@@ -1307,6 +1375,9 @@ static void v9fs_stat(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_stat_return(pdu->tag, pdu->id, v9stat.mode,
+ v9stat.atime, v9stat.mtime, v9stat.length);
+
complete_pdu(s, pdu, err);
}
@@ -1323,6 +1394,7 @@ static void v9fs_getattr(void *opaque)
V9fsState *s = pdu->s;
pdu_unmarshal(pdu, offset, "dq", &fid, &request_mask);
+ trace_v9fs_getattr(pdu->tag, pdu->id, fid, request_mask);
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
@@ -1338,11 +1410,24 @@ static void v9fs_getattr(void *opaque)
goto out;
}
stat_to_v9stat_dotl(s, &stbuf, &v9stat_dotl);
+
+ /* fill st_gen if requested and supported by underlying fs */
+ if (request_mask & P9_STATS_GEN) {
+ retval = v9fs_co_st_gen(pdu, &fidp->path, stbuf.st_mode, &v9stat_dotl);
+ if (retval < 0) {
+ goto out;
+ }
+ v9stat_dotl.st_result_mask |= P9_STATS_GEN;
+ }
retval = offset;
retval += pdu_marshal(pdu, offset, "A", &v9stat_dotl);
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_getattr_return(pdu->tag, pdu->id, v9stat_dotl.st_result_mask,
+ v9stat_dotl.st_mode, v9stat_dotl.st_uid,
+ v9stat_dotl.st_gid);
+
complete_pdu(s, pdu, retval);
}
@@ -1470,6 +1555,8 @@ static void v9fs_walk(void *opaque)
offset += pdu_unmarshal(pdu, offset, "ddw", &fid,
&newfid, &nwnames);
+ trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames);
+
if (nwnames && nwnames <= P9_MAXWELEM) {
wnames = g_malloc0(sizeof(wnames[0]) * nwnames);
qids = g_malloc0(sizeof(qids[0]) * nwnames);
@@ -1526,6 +1613,7 @@ out:
v9fs_path_free(&dpath);
v9fs_path_free(&path);
out_nofid:
+ trace_v9fs_walk_return(pdu->tag, pdu->id, nwnames, qids);
complete_pdu(s, pdu, err);
if (nwnames && nwnames <= P9_MAXWELEM) {
for (name_idx = 0; name_idx < nwnames; name_idx++) {
@@ -1576,6 +1664,8 @@ static void v9fs_open(void *opaque)
} else {
pdu_unmarshal(pdu, offset, "db", &fid, &mode);
}
+ trace_v9fs_open(pdu->tag, pdu->id, fid, mode);
+
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -ENOENT;
@@ -1598,10 +1688,7 @@ static void v9fs_open(void *opaque)
err = offset;
} else {
if (s->proto_version == V9FS_PROTO_2000L) {
- flags = mode;
- flags &= ~(O_NOCTTY | O_ASYNC | O_CREAT);
- /* Ignore direct disk access hint until the server supports it. */
- flags &= ~O_DIRECT;
+ flags = get_dotl_openflags(s, mode);
} else {
flags = omode_to_uflags(mode);
}
@@ -1625,6 +1712,8 @@ static void v9fs_open(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_open_return(pdu->tag, pdu->id,
+ qid.type, qid.version, qid.path, iounit);
complete_pdu(s, pdu, err);
}
@@ -1643,6 +1732,7 @@ static void v9fs_lcreate(void *opaque)
pdu_unmarshal(pdu, offset, "dsddd", &dfid, &name, &flags,
&mode, &gid);
+ trace_v9fs_lcreate(pdu->tag, pdu->id, dfid, flags, mode, gid);
fidp = get_fid(pdu, dfid);
if (fidp == NULL) {
@@ -1650,8 +1740,7 @@ static void v9fs_lcreate(void *opaque)
goto out_nofid;
}
- /* Ignore direct disk access hint until the server supports it. */
- flags &= ~O_DIRECT;
+ flags = get_dotl_openflags(pdu->s, flags);
err = v9fs_co_open2(pdu, fidp, &name, gid,
flags | O_CREAT, mode, &stbuf);
if (err < 0) {
@@ -1673,6 +1762,8 @@ static void v9fs_lcreate(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_lcreate_return(pdu->tag, pdu->id,
+ qid.type, qid.version, qid.path, iounit);
complete_pdu(pdu->s, pdu, err);
v9fs_string_free(&name);
}
@@ -1688,6 +1779,8 @@ static void v9fs_fsync(void *opaque)
V9fsState *s = pdu->s;
pdu_unmarshal(pdu, offset, "dd", &fid, &datasync);
+ trace_v9fs_fsync(pdu->tag, pdu->id, fid, datasync);
+
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -ENOENT;
@@ -1712,6 +1805,7 @@ static void v9fs_clunk(void *opaque)
V9fsState *s = pdu->s;
pdu_unmarshal(pdu, offset, "d", &fid);
+ trace_v9fs_clunk(pdu->tag, pdu->id, fid);
fidp = clunk_fid(s, fid);
if (fidp == NULL) {
@@ -1828,6 +1922,7 @@ static void v9fs_read(void *opaque)
V9fsState *s = pdu->s;
pdu_unmarshal(pdu, offset, "dqd", &fid, &off, &max_count);
+ trace_v9fs_read(pdu->tag, pdu->id, fid, off, max_count);
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
@@ -1886,6 +1981,7 @@ static void v9fs_read(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_read_return(pdu->tag, pdu->id, count, err);
complete_pdu(s, pdu, err);
}
@@ -1970,6 +2066,8 @@ static void v9fs_readdir(void *opaque)
pdu_unmarshal(pdu, offset, "dqd", &fid, &initial_offset, &max_count);
+ trace_v9fs_readdir(pdu->tag, pdu->id, fid, initial_offset, max_count);
+
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
retval = -EINVAL;
@@ -1995,6 +2093,7 @@ static void v9fs_readdir(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_readdir_return(pdu->tag, pdu->id, count, retval);
complete_pdu(s, pdu, retval);
}
@@ -2059,6 +2158,7 @@ static void v9fs_write(void *opaque)
V9fsState *s = pdu->s;
pdu_unmarshal(pdu, offset, "dqdv", &fid, &off, &count, sg, &cnt);
+ trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, cnt);
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
@@ -2105,6 +2205,7 @@ static void v9fs_write(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_write_return(pdu->tag, pdu->id, total, err);
complete_pdu(s, pdu, err);
}
@@ -2129,6 +2230,8 @@ static void v9fs_create(void *opaque)
pdu_unmarshal(pdu, offset, "dsdbs", &fid, &name,
&perm, &mode, &extension);
+ trace_v9fs_create(pdu->tag, pdu->id, fid, name.data, perm, mode);
+
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -EINVAL;
@@ -2262,6 +2365,8 @@ static void v9fs_create(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_create_return(pdu->tag, pdu->id,
+ qid.type, qid.version, qid.path, iounit);
complete_pdu(pdu->s, pdu, err);
v9fs_string_free(&name);
v9fs_string_free(&extension);
@@ -2282,6 +2387,7 @@ static void v9fs_symlink(void *opaque)
size_t offset = 7;
pdu_unmarshal(pdu, offset, "dssd", &dfid, &name, &symname, &gid);
+ trace_v9fs_symlink(pdu->tag, pdu->id, dfid, name.data, symname.data, gid);
dfidp = get_fid(pdu, dfid);
if (dfidp == NULL) {
@@ -2298,6 +2404,8 @@ static void v9fs_symlink(void *opaque)
out:
put_fid(pdu, dfidp);
out_nofid:
+ trace_v9fs_symlink_return(pdu->tag, pdu->id,
+ qid.type, qid.version, qid.path);
complete_pdu(pdu->s, pdu, err);
v9fs_string_free(&name);
v9fs_string_free(&symname);
@@ -2312,6 +2420,7 @@ static void v9fs_flush(void *opaque)
V9fsState *s = pdu->s;
pdu_unmarshal(pdu, offset, "w", &tag);
+ trace_v9fs_flush(pdu->tag, pdu->id, tag);
QLIST_FOREACH(cancel_pdu, &s->active_list, next) {
if (cancel_pdu->tag == tag) {
@@ -2342,6 +2451,7 @@ static void v9fs_link(void *opaque)
int err = 0;
pdu_unmarshal(pdu, offset, "dds", &dfid, &oldfid, &name);
+ trace_v9fs_link(pdu->tag, pdu->id, dfid, oldfid, name.data);
dfidp = get_fid(pdu, dfid);
if (dfidp == NULL) {
@@ -2375,6 +2485,7 @@ static void v9fs_remove(void *opaque)
V9fsPDU *pdu = opaque;
pdu_unmarshal(pdu, offset, "d", &fid);
+ trace_v9fs_remove(pdu->tag, pdu->id, fid);
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
@@ -2382,7 +2493,7 @@ static void v9fs_remove(void *opaque)
goto out_nofid;
}
/* if fs driver is not path based, return EOPNOTSUPP */
- if (!pdu->s->ctx.flags & PATHNAME_FSCONTEXT) {
+ if (!(pdu->s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT)) {
err = -EOPNOTSUPP;
goto out_err;
}
@@ -2417,6 +2528,7 @@ static void v9fs_unlinkat(void *opaque)
V9fsPDU *pdu = opaque;
pdu_unmarshal(pdu, offset, "dsd", &dfid, &name, &flags);
+ flags = dotl_to_at_flags(flags);
dfidp = get_fid(pdu, dfid);
if (dfidp == NULL) {
@@ -2528,7 +2640,7 @@ static void v9fs_rename(void *opaque)
}
BUG_ON(fidp->fid_type != P9_FID_NONE);
/* if fs driver is not path based, return EOPNOTSUPP */
- if (!pdu->s->ctx.flags & PATHNAME_FSCONTEXT) {
+ if (!(pdu->s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT)) {
err = -EOPNOTSUPP;
goto out;
}
@@ -2601,7 +2713,7 @@ static int v9fs_complete_renameat(V9fsPDU *pdu, int32_t olddirfid,
if (err < 0) {
goto out;
}
- if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+ if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
/* Only for path based fid we need to do the below fixup */
v9fs_fix_fid_paths(pdu, &olddirfidp->path, old_name,
&newdirfidp->path, new_name);
@@ -2653,6 +2765,8 @@ static void v9fs_wstat(void *opaque)
V9fsState *s = pdu->s;
pdu_unmarshal(pdu, offset, "dwS", &fid, &unused, &v9stat);
+ trace_v9fs_wstat(pdu->tag, pdu->id, fid,
+ v9stat.mode, v9stat.atime, v9stat.mtime);
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
@@ -2821,6 +2935,7 @@ static void v9fs_mknod(void *opaque)
pdu_unmarshal(pdu, offset, "dsdddd", &fid, &name, &mode,
&major, &minor, &gid);
+ trace_v9fs_mknod(pdu->tag, pdu->id, fid, mode, major, minor);
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
@@ -2838,6 +2953,7 @@ static void v9fs_mknod(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_mknod_return(pdu->tag, pdu->id, qid.type, qid.version, qid.path);
complete_pdu(s, pdu, err);
v9fs_string_free(&name);
}
@@ -2865,6 +2981,10 @@ static void v9fs_lock(void *opaque)
pdu_unmarshal(pdu, offset, "dbdqqds", &fid, &flock->type,
&flock->flags, &flock->start, &flock->length,
&flock->proc_id, &flock->client_id);
+
+ trace_v9fs_lock(pdu->tag, pdu->id, fid,
+ flock->type, flock->start, flock->length);
+
status = P9_LOCK_ERROR;
/* We support only block flag now (that too ignored currently) */
@@ -2887,6 +3007,7 @@ out:
out_nofid:
err = offset;
err += pdu_marshal(pdu, offset, "b", status);
+ trace_v9fs_lock_return(pdu->tag, pdu->id, status);
complete_pdu(s, pdu, err);
v9fs_string_free(&flock->client_id);
g_free(flock);
@@ -2911,6 +3032,9 @@ static void v9fs_getlock(void *opaque)
&glock->start, &glock->length, &glock->proc_id,
&glock->client_id);
+ trace_v9fs_getlock(pdu->tag, pdu->id, fid,
+ glock->type, glock->start, glock->length);
+
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -ENOENT;
@@ -2920,7 +3044,7 @@ static void v9fs_getlock(void *opaque)
if (err < 0) {
goto out;
}
- glock->type = F_UNLCK;
+ glock->type = P9_LOCK_TYPE_UNLCK;
offset += pdu_marshal(pdu, offset, "bqqds", glock->type,
glock->start, glock->length, glock->proc_id,
&glock->client_id);
@@ -2928,6 +3052,9 @@ static void v9fs_getlock(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_getlock_return(pdu->tag, pdu->id, glock->type, glock->start,
+ glock->length, glock->proc_id);
+
complete_pdu(s, pdu, err);
v9fs_string_free(&glock->client_id);
g_free(glock);
@@ -2948,6 +3075,8 @@ static void v9fs_mkdir(void *opaque)
pdu_unmarshal(pdu, offset, "dsdd", &fid, &name, &mode, &gid);
+ trace_v9fs_mkdir(pdu->tag, pdu->id, fid, name.data, mode, gid);
+
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -ENOENT;
@@ -2963,6 +3092,8 @@ static void v9fs_mkdir(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_mkdir_return(pdu->tag, pdu->id,
+ qid.type, qid.version, qid.path, err);
complete_pdu(pdu->s, pdu, err);
v9fs_string_free(&name);
}
@@ -2980,6 +3111,8 @@ static void v9fs_xattrwalk(void *opaque)
V9fsState *s = pdu->s;
pdu_unmarshal(pdu, offset, "dds", &fid, &newfid, &name);
+ trace_v9fs_xattrwalk(pdu->tag, pdu->id, fid, newfid, name.data);
+
file_fidp = get_fid(pdu, fid);
if (file_fidp == NULL) {
err = -ENOENT;
@@ -3056,6 +3189,7 @@ out:
put_fid(pdu, xattr_fidp);
}
out_nofid:
+ trace_v9fs_xattrwalk_return(pdu->tag, pdu->id, size);
complete_pdu(s, pdu, err);
v9fs_string_free(&name);
}
@@ -3075,6 +3209,7 @@ static void v9fs_xattrcreate(void *opaque)
pdu_unmarshal(pdu, offset, "dsqd",
&fid, &name, &size, &flags);
+ trace_v9fs_xattrcreate(pdu->tag, pdu->id, fid, name.data, size, flags);
file_fidp = get_fid(pdu, fid);
if (file_fidp == NULL) {
@@ -3111,6 +3246,7 @@ static void v9fs_readlink(void *opaque)
V9fsFidState *fidp;
pdu_unmarshal(pdu, offset, "d", &fid);
+ trace_v9fs_readlink(pdu->tag, pdu->id, fid);
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
err = -ENOENT;
@@ -3128,6 +3264,7 @@ static void v9fs_readlink(void *opaque)
out:
put_fid(pdu, fidp);
out_nofid:
+ trace_v9fs_readlink_return(pdu->tag, pdu->id, target.data);
complete_pdu(pdu->s, pdu, err);
}
@@ -3179,9 +3316,6 @@ static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
Coroutine *co;
CoroutineEntry *handler;
- if (debug_9p_pdu) {
- pprint_pdu(pdu);
- }
if (pdu->id >= ARRAY_SIZE(pdu_co_handlers) ||
(pdu_co_handlers[pdu->id] == NULL)) {
handler = v9fs_op_not_supp;
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 60b8a56e57..802f5809d1 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -352,6 +352,35 @@ typedef struct V9fsMkState {
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
@@ -393,21 +422,21 @@ static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
static inline void v9fs_path_write_lock(V9fsState *s)
{
- if (s->ctx.flags & PATHNAME_FSCONTEXT) {
+ 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.flags & PATHNAME_FSCONTEXT) {
+ 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.flags & PATHNAME_FSCONTEXT) {
+ if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
qemu_co_rwlock_unlock(&s->rename_lock);
}
}
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index df27c198b0..ca5923c495 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -83,11 +83,6 @@
/* Flags track per-device state like workarounds for quirks in older guests. */
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG (1 << 0)
-/* Performance improves when virtqueue kick processing is decoupled from the
- * vcpu thread using ioeventfd for some devices. */
-#define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1
-#define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
-
/* QEMU doesn't strictly need write barriers since everything runs in
* lock-step. We'll leave the calls to wmb() in though to make it obvious for
* KVM or if kqemu gets SMP support.
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index 14c10f7d67..f8404de92b 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -18,6 +18,11 @@
#include "virtio-net.h"
#include "virtio-serial.h"
+/* Performance improves when virtqueue kick processing is decoupled from the
+ * vcpu thread using ioeventfd for some devices. */
+#define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1
+#define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
+
typedef struct {
PCIDevice pci_dev;
VirtIODevice *vdev;