diff options
Diffstat (limited to 'hw/9pfs')
-rw-r--r-- | hw/9pfs/virtio-9p-device.c | 1 | ||||
-rw-r--r-- | hw/9pfs/virtio-9p-handle.c | 17 | ||||
-rw-r--r-- | hw/9pfs/virtio-9p-local.c | 18 | ||||
-rw-r--r-- | hw/9pfs/virtio-9p.c | 22 |
4 files changed, 48 insertions, 10 deletions
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index e5b68dad5a..403eed089e 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -115,6 +115,7 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) exit(1); } + s->ctx.export_flags = fse->export_flags; s->ctx.fs_root = g_strdup(fse->path); len = strlen(conf->tag); if (len > MAX_TAG_LEN) { diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c index 5c8b5ed471..b248e44916 100644 --- a/hw/9pfs/virtio-9p-handle.c +++ b/hw/9pfs/virtio-9p-handle.c @@ -192,16 +192,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) diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index 9559ff6550..47295b7e27 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -203,16 +203,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) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index c01c31aa25..3958788248 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -80,6 +80,20 @@ 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 = oflags & ~(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; @@ -1598,10 +1612,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); } @@ -1650,8 +1661,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) { |