From 936532a4928ce6c95de5718974f6c987aaad7b68 Mon Sep 17 00:00:00 2001 From: Malahal Naineni Date: Wed, 1 Jun 2011 12:35:11 +0530 Subject: [PATCH 1/7] [virtio-9p] Stop renaming files with similar name! v9fs_complete_rename() mistakenly renames files with similar name as we don't check if the matched name is really an offspring. Signed-off-by: Malahal Naineni Signed-off-by: Venkateswararao Jujjuri (JV) --- hw/9pfs/virtio-9p.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index b5fc52b3eb..77d1c0874a 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -423,6 +423,22 @@ static void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs) v9fs_string_sprintf(lhs, "%s", rhs->data); } +/* + * Return TRUE if s1 is an ancestor of s2. + * + * E.g. "a/b" is an ancestor of "a/b/c" but not of "a/bc/d". + * As a special case, We treat s1 as ancestor of s2 if they are same! + */ +static int v9fs_path_is_ancestor(V9fsString *s1, V9fsString *s2) +{ + if (!strncmp(s1->data, s2->data, s1->size)) { + if (s2->data[s1->size] == '\0' || s2->data[s1->size] == '/') { + return 1; + } + } + return 0; +} + static size_t v9fs_string_size(V9fsString *str) { return str->size; @@ -2805,13 +2821,13 @@ static int v9fs_complete_rename(V9fsState *s, V9fsRenameState *vs) for (fidp = s->fid_list; fidp; fidp = fidp->next) { if (vs->fidp == fidp) { /* - * we replace name of this fid towards the end - * so that our below strcmp will work + * we replace name of this fid towards the end so + * that our below v9fs_path_is_ancestor check will + * work */ continue; } - if (!strncmp(vs->fidp->path.data, fidp->path.data, - strlen(vs->fidp->path.data))) { + if (v9fs_path_is_ancestor(&vs->fidp->path, &fidp->path)) { /* replace the name */ v9fs_fix_path(&fidp->path, &vs->name, strlen(vs->fidp->path.data)); From 1c88c71564bb6e6554f8aad16c7be1bf2a57c89b Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 1 Jun 2011 12:35:13 +0530 Subject: [PATCH 2/7] virtio-9p: Don't link to 9p if virtio is not enabled If virtio is not enabled then we should not pull in virtfs files Signed-off-by: Aneesh Kumar K.V Signed-off-by: Venkateswararao Jujjuri (JV) --- Makefile.objs | 8 +++++--- fsdev/qemu-fsdev-dummy.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 fsdev/qemu-fsdev-dummy.c diff --git a/Makefile.objs b/Makefile.objs index 90838f6a0d..bdcc845941 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -49,8 +49,10 @@ ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS),yy) # 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. CONFIG_REALLY_VIRTFS=y +fsdev-nested-y = qemu-fsdev.o +else +fsdev-nested-y = qemu-fsdev-dummy.o endif -fsdev-nested-$(CONFIG_VIRTFS) = qemu-fsdev.o fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y)) ###################################################################### @@ -285,11 +287,11 @@ sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y) -9pfs-nested-$(CONFIG_REALLY_VIRTFS) = virtio-9p-debug.o +9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p-debug.o 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o -hw-obj-$(CONFIG_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y)) +hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y)) $(addprefix 9pfs/, $(9pfs-nested-y)): CFLAGS += -I$(SRC_PATH)/hw/ diff --git a/fsdev/qemu-fsdev-dummy.c b/fsdev/qemu-fsdev-dummy.c new file mode 100644 index 0000000000..619e163a46 --- /dev/null +++ b/fsdev/qemu-fsdev-dummy.c @@ -0,0 +1,20 @@ +/* + * Virtio 9p + * + * Copyright IBM, Corp. 2010 + * + * Authors: + * Gautham R Shenoy + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ +#include +#include +#include "qemu-fsdev.h" + +int qemu_fsdev_add(QemuOpts *opts) +{ + return 0; +} From 9fe1ebebd0c427fd9b3d1ffffa77a9969d873d93 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 1 Jun 2011 12:35:13 +0530 Subject: [PATCH 3/7] virtio-9p: Move 9p device registration into virtio-9p.c This patch move the 9p device registration into its own file Signed-off-by: Aneesh Kumar K.V Signed-off-by: Venkateswararao Jujjuri (JV) --- Makefile.objs | 2 +- hw/9pfs/virtio-9p.c | 38 ++++++++++++++++++++++++++++++ hw/virtio-pci.c | 57 ++------------------------------------------- hw/virtio-pci.h | 43 ++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 56 deletions(-) create mode 100644 hw/virtio-pci.h diff --git a/Makefile.objs b/Makefile.objs index bdcc845941..1af0c44ee1 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -45,7 +45,7 @@ net-nested-$(CONFIG_SLIRP) += slirp.o net-nested-$(CONFIG_VDE) += vde.o net-obj-y += $(addprefix net/, $(net-nested-y)) -ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS),yy) +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. CONFIG_REALLY_VIRTFS=y diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 77d1c0874a..28c128e762 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -14,6 +14,7 @@ #include "virtio.h" #include "pc.h" #include "qemu_socket.h" +#include "virtio-pci.h" #include "virtio-9p.h" #include "fsdev/qemu-fsdev.h" #include "virtio-9p-debug.h" @@ -3761,3 +3762,40 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) return &s->vdev; } + +static int virtio_9p_init_pci(PCIDevice *pci_dev) +{ + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; + + vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf); + vdev->nvectors = proxy->nvectors; + virtio_init_pci(proxy, vdev, + PCI_VENDOR_ID_REDHAT_QUMRANET, + 0x1009, + 0x2, + 0x00); + /* make the actual value visible */ + proxy->nvectors = vdev->nvectors; + return 0; +} + +static PCIDeviceInfo virtio_9p_info = { + .qdev.name = "virtio-9p-pci", + .qdev.size = sizeof(VirtIOPCIProxy), + .init = virtio_9p_init_pci, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), + DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), + DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag), + DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id), + DEFINE_PROP_END_OF_LIST(), + } +}; + +static void virtio_9p_register_devices(void) +{ + pci_qdev_register(&virtio_9p_info); +} + +device_init(virtio_9p_register_devices) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index c19629d507..c018351095 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -26,6 +26,7 @@ #include "loader.h" #include "kvm.h" #include "blockdev.h" +#include "virtio-pci.h" /* from Linux's linux/virtio_pci.h */ @@ -95,27 +96,6 @@ */ #define wmb() do { } while (0) -/* PCI bindings. */ - -typedef struct { - PCIDevice pci_dev; - VirtIODevice *vdev; - uint32_t flags; - uint32_t addr; - uint32_t class_code; - uint32_t nvectors; - BlockConf block; - NICConf nic; - uint32_t host_features; -#ifdef CONFIG_LINUX - V9fsConf fsconf; -#endif - virtio_serial_conf serial; - virtio_net_conf net; - bool ioeventfd_disabled; - bool ioeventfd_started; -} VirtIOPCIProxy; - /* virtio device */ static void virtio_pci_notify(void *opaque, uint16_t vector) @@ -669,7 +649,7 @@ static const VirtIOBindings virtio_pci_bindings = { .vmstate_change = virtio_pci_vmstate_change, }; -static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, +void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, uint16_t vendor, uint16_t device, uint16_t class_code, uint8_t pif) { @@ -835,25 +815,6 @@ static int virtio_balloon_init_pci(PCIDevice *pci_dev) return 0; } -#ifdef CONFIG_VIRTFS -static int virtio_9p_init_pci(PCIDevice *pci_dev) -{ - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - VirtIODevice *vdev; - - vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf); - vdev->nvectors = proxy->nvectors; - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - 0x1009, - 0x2, - 0x00); - /* make the actual value visible */ - proxy->nvectors = vdev->nvectors; - return 0; -} -#endif - static PCIDeviceInfo virtio_info[] = { { .qdev.name = "virtio-blk-pci", @@ -922,20 +883,6 @@ static PCIDeviceInfo virtio_info[] = { }, .qdev.reset = virtio_pci_reset, },{ -#ifdef CONFIG_VIRTFS - .qdev.name = "virtio-9p-pci", - .qdev.alias = "virtio-9p", - .qdev.size = sizeof(VirtIOPCIProxy), - .init = virtio_9p_init_pci, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag), - DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id), - DEFINE_PROP_END_OF_LIST(), - }, - }, { -#endif /* end of list */ } }; diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h new file mode 100644 index 0000000000..a4b5fd30e1 --- /dev/null +++ b/hw/virtio-pci.h @@ -0,0 +1,43 @@ +/* + * Virtio PCI Bindings + * + * Copyright IBM, Corp. 2007 + * Copyright (c) 2009 CodeSourcery + * + * Authors: + * Anthony Liguori + * Paul Brook + * + * 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_PCI_H +#define QEMU_VIRTIO_PCI_H + +#include "virtio-net.h" +#include "virtio-serial.h" + +typedef struct { + PCIDevice pci_dev; + VirtIODevice *vdev; + uint32_t flags; + uint32_t addr; + uint32_t class_code; + uint32_t nvectors; + BlockConf block; + NICConf nic; + uint32_t host_features; +#ifdef CONFIG_LINUX + V9fsConf fsconf; +#endif + virtio_serial_conf serial; + virtio_net_conf net; + bool ioeventfd_disabled; + bool ioeventfd_started; +} VirtIOPCIProxy; + +extern void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, + uint16_t vendor, uint16_t device, + uint16_t class_code, uint8_t pif); +#endif From f4f61d272e26ca34612c05070dfbda86dc00298b Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 1 Jun 2011 12:35:13 +0530 Subject: [PATCH 4/7] virtio-9p: Move device specific code to virtio-9p-device Signed-off-by: Aneesh Kumar K.V Signed-off-by: Venkateswararao Jujjuri (JV) --- Makefile.objs | 2 +- Makefile.target | 4 +- hw/9pfs/virtio-9p-device.c | 173 +++++++++++++++++++++++++++++++++++++ hw/9pfs/virtio-9p.c | 155 +-------------------------------- hw/9pfs/virtio-9p.h | 2 + 5 files changed, 179 insertions(+), 157 deletions(-) create mode 100644 hw/9pfs/virtio-9p-device.c diff --git a/Makefile.objs b/Makefile.objs index 1af0c44ee1..1dc45c475a 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -287,7 +287,7 @@ sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y) -9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p-debug.o +9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p.o virtio-9p-debug.o 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o diff --git a/Makefile.target b/Makefile.target index 602d50dc64..73ab0164f9 100644 --- a/Makefile.target +++ b/Makefile.target @@ -194,7 +194,7 @@ obj-$(CONFIG_VIRTIO) += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o obj-y += vhost_net.o obj-$(CONFIG_VHOST_NET) += vhost.o -obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p.o +obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o obj-y += rwhandler.o obj-$(CONFIG_KVM) += kvm.o kvm-all.o obj-$(CONFIG_NO_KVM) += kvm-stub.o @@ -413,7 +413,7 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx qmp-commands.h: $(SRC_PATH)/qmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") -9pfs/virtio-9p.o: CFLAGS += -I$(SRC_PATH)/hw/ +9pfs/virtio-9p-device.o: CFLAGS += -I$(SRC_PATH)/hw/ clean: rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c new file mode 100644 index 0000000000..f9854861aa --- /dev/null +++ b/hw/9pfs/virtio-9p-device.c @@ -0,0 +1,173 @@ +/* + * Virtio 9p backend + * + * Copyright IBM, Corp. 2010 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "virtio.h" +#include "pc.h" +#include "qemu_socket.h" +#include "virtio-pci.h" +#include "virtio-9p.h" +#include "fsdev/qemu-fsdev.h" +#include "virtio-9p-xattr.h" + +static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features) +{ + features |= 1 << VIRTIO_9P_MOUNT_TAG; + return features; +} + +static V9fsState *to_virtio_9p(VirtIODevice *vdev) +{ + return (V9fsState *)vdev; +} + +static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config) +{ + struct virtio_9p_config *cfg; + V9fsState *s = to_virtio_9p(vdev); + + cfg = qemu_mallocz(sizeof(struct virtio_9p_config) + + s->tag_len); + stw_raw(&cfg->tag_len, s->tag_len); + memcpy(cfg->tag, s->tag, s->tag_len); + memcpy(config, cfg, s->config_size); + qemu_free(cfg); +} + +VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) + { + V9fsState *s; + int i, len; + struct stat stat; + FsTypeEntry *fse; + + + s = (V9fsState *)virtio_common_init("virtio-9p", + VIRTIO_ID_9P, + sizeof(struct virtio_9p_config)+ + MAX_TAG_LEN, + sizeof(V9fsState)); + + /* initialize pdu allocator */ + QLIST_INIT(&s->free_list); + for (i = 0; i < (MAX_REQ - 1); i++) { + QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next); + } + + s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output); + + fse = get_fsdev_fsentry(conf->fsdev_id); + + if (!fse) { + /* We don't have a fsdev identified by fsdev_id */ + fprintf(stderr, "Virtio-9p device couldn't find fsdev with the " + "id = %s\n", conf->fsdev_id ? conf->fsdev_id : "NULL"); + exit(1); + } + + if (!fse->path || !conf->tag) { + /* we haven't specified a mount_tag or the path */ + fprintf(stderr, "fsdev with id %s needs path " + "and Virtio-9p device needs mount_tag arguments\n", + conf->fsdev_id); + 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.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; + 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; + 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 = qemu_strdup(fse->path); + len = strlen(conf->tag); + if (len > MAX_TAG_LEN) { + len = MAX_TAG_LEN; + } + /* s->tag is non-NULL terminated string */ + s->tag = qemu_malloc(len); + memcpy(s->tag, conf->tag, len); + s->tag_len = len; + s->ctx.uid = -1; + + s->ops = fse->ops; + s->vdev.get_features = virtio_9p_get_features; + s->config_size = sizeof(struct virtio_9p_config) + + s->tag_len; + s->vdev.get_config = virtio_9p_get_config; + + return &s->vdev; +} + +static int virtio_9p_init_pci(PCIDevice *pci_dev) +{ + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; + + vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf); + vdev->nvectors = proxy->nvectors; + virtio_init_pci(proxy, vdev, + PCI_VENDOR_ID_REDHAT_QUMRANET, + 0x1009, + 0x2, + 0x00); + /* make the actual value visible */ + proxy->nvectors = vdev->nvectors; + return 0; +} + +static PCIDeviceInfo virtio_9p_info = { + .qdev.name = "virtio-9p-pci", + .qdev.size = sizeof(VirtIOPCIProxy), + .init = virtio_9p_init_pci, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), + DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), + DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag), + DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id), + DEFINE_PROP_END_OF_LIST(), + } +}; + +static void virtio_9p_register_devices(void) +{ + pci_qdev_register(&virtio_9p_info); +} + +device_init(virtio_9p_register_devices) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 28c128e762..21865b1f24 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -3622,7 +3622,7 @@ static void submit_pdu(V9fsState *s, V9fsPDU *pdu) handler(s, pdu); } -static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq) +void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq) { V9fsState *s = (V9fsState *)vdev; V9fsPDU *pdu; @@ -3646,156 +3646,3 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq) free_pdu(s, pdu); } - -static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features) -{ - features |= 1 << VIRTIO_9P_MOUNT_TAG; - return features; -} - -static V9fsState *to_virtio_9p(VirtIODevice *vdev) -{ - return (V9fsState *)vdev; -} - -static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config) -{ - struct virtio_9p_config *cfg; - V9fsState *s = to_virtio_9p(vdev); - - cfg = qemu_mallocz(sizeof(struct virtio_9p_config) + - s->tag_len); - stw_raw(&cfg->tag_len, s->tag_len); - memcpy(cfg->tag, s->tag, s->tag_len); - memcpy(config, cfg, s->config_size); - qemu_free(cfg); -} - -VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) - { - V9fsState *s; - int i, len; - struct stat stat; - FsTypeEntry *fse; - - - s = (V9fsState *)virtio_common_init("virtio-9p", - VIRTIO_ID_9P, - sizeof(struct virtio_9p_config)+ - MAX_TAG_LEN, - sizeof(V9fsState)); - - /* initialize pdu allocator */ - QLIST_INIT(&s->free_list); - for (i = 0; i < (MAX_REQ - 1); i++) { - QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next); - } - - s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output); - - fse = get_fsdev_fsentry(conf->fsdev_id); - - if (!fse) { - /* We don't have a fsdev identified by fsdev_id */ - fprintf(stderr, "Virtio-9p device couldn't find fsdev with the " - "id = %s\n", conf->fsdev_id ? conf->fsdev_id : "NULL"); - exit(1); - } - - if (!fse->path || !conf->tag) { - /* we haven't specified a mount_tag or the path */ - fprintf(stderr, "fsdev with id %s needs path " - "and Virtio-9p device needs mount_tag arguments\n", - conf->fsdev_id); - 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.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; - 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; - 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 = qemu_strdup(fse->path); - len = strlen(conf->tag); - if (len > MAX_TAG_LEN) { - len = MAX_TAG_LEN; - } - /* s->tag is non-NULL terminated string */ - s->tag = qemu_malloc(len); - memcpy(s->tag, conf->tag, len); - s->tag_len = len; - s->ctx.uid = -1; - - s->ops = fse->ops; - s->vdev.get_features = virtio_9p_get_features; - s->config_size = sizeof(struct virtio_9p_config) + - s->tag_len; - s->vdev.get_config = virtio_9p_get_config; - - return &s->vdev; -} - -static int virtio_9p_init_pci(PCIDevice *pci_dev) -{ - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - VirtIODevice *vdev; - - vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf); - vdev->nvectors = proxy->nvectors; - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - 0x1009, - 0x2, - 0x00); - /* make the actual value visible */ - proxy->nvectors = vdev->nvectors; - return 0; -} - -static PCIDeviceInfo virtio_9p_info = { - .qdev.name = "virtio-9p-pci", - .qdev.size = sizeof(VirtIOPCIProxy), - .init = virtio_9p_init_pci, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag), - DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void virtio_9p_register_devices(void) -{ - pci_qdev_register(&virtio_9p_info); -} - -device_init(virtio_9p_register_devices) diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 622928fce5..27f997073a 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -504,4 +504,6 @@ static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count, return pdu_packunpack(dst, sg, sg_count, offset, size, 0); } +extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq); + #endif From 873c32139354caef3cc1013f00963cc740a6a727 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Wed, 1 Jun 2011 12:35:14 +0530 Subject: [PATCH 5/7] virtio-9p: Use relative includes for files in hw Commit 353ac78d495ef976242abd868f68d78420861c2c moved the files without fixing the include paths. It used a modified CFLAGS to add hw to the include search path, but this breaks builds where the user wants to set special CFLAGS. Long include paths also increase compilation time. Therefore this patch removes the special CFLAGS for virtio and fixes the include statements by using relative include paths. v2: Remove special CFLAGS. v3: Update needed for latest QEMU. Signed-off-by: Stefan Weil Signed-off-by: Venkateswararao Jujjuri (JV) --- Makefile.objs | 1 - Makefile.target | 2 -- hw/9pfs/virtio-9p-debug.c | 5 +++-- hw/9pfs/virtio-9p-device.c | 6 +++--- hw/9pfs/virtio-9p-local.c | 3 ++- hw/9pfs/virtio-9p-posix-acl.c | 2 +- hw/9pfs/virtio-9p-xattr-user.c | 2 +- hw/9pfs/virtio-9p-xattr.c | 2 +- hw/9pfs/virtio-9p.c | 6 +++--- 9 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Makefile.objs b/Makefile.objs index 1dc45c475a..00ffa42a98 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -292,7 +292,6 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y) 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y)) -$(addprefix 9pfs/, $(9pfs-nested-y)): CFLAGS += -I$(SRC_PATH)/hw/ ###################################################################### diff --git a/Makefile.target b/Makefile.target index 73ab0164f9..99ff3bae46 100644 --- a/Makefile.target +++ b/Makefile.target @@ -413,8 +413,6 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx qmp-commands.h: $(SRC_PATH)/qmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") -9pfs/virtio-9p-device.o: CFLAGS += -I$(SRC_PATH)/hw/ - clean: rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o rm -f *.d */*.d tcg/*.o ide/*.o 9pfs/*.o diff --git a/hw/9pfs/virtio-9p-debug.c b/hw/9pfs/virtio-9p-debug.c index 6b18842fd4..4636ad51f0 100644 --- a/hw/9pfs/virtio-9p-debug.c +++ b/hw/9pfs/virtio-9p-debug.c @@ -10,8 +10,9 @@ * the COPYING file in the top-level directory. * */ -#include "virtio.h" -#include "pc.h" + +#include "hw/virtio.h" +#include "hw/pc.h" #include "virtio-9p.h" #include "virtio-9p-debug.h" diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index f9854861aa..a2b6acc408 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -11,10 +11,10 @@ * */ -#include "virtio.h" -#include "pc.h" +#include "hw/virtio.h" +#include "hw/pc.h" #include "qemu_socket.h" -#include "virtio-pci.h" +#include "hw/virtio-pci.h" #include "virtio-9p.h" #include "fsdev/qemu-fsdev.h" #include "virtio-9p-xattr.h" diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index 0a015de9a5..3effc39316 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -10,7 +10,8 @@ * the COPYING file in the top-level directory. * */ -#include "virtio.h" + +#include "hw/virtio.h" #include "virtio-9p.h" #include "virtio-9p-xattr.h" #include diff --git a/hw/9pfs/virtio-9p-posix-acl.c b/hw/9pfs/virtio-9p-posix-acl.c index 575abe86b0..c0ae9d6fea 100644 --- a/hw/9pfs/virtio-9p-posix-acl.c +++ b/hw/9pfs/virtio-9p-posix-acl.c @@ -13,7 +13,7 @@ #include #include -#include "virtio.h" +#include "hw/virtio.h" #include "virtio-9p.h" #include "fsdev/file-op-9p.h" #include "virtio-9p-xattr.h" diff --git a/hw/9pfs/virtio-9p-xattr-user.c b/hw/9pfs/virtio-9p-xattr-user.c index bba13ce643..c56039c7f5 100644 --- a/hw/9pfs/virtio-9p-xattr-user.c +++ b/hw/9pfs/virtio-9p-xattr-user.c @@ -12,7 +12,7 @@ */ #include -#include "virtio.h" +#include "hw/virtio.h" #include "virtio-9p.h" #include "fsdev/file-op-9p.h" #include "virtio-9p-xattr.h" diff --git a/hw/9pfs/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c index 03c3d3f6bb..f08ce6ec5f 100644 --- a/hw/9pfs/virtio-9p-xattr.c +++ b/hw/9pfs/virtio-9p-xattr.c @@ -11,7 +11,7 @@ * */ -#include "virtio.h" +#include "hw/virtio.h" #include "virtio-9p.h" #include "fsdev/file-op-9p.h" #include "virtio-9p-xattr.h" diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 21865b1f24..ec97b10f49 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -11,10 +11,10 @@ * */ -#include "virtio.h" -#include "pc.h" +#include "hw/virtio.h" +#include "hw/pc.h" #include "qemu_socket.h" -#include "virtio-pci.h" +#include "hw/virtio-pci.h" #include "virtio-9p.h" #include "fsdev/qemu-fsdev.h" #include "virtio-9p-debug.h" From faa44e3d3e986f29579e0d0d07b7aef771184e8c Mon Sep 17 00:00:00 2001 From: "Venkateswararao Jujjuri (JV)" Date: Wed, 1 Jun 2011 12:35:14 +0530 Subject: [PATCH 6/7] [virtio-9p] Make rpath thread safe Current rpath inline function is heavily used in all system calls. This function has a static buffer making it a non-thread safe function. This patch introduces new thread-safe routine and makes use of it. Signed-off-by: Venkateswararao Jujjuri " --- fsdev/file-op-9p.h | 7 -- hw/9pfs/virtio-9p-local.c | 135 ++++++++++++++++----------------- hw/9pfs/virtio-9p-posix-acl.c | 20 +++-- hw/9pfs/virtio-9p-xattr-user.c | 9 ++- hw/9pfs/virtio-9p-xattr.c | 5 +- hw/9pfs/virtio-9p-xattr.h | 9 ++- hw/9pfs/virtio-9p.h | 5 ++ 7 files changed, 98 insertions(+), 92 deletions(-) diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h index 126e60e276..af9daf797f 100644 --- a/fsdev/file-op-9p.h +++ b/fsdev/file-op-9p.h @@ -97,11 +97,4 @@ typedef struct FileOperations void *opaque; } FileOperations; -static inline const char *rpath(FsContext *ctx, const char *path) -{ - /* FIXME: so wrong... */ - static char buffer[4096]; - snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path); - return buffer; -} #endif diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index 3effc39316..77904c37bd 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -25,7 +25,8 @@ static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf) { int err; - err = lstat(rpath(fs_ctx, path), stbuf); + char buffer[PATH_MAX]; + err = lstat(rpath(fs_ctx, path, buffer), stbuf); if (err) { return err; } @@ -35,19 +36,19 @@ static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf) gid_t tmp_gid; mode_t tmp_mode; dev_t tmp_dev; - if (getxattr(rpath(fs_ctx, path), "user.virtfs.uid", &tmp_uid, + if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) { stbuf->st_uid = tmp_uid; } - if (getxattr(rpath(fs_ctx, path), "user.virtfs.gid", &tmp_gid, + if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) { stbuf->st_gid = tmp_gid; } - if (getxattr(rpath(fs_ctx, path), "user.virtfs.mode", &tmp_mode, - sizeof(mode_t)) > 0) { + if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.mode", + &tmp_mode, sizeof(mode_t)) > 0) { stbuf->st_mode = tmp_mode; } - if (getxattr(rpath(fs_ctx, path), "user.virtfs.rdev", &tmp_dev, + if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) { stbuf->st_rdev = tmp_dev; } @@ -92,10 +93,12 @@ static int local_set_xattr(const char *path, FsCred *credp) static int local_post_create_passthrough(FsContext *fs_ctx, const char *path, FsCred *credp) { - if (chmod(rpath(fs_ctx, path), credp->fc_mode & 07777) < 0) { + char buffer[PATH_MAX]; + if (chmod(rpath(fs_ctx, path, buffer), credp->fc_mode & 07777) < 0) { return -1; } - if (lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid) < 0) { + if (lchown(rpath(fs_ctx, path, buffer), credp->fc_uid, + credp->fc_gid) < 0) { /* * If we fail to change ownership and if we are * using security model none. Ignore the error @@ -111,9 +114,10 @@ static ssize_t local_readlink(FsContext *fs_ctx, const char *path, char *buf, size_t bufsz) { ssize_t tsize = -1; + char buffer[PATH_MAX]; if (fs_ctx->fs_sm == SM_MAPPED) { int fd; - fd = open(rpath(fs_ctx, path), O_RDONLY); + fd = open(rpath(fs_ctx, path, buffer), O_RDONLY); if (fd == -1) { return -1; } @@ -124,7 +128,7 @@ static ssize_t local_readlink(FsContext *fs_ctx, const char *path, return tsize; } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || (fs_ctx->fs_sm == SM_NONE)) { - tsize = readlink(rpath(fs_ctx, path), buf, bufsz); + tsize = readlink(rpath(fs_ctx, path, buffer), buf, bufsz); } return tsize; } @@ -141,12 +145,14 @@ static int local_closedir(FsContext *ctx, DIR *dir) static int local_open(FsContext *ctx, const char *path, int flags) { - return open(rpath(ctx, path), flags); + char buffer[PATH_MAX]; + return open(rpath(ctx, path, buffer), flags); } static DIR *local_opendir(FsContext *ctx, const char *path) { - return opendir(rpath(ctx, path)); + char buffer[PATH_MAX]; + return opendir(rpath(ctx, path, buffer)); } static void local_rewinddir(FsContext *ctx, DIR *dir) @@ -201,11 +207,12 @@ static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov, static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp) { + char buffer[PATH_MAX]; if (fs_ctx->fs_sm == SM_MAPPED) { - return local_set_xattr(rpath(fs_ctx, path), credp); + return local_set_xattr(rpath(fs_ctx, path, buffer), credp); } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || (fs_ctx->fs_sm == SM_NONE)) { - return chmod(rpath(fs_ctx, path), credp->fc_mode); + return chmod(rpath(fs_ctx, path, buffer), credp->fc_mode); } return -1; } @@ -214,21 +221,24 @@ static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp) { int err = -1; int serrno = 0; + char buffer[PATH_MAX]; /* Determine the security model */ if (fs_ctx->fs_sm == SM_MAPPED) { - err = mknod(rpath(fs_ctx, path), SM_LOCAL_MODE_BITS|S_IFREG, 0); + err = mknod(rpath(fs_ctx, path, buffer), + SM_LOCAL_MODE_BITS|S_IFREG, 0); if (err == -1) { return err; } - local_set_xattr(rpath(fs_ctx, path), credp); + local_set_xattr(rpath(fs_ctx, path, buffer), credp); if (err == -1) { serrno = errno; goto err_end; } } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || (fs_ctx->fs_sm == SM_NONE)) { - err = mknod(rpath(fs_ctx, path), credp->fc_mode, credp->fc_rdev); + err = mknod(rpath(fs_ctx, path, buffer), credp->fc_mode, + credp->fc_rdev); if (err == -1) { return err; } @@ -241,7 +251,7 @@ static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp) return err; err_end: - remove(rpath(fs_ctx, path)); + remove(rpath(fs_ctx, path, buffer)); errno = serrno; return err; } @@ -250,22 +260,23 @@ static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp) { int err = -1; int serrno = 0; + char buffer[PATH_MAX]; /* Determine the security model */ if (fs_ctx->fs_sm == SM_MAPPED) { - err = mkdir(rpath(fs_ctx, path), SM_LOCAL_DIR_MODE_BITS); + err = mkdir(rpath(fs_ctx, path, buffer), SM_LOCAL_DIR_MODE_BITS); if (err == -1) { return err; } credp->fc_mode = credp->fc_mode|S_IFDIR; - err = local_set_xattr(rpath(fs_ctx, path), credp); + err = local_set_xattr(rpath(fs_ctx, path, buffer), credp); if (err == -1) { serrno = errno; goto err_end; } } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || (fs_ctx->fs_sm == SM_NONE)) { - err = mkdir(rpath(fs_ctx, path), credp->fc_mode); + err = mkdir(rpath(fs_ctx, path, buffer), credp->fc_mode); if (err == -1) { return err; } @@ -278,7 +289,7 @@ static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp) return err; err_end: - remove(rpath(fs_ctx, path)); + remove(rpath(fs_ctx, path, buffer)); errno = serrno; return err; } @@ -319,23 +330,24 @@ static int local_open2(FsContext *fs_ctx, const char *path, int flags, int fd = -1; int err = -1; int serrno = 0; + char buffer[PATH_MAX]; /* Determine the security model */ if (fs_ctx->fs_sm == SM_MAPPED) { - fd = open(rpath(fs_ctx, path), flags, SM_LOCAL_MODE_BITS); + fd = open(rpath(fs_ctx, path, buffer), flags, SM_LOCAL_MODE_BITS); if (fd == -1) { return fd; } credp->fc_mode = credp->fc_mode|S_IFREG; /* Set cleint credentials in xattr */ - err = local_set_xattr(rpath(fs_ctx, path), credp); + err = local_set_xattr(rpath(fs_ctx, path, buffer), credp); if (err == -1) { serrno = errno; goto err_end; } } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || (fs_ctx->fs_sm == SM_NONE)) { - fd = open(rpath(fs_ctx, path), flags, credp->fc_mode); + fd = open(rpath(fs_ctx, path, buffer), flags, credp->fc_mode); if (fd == -1) { return fd; } @@ -349,7 +361,7 @@ static int local_open2(FsContext *fs_ctx, const char *path, int flags, err_end: close(fd); - remove(rpath(fs_ctx, path)); + remove(rpath(fs_ctx, path, buffer)); errno = serrno; return err; } @@ -360,12 +372,13 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath, { int err = -1; int serrno = 0; + char buffer[PATH_MAX]; /* Determine the security model */ if (fs_ctx->fs_sm == SM_MAPPED) { int fd; ssize_t oldpath_size, write_size; - fd = open(rpath(fs_ctx, newpath), O_CREAT|O_EXCL|O_RDWR, + fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR, SM_LOCAL_MODE_BITS); if (fd == -1) { return fd; @@ -385,18 +398,19 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath, close(fd); /* Set cleint credentials in symlink's xattr */ credp->fc_mode = credp->fc_mode|S_IFLNK; - err = local_set_xattr(rpath(fs_ctx, newpath), credp); + err = local_set_xattr(rpath(fs_ctx, newpath, buffer), credp); if (err == -1) { serrno = errno; goto err_end; } } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || (fs_ctx->fs_sm == SM_NONE)) { - err = symlink(oldpath, rpath(fs_ctx, newpath)); + err = symlink(oldpath, rpath(fs_ctx, newpath, buffer)); if (err) { return err; } - err = lchown(rpath(fs_ctx, newpath), credp->fc_uid, credp->fc_gid); + err = lchown(rpath(fs_ctx, newpath, buffer), credp->fc_uid, + credp->fc_gid); if (err == -1) { /* * If we fail to change ownership and if we are @@ -412,70 +426,45 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath, return err; err_end: - remove(rpath(fs_ctx, newpath)); + remove(rpath(fs_ctx, newpath, buffer)); errno = serrno; return err; } static int local_link(FsContext *ctx, const char *oldpath, const char *newpath) { - char *tmp = qemu_strdup(rpath(ctx, oldpath)); - int err, serrno = 0; + char buffer[PATH_MAX], buffer1[PATH_MAX]; - if (tmp == NULL) { - return -ENOMEM; - } - - err = link(tmp, rpath(ctx, newpath)); - if (err == -1) { - serrno = errno; - } - - qemu_free(tmp); - - if (err == -1) { - errno = serrno; - } - - return err; + return link(rpath(ctx, oldpath, buffer), rpath(ctx, newpath, buffer1)); } static int local_truncate(FsContext *ctx, const char *path, off_t size) { - return truncate(rpath(ctx, path), size); + char buffer[PATH_MAX]; + return truncate(rpath(ctx, path, buffer), size); } static int local_rename(FsContext *ctx, const char *oldpath, const char *newpath) { - char *tmp; - int err; - - tmp = qemu_strdup(rpath(ctx, oldpath)); - - err = rename(tmp, rpath(ctx, newpath)); - if (err == -1) { - int serrno = errno; - qemu_free(tmp); - errno = serrno; - } else { - qemu_free(tmp); - } - - return err; + char buffer[PATH_MAX], buffer1[PATH_MAX]; + return rename(rpath(ctx, oldpath, buffer), rpath(ctx, newpath, buffer1)); } static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp) { + char buffer[PATH_MAX]; if ((credp->fc_uid == -1 && credp->fc_gid == -1) || (fs_ctx->fs_sm == SM_PASSTHROUGH)) { - return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid); + return lchown(rpath(fs_ctx, path, buffer), credp->fc_uid, + credp->fc_gid); } else if (fs_ctx->fs_sm == SM_MAPPED) { - return local_set_xattr(rpath(fs_ctx, path), credp); + return local_set_xattr(rpath(fs_ctx, path, buffer), credp); } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || (fs_ctx->fs_sm == SM_NONE)) { - return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid); + return lchown(rpath(fs_ctx, path, buffer), credp->fc_uid, + credp->fc_gid); } return -1; } @@ -483,12 +472,15 @@ static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp) static int local_utimensat(FsContext *s, const char *path, const struct timespec *buf) { - return qemu_utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW); + char buffer[PATH_MAX]; + return qemu_utimensat(AT_FDCWD, rpath(s, path, buffer), buf, + AT_SYMLINK_NOFOLLOW); } static int local_remove(FsContext *ctx, const char *path) { - return remove(rpath(ctx, path)); + char buffer[PATH_MAX]; + return remove(rpath(ctx, path, buffer)); } static int local_fsync(FsContext *ctx, int fd, int datasync) @@ -502,7 +494,8 @@ static int local_fsync(FsContext *ctx, int fd, int datasync) static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf) { - return statfs(rpath(s, path), stbuf); + char buffer[PATH_MAX]; + return statfs(rpath(s, path, buffer), stbuf); } static ssize_t local_lgetxattr(FsContext *ctx, const char *path, diff --git a/hw/9pfs/virtio-9p-posix-acl.c b/hw/9pfs/virtio-9p-posix-acl.c index c0ae9d6fea..f5b392e180 100644 --- a/hw/9pfs/virtio-9p-posix-acl.c +++ b/hw/9pfs/virtio-9p-posix-acl.c @@ -26,7 +26,8 @@ static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size) { - return lgetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size); + char buffer[PATH_MAX]; + return lgetxattr(rpath(ctx, path, buffer), MAP_ACL_ACCESS, value, size); } static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, @@ -50,14 +51,17 @@ static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size, int flags) { - return lsetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size, flags); + char buffer[PATH_MAX]; + return lsetxattr(rpath(ctx, path, buffer), MAP_ACL_ACCESS, value, + size, flags); } static int mp_pacl_removexattr(FsContext *ctx, const char *path, const char *name) { int ret; - ret = lremovexattr(rpath(ctx, path), MAP_ACL_ACCESS); + char buffer[PATH_MAX]; + ret = lremovexattr(rpath(ctx, path, buffer), MAP_ACL_ACCESS); if (ret == -1 && errno == ENODATA) { /* * We don't get ENODATA error when trying to remove a @@ -73,7 +77,8 @@ static int mp_pacl_removexattr(FsContext *ctx, static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size) { - return lgetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size); + char buffer[PATH_MAX]; + return lgetxattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT, value, size); } static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, @@ -97,14 +102,17 @@ static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size, int flags) { - return lsetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size, flags); + char buffer[PATH_MAX]; + return lsetxattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT, value, + size, flags); } static int mp_dacl_removexattr(FsContext *ctx, const char *path, const char *name) { int ret; - ret = lremovexattr(rpath(ctx, path), MAP_ACL_DEFAULT); + char buffer[PATH_MAX]; + ret = lremovexattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT); if (ret == -1 && errno == ENODATA) { /* * We don't get ENODATA error when trying to remove a diff --git a/hw/9pfs/virtio-9p-xattr-user.c b/hw/9pfs/virtio-9p-xattr-user.c index c56039c7f5..5044a3e5ab 100644 --- a/hw/9pfs/virtio-9p-xattr-user.c +++ b/hw/9pfs/virtio-9p-xattr-user.c @@ -21,6 +21,7 @@ static ssize_t mp_user_getxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size) { + char buffer[PATH_MAX]; if (strncmp(name, "user.virtfs.", 12) == 0) { /* * Don't allow fetch of user.virtfs namesapce @@ -29,7 +30,7 @@ static ssize_t mp_user_getxattr(FsContext *ctx, const char *path, errno = ENOATTR; return -1; } - return lgetxattr(rpath(ctx, path), name, value, size); + return lgetxattr(rpath(ctx, path, buffer), name, value, size); } static ssize_t mp_user_listxattr(FsContext *ctx, const char *path, @@ -67,6 +68,7 @@ static ssize_t mp_user_listxattr(FsContext *ctx, const char *path, static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size, int flags) { + char buffer[PATH_MAX]; if (strncmp(name, "user.virtfs.", 12) == 0) { /* * Don't allow fetch of user.virtfs namesapce @@ -75,12 +77,13 @@ static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name, errno = EACCES; return -1; } - return lsetxattr(rpath(ctx, path), name, value, size, flags); + return lsetxattr(rpath(ctx, path, buffer), name, value, size, flags); } static int mp_user_removexattr(FsContext *ctx, const char *path, const char *name) { + char buffer[PATH_MAX]; if (strncmp(name, "user.virtfs.", 12) == 0) { /* * Don't allow fetch of user.virtfs namesapce @@ -89,7 +92,7 @@ static int mp_user_removexattr(FsContext *ctx, errno = EACCES; return -1; } - return lremovexattr(rpath(ctx, path), name); + return lremovexattr(rpath(ctx, path, buffer), name); } XattrOperations mapped_user_xattr = { diff --git a/hw/9pfs/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c index f08ce6ec5f..bde0b7fb4f 100644 --- a/hw/9pfs/virtio-9p-xattr.c +++ b/hw/9pfs/virtio-9p-xattr.c @@ -66,20 +66,21 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, void *value, size_t vsize) { ssize_t size = 0; + char buffer[PATH_MAX]; void *ovalue = value; XattrOperations *xops; char *orig_value, *orig_value_start; ssize_t xattr_len, parsed_len = 0, attr_len; /* Get the actual len */ - xattr_len = llistxattr(rpath(ctx, path), value, 0); + xattr_len = llistxattr(rpath(ctx, path, buffer), value, 0); if (xattr_len <= 0) { return xattr_len; } /* Now fetch the xattr and find the actual size */ orig_value = qemu_malloc(xattr_len); - xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len); + xattr_len = llistxattr(rpath(ctx, path, buffer), orig_value, xattr_len); /* store the orig pointer */ orig_value_start = orig_value; diff --git a/hw/9pfs/virtio-9p-xattr.h b/hw/9pfs/virtio-9p-xattr.h index 2bbae2dcb5..247e414ebd 100644 --- a/hw/9pfs/virtio-9p-xattr.h +++ b/hw/9pfs/virtio-9p-xattr.h @@ -54,20 +54,23 @@ ssize_t pt_listxattr(FsContext *ctx, const char *path, char *name, void *value, static inline ssize_t pt_getxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size) { - return lgetxattr(rpath(ctx, path), name, value, size); + char buffer[PATH_MAX]; + return lgetxattr(rpath(ctx, path, buffer), name, value, size); } static inline int pt_setxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size, int flags) { - return lsetxattr(rpath(ctx, path), name, value, size, flags); + char buffer[PATH_MAX]; + return lsetxattr(rpath(ctx, path, buffer), name, value, size, flags); } static inline int pt_removexattr(FsContext *ctx, const char *path, const char *name) { - return lremovexattr(rpath(ctx, path), name); + char buffer[PATH_MAX]; + return lremovexattr(rpath(ctx, path, buffer), name); } static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path, diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 27f997073a..2bfbe622af 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -101,6 +101,11 @@ enum p9_proto_version { #define P9_NOTAG (u16)(~0) #define P9_NOFID (u32)(~0) #define P9_MAXWELEM 16 +static inline const char *rpath(FsContext *ctx, const char *path, char *buffer) +{ + snprintf(buffer, PATH_MAX, "%s/%s", ctx->fs_root, path); + return buffer; +} /* * ample room for Twrite/Rread header From 5c3234c6c037943bd4c2d643a1b8cc35f563dbdb Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 1 Jun 2011 12:35:14 +0530 Subject: [PATCH 7/7] hw/9pfs: Don't crash when we get a request with not supported 9p operation Return EOPNOTSUPP as error Signed-off-by: Aneesh Kumar K.V Signed-off-by: Venkateswararao Jujjuri (JV) --- hw/9pfs/virtio-9p.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index ec97b10f49..ed081393a9 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -3606,6 +3606,11 @@ static pdu_handler_t *pdu_handlers[] = { [P9_TREMOVE] = v9fs_remove, }; +static void v9fs_op_not_supp(V9fsState *s, V9fsPDU *pdu) +{ + complete_pdu(s, pdu, -EOPNOTSUPP); +} + static void submit_pdu(V9fsState *s, V9fsPDU *pdu) { pdu_handler_t *handler; @@ -3613,12 +3618,12 @@ static void submit_pdu(V9fsState *s, V9fsPDU *pdu) if (debug_9p_pdu) { pprint_pdu(pdu); } - - BUG_ON(pdu->id >= ARRAY_SIZE(pdu_handlers)); - - handler = pdu_handlers[pdu->id]; - BUG_ON(handler == NULL); - + if (pdu->id >= ARRAY_SIZE(pdu_handlers) || + (pdu_handlers[pdu->id] == NULL)) { + handler = v9fs_op_not_supp; + } else { + handler = pdu_handlers[pdu->id]; + } handler(s, pdu); }