From: "Dr. David Alan Gilbert" <dgilb...@redhat.com> The 'journal' is a shared block of RAM between QEMU and it's fuse daemon. It's typically a shmfs file and it's specified as:
-device vhost-user-fs-pci,chardev=char0,tag=myfs,cache-size=1G,versiontable=/dev/shm/mdvt1,journal=/dev/shm/journal1 It gets mapped into the PCI bar after the version table. Signed-off-by: Dr. David Alan Gilbert <dgilb...@redhat.com> --- hw/virtio/vhost-user-fs.c | 35 ++++++++++++++++++++-- hw/virtio/virtio-pci.c | 14 ++++++++- include/hw/virtio/vhost-user-fs.h | 4 +++ include/standard-headers/linux/virtio_fs.h | 1 + 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c index a39ecd3a16..b263f43c60 100644 --- a/hw/virtio/vhost-user-fs.c +++ b/hw/virtio/vhost-user-fs.c @@ -297,6 +297,7 @@ static void vuf_device_realize(DeviceState *dev, Error **errp) size_t len; int ret; int mdvtfd = -1; + int journalfd = -1; if (!fs->conf.chardev.chr) { error_setg(errp, "missing chardev"); @@ -361,8 +362,31 @@ static void vuf_device_realize(DeviceState *dev, Error **errp) fs->mdvt_size = statbuf.st_size; } - fprintf(stderr, "%s: cachesize=%zd mdvt_size=%zd\n", __func__, - fs->conf.cache_size, fs->mdvt_size); + if (fs->conf.journalpath) { + struct stat statbuf; + + journalfd = open(fs->conf.journalpath, O_RDWR); + if (journalfd < 0) { + error_setg_errno(errp, errno, + "Failed to open journal '%s'", + fs->conf.journalpath); + + close(mdvtfd); + return; + } + if (fstat(journalfd, &statbuf) == -1) { + error_setg_errno(errp, errno, + "Failed to stat journal '%s'", + fs->conf.journalpath); + close(mdvtfd); + close(journalfd); + return; + } + + fs->journal_size = statbuf.st_size; + } + fprintf(stderr, "%s: cachesize=%zd mdvt_size=%zd journal_size=%zd\n", + __func__, fs->conf.cache_size, fs->mdvt_size, fs->journal_size); /* We need a region with some host memory, 'ram' is the easiest */ memory_region_init_ram_nomigrate(&fs->cache, OBJECT(vdev), @@ -383,6 +407,12 @@ static void vuf_device_realize(DeviceState *dev, Error **errp) memory_region_set_readonly(&fs->mdvt, true); } + if (journalfd) { + memory_region_init_ram_from_fd(&fs->journal, OBJECT(vdev), + "virtio-fs-journal", + fs->journal_size, true, journalfd, NULL); + } + fs->vhost_user = vhost_user_init(); if (!fs->vhost_user) { error_setg(errp, "failed to initialize vhost-user"); @@ -452,6 +482,7 @@ static Property vuf_properties[] = { DEFINE_PROP_STRING("vhostfd", VHostUserFS, conf.vhostfd), DEFINE_PROP_SIZE("cache-size", VHostUserFS, conf.cache_size, 1ull << 30), DEFINE_PROP_STRING("versiontable", VHostUserFS, conf.mdvtpath), + DEFINE_PROP_STRING("journal", VHostUserFS, conf.journalpath), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index d8785b78bf..a46dd5a784 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -2687,10 +2687,12 @@ static void vhost_user_fs_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) cachesize = memory_region_size(&dev->vdev.cache); /* PCIe bar needs to be a power of 2 */ - totalsize = pow2ceil(cachesize + dev->vdev.mdvt_size); + totalsize = pow2ceil(cachesize + dev->vdev.mdvt_size + + dev->vdev.journal_size); /* The bar starts with the data/DAX cache * followed by the metadata cache. + * followed by the journal */ memory_region_init(&dev->cachebar, OBJECT(vpci_dev), "vhost-fs-pci-cachebar", totalsize); @@ -2706,6 +2708,16 @@ static void vhost_user_fs_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) VIRTIO_FS_PCI_SHMCAP_ID_VERTAB); } + if (dev->vdev.journal_size) { + memory_region_add_subregion(&dev->cachebar, + cachesize + dev->vdev.mdvt_size, + &dev->vdev.journal); + virtio_pci_add_shm_cap(vpci_dev, VIRTIO_FS_PCI_CACHE_BAR, + cachesize + dev->vdev.mdvt_size, + dev->vdev.journal_size, + VIRTIO_FS_PCI_SHMCAP_ID_JOURNAL); + } + /* After 'realized' so the memory region exists */ pci_register_bar(&vpci_dev->pci_dev, VIRTIO_FS_PCI_CACHE_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY | diff --git a/include/hw/virtio/vhost-user-fs.h b/include/hw/virtio/vhost-user-fs.h index 281ae0a52d..6d9f74a543 100644 --- a/include/hw/virtio/vhost-user-fs.h +++ b/include/hw/virtio/vhost-user-fs.h @@ -49,6 +49,7 @@ typedef struct { char *vhostfd; size_t cache_size; char *mdvtpath; + char *journalpath; } VHostUserFSConf; typedef struct { @@ -64,6 +65,9 @@ typedef struct { /* Metadata version table */ size_t mdvt_size; MemoryRegion mdvt; + /* Journal */ + size_t journal_size; + MemoryRegion journal; } VHostUserFS; /* Callbacks from the vhost-user code for slave commands */ diff --git a/include/standard-headers/linux/virtio_fs.h b/include/standard-headers/linux/virtio_fs.h index 77fa651073..0242f2a06e 100644 --- a/include/standard-headers/linux/virtio_fs.h +++ b/include/standard-headers/linux/virtio_fs.h @@ -43,5 +43,6 @@ struct virtio_fs_config { /* For the id field in virtio_pci_shm_cap */ #define VIRTIO_FS_PCI_SHMCAP_ID_CACHE 0 #define VIRTIO_FS_PCI_SHMCAP_ID_VERTAB 1 +#define VIRTIO_FS_PCI_SHMCAP_ID_JOURNAL 2 #endif /* _LINUX_VIRTIO_FS_H */ -- 2.19.2