From aae91ad9ae0677395366ff1f7a3e8763fd8470f2 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 6 Jun 2016 11:52:34 +0200 Subject: 9p: some more cleanup in #include directives The "9p-attr.h" header isn't needed by 9p synth and virtio 9p. While here, also drop last references to virtio from 9p synth since it is now transport agnostic code. Signed-off-by: Greg Kurz --- hw/9pfs/9p-synth.c | 4 +--- hw/9pfs/virtio-9p-device.c | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'hw') diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c index f1475dfd6d..8e504130d9 100644 --- a/hw/9pfs/9p-synth.c +++ b/hw/9pfs/9p-synth.c @@ -1,5 +1,5 @@ /* - * Virtio 9p synthetic file system support + * 9p synthetic file system support * * Copyright IBM, Corp. 2011 * @@ -13,9 +13,7 @@ */ #include "qemu/osdep.h" -#include "hw/virtio/virtio.h" #include "9p.h" -#include "9p-xattr.h" #include "fsdev/qemu-fsdev.h" #include "9p-synth.h" #include "qemu/rcu.h" diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index a38850ee89..74a3ccbcd1 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -17,7 +17,6 @@ #include "qemu/sockets.h" #include "virtio-9p.h" #include "fsdev/qemu-fsdev.h" -#include "9p-xattr.h" #include "coth.h" #include "hw/virtio/virtio-access.h" #include "qemu/iov.h" -- cgit v1.2.3 From af8b38b0d1878950d27156fd350e5457fd8a15a1 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 6 Jun 2016 11:52:34 +0200 Subject: 9p/fsdev: remove obsolete references to virtio Most of the 9p code is now virtio agnostic. This patch does a final cleanup: - drop references to Virtio from the header comments - fix includes Also drop a couple of leading empty lines while here. Signed-off-by: Greg Kurz --- hw/9pfs/9p.h | 2 -- hw/9pfs/codir.c | 3 +-- hw/9pfs/cofile.c | 3 +-- hw/9pfs/cofs.c | 3 +-- hw/9pfs/coth.c | 1 - hw/9pfs/coth.h | 3 ++- hw/9pfs/coxattr.c | 3 +-- 7 files changed, 6 insertions(+), 12 deletions(-) (limited to 'hw') diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index 1a19418a8c..43378943cd 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -5,8 +5,6 @@ #include #include #include -#include "standard-headers/linux/virtio_9p.h" -#include "hw/virtio/virtio.h" #include "fsdev/file-op-9p.h" #include "fsdev/9p-iov-marshal.h" #include "qemu/thread.h" diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c index 91df7f7a7b..8e3ba17bae 100644 --- a/hw/9pfs/codir.c +++ b/hw/9pfs/codir.c @@ -1,6 +1,5 @@ - /* - * Virtio 9p backend + * 9p backend * * Copyright IBM, Corp. 2011 * diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c index 293483e0c9..10343c0a93 100644 --- a/hw/9pfs/cofile.c +++ b/hw/9pfs/cofile.c @@ -1,6 +1,5 @@ - /* - * Virtio 9p backend + * 9p backend * * Copyright IBM, Corp. 2011 * diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c index 18c81cb3dc..70f584fcbd 100644 --- a/hw/9pfs/cofs.c +++ b/hw/9pfs/cofs.c @@ -1,6 +1,5 @@ - /* - * Virtio 9p backend + * 9p backend * * Copyright IBM, Corp. 2011 * diff --git a/hw/9pfs/coth.c b/hw/9pfs/coth.c index 464293ef2e..9b1151b60e 100644 --- a/hw/9pfs/coth.c +++ b/hw/9pfs/coth.c @@ -16,7 +16,6 @@ #include "qemu-common.h" #include "block/thread-pool.h" #include "qemu/coroutine.h" -#include "qemu/main-loop.h" #include "coth.h" /* Called from QEMU I/O thread. */ diff --git a/hw/9pfs/coth.h b/hw/9pfs/coth.h index a911cbb165..6adc773d46 100644 --- a/hw/9pfs/coth.h +++ b/hw/9pfs/coth.h @@ -17,7 +17,8 @@ #include "qemu/thread.h" #include "qemu/coroutine.h" -#include "virtio-9p.h" +#include "qemu/main-loop.h" +#include "9p.h" /* * we want to use bottom half because we want to make sure the below diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c index 6ad96ea9f6..133c4ead37 100644 --- a/hw/9pfs/coxattr.c +++ b/hw/9pfs/coxattr.c @@ -1,6 +1,5 @@ - /* - * Virtio 9p backend + * 9p backend * * Copyright IBM, Corp. 2011 * -- cgit v1.2.3 From beff62e6836ca05be3628fcfc78ef30d738ff21d Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 6 Jun 2016 11:52:34 +0200 Subject: 9p: drop useless inclusion of hw/i386/pc.h Signed-off-by: Greg Kurz --- hw/9pfs/9p.c | 1 - hw/9pfs/virtio-9p-device.c | 1 - 2 files changed, 2 deletions(-) (limited to 'hw') diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index f5e30125fc..a71d44dc74 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -13,7 +13,6 @@ #include "qemu/osdep.h" #include "hw/virtio/virtio.h" -#include "hw/i386/pc.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/iov.h" diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index 74a3ccbcd1..494e85e029 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -13,7 +13,6 @@ #include "qemu/osdep.h" #include "hw/virtio/virtio.h" -#include "hw/i386/pc.h" #include "qemu/sockets.h" #include "virtio-9p.h" #include "fsdev/qemu-fsdev.h" -- cgit v1.2.3 From 8762a46d3637f388fd9d2463dd966814522d5689 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 6 Jun 2016 11:52:34 +0200 Subject: 9p: drop useless out: label Reviewed-by: Eric Blake Signed-off-by: Greg Kurz --- hw/9pfs/9p.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'hw') diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index a71d44dc74..42ac4d79fb 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -1642,15 +1642,15 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, } err = v9fs_co_name_to_path(pdu, &fidp->path, dent->d_name, &path); if (err < 0) { - goto out; + break; } err = v9fs_co_lstat(pdu, &path, &stbuf); if (err < 0) { - goto out; + break; } err = stat_to_v9stat(pdu, &path, &stbuf, &v9stat); if (err < 0) { - goto out; + break; } /* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */ len = pdu_marshal(pdu, 11 + count, "S", &v9stat); @@ -1667,7 +1667,7 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, v9fs_path_free(&path); saved_dir_pos = dent->d_off; } -out: + g_free(dent); v9fs_path_free(&path); if (err < 0) { -- cgit v1.2.3 From f314ea4e30a1ef87bf8845da952c6dd0bac20b95 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 6 Jun 2016 11:52:34 +0200 Subject: 9p: introduce the V9fsDir type If we are to switch back to readdir(), we need a more complex type than DIR * to be able to serialize concurrent accesses to the directory stream. This patch introduces a placeholder type and fixes all users. Reviewed-by: Eric Blake Signed-off-by: Greg Kurz --- hw/9pfs/9p-handle.c | 18 +++++++++--------- hw/9pfs/9p-local.c | 18 +++++++++--------- hw/9pfs/9p-proxy.c | 20 ++++++++++---------- hw/9pfs/9p.c | 12 ++++++------ hw/9pfs/9p.h | 6 +++++- 5 files changed, 39 insertions(+), 35 deletions(-) (limited to 'hw') diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c index 894041488a..c5df053007 100644 --- a/hw/9pfs/9p-handle.c +++ b/hw/9pfs/9p-handle.c @@ -112,7 +112,7 @@ static int handle_close(FsContext *ctx, V9fsFidOpenState *fs) static int handle_closedir(FsContext *ctx, V9fsFidOpenState *fs) { - return closedir(fs->dir); + return closedir(fs->dir.stream); } static int handle_open(FsContext *ctx, V9fsPath *fs_path, @@ -132,8 +132,8 @@ static int handle_opendir(FsContext *ctx, if (ret < 0) { return -1; } - fs->dir = fdopendir(ret); - if (!fs->dir) { + fs->dir.stream = fdopendir(ret); + if (!fs->dir.stream) { return -1; } return 0; @@ -141,24 +141,24 @@ static int handle_opendir(FsContext *ctx, static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) { - rewinddir(fs->dir); + rewinddir(fs->dir.stream); } static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs) { - return telldir(fs->dir); + return telldir(fs->dir.stream); } static int handle_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, struct dirent *entry, struct dirent **result) { - return readdir_r(fs->dir, entry, result); + return readdir_r(fs->dir.stream, entry, result); } static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) { - seekdir(fs->dir, off); + seekdir(fs->dir.stream, off); } static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs, @@ -262,7 +262,7 @@ static int handle_fstat(FsContext *fs_ctx, int fid_type, int fd; if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir); + fd = dirfd(fs->dir.stream); } else { fd = fs->fd; } @@ -409,7 +409,7 @@ static int handle_fsync(FsContext *ctx, int fid_type, int fd; if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir); + fd = dirfd(fs->dir.stream); } else { fd = fs->fd; } diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index 16f45f4854..3281acdef1 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -348,7 +348,7 @@ static int local_close(FsContext *ctx, V9fsFidOpenState *fs) static int local_closedir(FsContext *ctx, V9fsFidOpenState *fs) { - return closedir(fs->dir); + return closedir(fs->dir.stream); } static int local_open(FsContext *ctx, V9fsPath *fs_path, @@ -370,9 +370,9 @@ static int local_opendir(FsContext *ctx, char *path = fs_path->data; buffer = rpath(ctx, path); - fs->dir = opendir(buffer); + fs->dir.stream = opendir(buffer); g_free(buffer); - if (!fs->dir) { + if (!fs->dir.stream) { return -1; } return 0; @@ -380,12 +380,12 @@ static int local_opendir(FsContext *ctx, static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) { - rewinddir(fs->dir); + rewinddir(fs->dir.stream); } static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs) { - return telldir(fs->dir); + return telldir(fs->dir.stream); } static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, @@ -395,7 +395,7 @@ static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, int ret; again: - ret = readdir_r(fs->dir, entry, result); + ret = readdir_r(fs->dir.stream, entry, result); if (ctx->export_flags & V9FS_SM_MAPPED) { entry->d_type = DT_UNKNOWN; } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { @@ -411,7 +411,7 @@ again: static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) { - seekdir(fs->dir, off); + seekdir(fs->dir.stream, off); } static ssize_t local_preadv(FsContext *ctx, V9fsFidOpenState *fs, @@ -610,7 +610,7 @@ static int local_fstat(FsContext *fs_ctx, int fid_type, int err, fd; if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir); + fd = dirfd(fs->dir.stream); } else { fd = fs->fd; } @@ -998,7 +998,7 @@ static int local_fsync(FsContext *ctx, int fid_type, int fd; if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir); + fd = dirfd(fs->dir.stream); } else { fd = fs->fd; } diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c index 00a4eb2a7b..63b0747815 100644 --- a/hw/9pfs/9p-proxy.c +++ b/hw/9pfs/9p-proxy.c @@ -633,7 +633,7 @@ static int proxy_close(FsContext *ctx, V9fsFidOpenState *fs) static int proxy_closedir(FsContext *ctx, V9fsFidOpenState *fs) { - return closedir(fs->dir); + return closedir(fs->dir.stream); } static int proxy_open(FsContext *ctx, V9fsPath *fs_path, @@ -652,14 +652,14 @@ static int proxy_opendir(FsContext *ctx, { int serrno, fd; - fs->dir = NULL; + fs->dir.stream = NULL; fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY); if (fd < 0) { errno = -fd; return -1; } - fs->dir = fdopendir(fd); - if (!fs->dir) { + fs->dir.stream = fdopendir(fd); + if (!fs->dir.stream) { serrno = errno; close(fd); errno = serrno; @@ -670,24 +670,24 @@ static int proxy_opendir(FsContext *ctx, static void proxy_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) { - rewinddir(fs->dir); + rewinddir(fs->dir.stream); } static off_t proxy_telldir(FsContext *ctx, V9fsFidOpenState *fs) { - return telldir(fs->dir); + return telldir(fs->dir.stream); } static int proxy_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, struct dirent *entry, struct dirent **result) { - return readdir_r(fs->dir, entry, result); + return readdir_r(fs->dir.stream, entry, result); } static void proxy_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) { - seekdir(fs->dir, off); + seekdir(fs->dir.stream, off); } static ssize_t proxy_preadv(FsContext *ctx, V9fsFidOpenState *fs, @@ -791,7 +791,7 @@ static int proxy_fstat(FsContext *fs_ctx, int fid_type, int fd; if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir); + fd = dirfd(fs->dir.stream); } else { fd = fs->fd; } @@ -936,7 +936,7 @@ static int proxy_fsync(FsContext *ctx, int fid_type, int fd; if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir); + fd = dirfd(fs->dir.stream); } else { fd = fs->fd; } diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 42ac4d79fb..803f525a2a 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -231,7 +231,7 @@ static int v9fs_reopen_fid(V9fsPDU *pdu, V9fsFidState *f) } while (err == -EINTR && !pdu->cancelled); } } else if (f->fid_type == P9_FID_DIR) { - if (f->fs.dir == NULL) { + if (f->fs.dir.stream == NULL) { do { err = v9fs_co_opendir(pdu, f); } while (err == -EINTR && !pdu->cancelled); @@ -345,7 +345,7 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp) retval = v9fs_co_close(pdu, &fidp->fs); } } else if (fidp->fid_type == P9_FID_DIR) { - if (fidp->fs.dir != NULL) { + if (fidp->fs.dir.stream != NULL) { retval = v9fs_co_closedir(pdu, &fidp->fs); } } else if (fidp->fid_type == P9_FID_XATTR) { @@ -443,7 +443,7 @@ void v9fs_reclaim_fd(V9fsPDU *pdu) reclaim_count++; } } else if (f->fid_type == P9_FID_DIR) { - if (f->fs.dir != NULL) { + if (f->fs.dir.stream != NULL) { /* * Up the reference count so that * a clunk request won't free this fid @@ -451,8 +451,8 @@ void v9fs_reclaim_fd(V9fsPDU *pdu) f->ref++; f->rclm_lst = reclaim_list; reclaim_list = f; - f->fs_reclaim.dir = f->fs.dir; - f->fs.dir = NULL; + f->fs_reclaim.dir.stream = f->fs.dir.stream; + f->fs.dir.stream = NULL; reclaim_count++; } } @@ -1883,7 +1883,7 @@ static void v9fs_readdir(void *opaque) retval = -EINVAL; goto out_nofid; } - if (!fidp->fs.dir) { + if (!fidp->fs.dir.stream) { retval = -EINVAL; goto out; } diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index 43378943cd..92ee309ef4 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -167,13 +167,17 @@ typedef struct V9fsXattr int flags; } V9fsXattr; +typedef struct V9fsDir { + DIR *stream; +} V9fsDir; + /* * Filled by fs driver on open and other * calls. */ union V9fsFidOpenState { int fd; - DIR *dir; + V9fsDir dir; V9fsXattr xattr; /* * private pointer for fs drivers, that -- cgit v1.2.3 From 7cde47d4a89d5efefcc805788bc29133f4f3c5c7 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 6 Jun 2016 11:52:34 +0200 Subject: 9p: add locking to V9fsDir If several threads concurrently call readdir() with the same directory stream pointer, it is possible that they all get a pointer to the same dirent structure, whose content is overwritten each time readdir() is called. We must thus serialize accesses to the dirent structure. This may be achieved with a mutex like below: lock_mutex(); readdir(); // work with the dirent unlock_mutex(); This patch adds all the locking, to prepare the switch to readdir(). Reviewed-by: Eric Blake Signed-off-by: Greg Kurz --- hw/9pfs/9p.c | 21 +++++++++++++++++++++ hw/9pfs/9p.h | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'hw') diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 803f525a2a..11085f45ad 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -300,6 +300,9 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid) f->next = s->fid_list; s->fid_list = f; + v9fs_readdir_init(&f->fs.dir); + v9fs_readdir_init(&f->fs_reclaim.dir); + return f; } @@ -1636,6 +1639,9 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, while (1) { v9fs_path_init(&path); + + v9fs_readdir_lock(&fidp->fs.dir); + err = v9fs_co_readdir_r(pdu, fidp, dent, &result); if (err || !result) { break; @@ -1654,6 +1660,9 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, } /* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */ len = pdu_marshal(pdu, 11 + count, "S", &v9stat); + + v9fs_readdir_unlock(&fidp->fs.dir); + if ((len != (v9stat.size + 2)) || ((count + len) > max_count)) { /* Ran out of buffer. Set dir back to old position and return */ v9fs_co_seekdir(pdu, fidp, saved_dir_pos); @@ -1668,6 +1677,8 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, saved_dir_pos = dent->d_off; } + v9fs_readdir_unlock(&fidp->fs.dir); + g_free(dent); v9fs_path_free(&path); if (err < 0) { @@ -1815,6 +1826,8 @@ static int v9fs_do_readdir(V9fsPDU *pdu, dent = g_malloc(sizeof(struct dirent)); while (1) { + v9fs_readdir_lock(&fidp->fs.dir); + err = v9fs_co_readdir_r(pdu, fidp, dent, &result); if (err || !result) { break; @@ -1822,6 +1835,8 @@ static int v9fs_do_readdir(V9fsPDU *pdu, v9fs_string_init(&name); v9fs_string_sprintf(&name, "%s", dent->d_name); if ((count + v9fs_readdir_data_size(&name)) > max_count) { + v9fs_readdir_unlock(&fidp->fs.dir); + /* Ran out of buffer. Set dir back to old position and return */ v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_string_free(&name); @@ -1843,6 +1858,9 @@ static int v9fs_do_readdir(V9fsPDU *pdu, len = pdu_marshal(pdu, 11 + count, "Qqbs", &qid, dent->d_off, dent->d_type, &name); + + v9fs_readdir_unlock(&fidp->fs.dir); + if (len < 0) { v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_string_free(&name); @@ -1853,6 +1871,9 @@ static int v9fs_do_readdir(V9fsPDU *pdu, v9fs_string_free(&name); saved_dir_pos = dent->d_off; } + + v9fs_readdir_unlock(&fidp->fs.dir); + g_free(dent); if (err < 0) { return err; diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index 92ee309ef4..46d787627a 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -169,8 +169,24 @@ typedef struct V9fsXattr typedef struct V9fsDir { DIR *stream; + QemuMutex readdir_mutex; } V9fsDir; +static inline void v9fs_readdir_lock(V9fsDir *dir) +{ + qemu_mutex_lock(&dir->readdir_mutex); +} + +static inline void v9fs_readdir_unlock(V9fsDir *dir) +{ + qemu_mutex_unlock(&dir->readdir_mutex); +} + +static inline void v9fs_readdir_init(V9fsDir *dir) +{ + qemu_mutex_init(&dir->readdir_mutex); +} + /* * Filled by fs driver on open and other * calls. -- cgit v1.2.3 From 635324e83e238598e86628dba5ab62ce910e6f72 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 6 Jun 2016 11:52:34 +0200 Subject: 9p: switch back to readdir() This patch changes the 9p code to use readdir() again instead of readdir_r(), which is deprecated in glibc 2.24. All the locking was put in place by a previous patch. Reviewed-by: Eric Blake Signed-off-by: Greg Kurz --- hw/9pfs/9p-handle.c | 8 +++----- hw/9pfs/9p-local.c | 20 +++++++++++--------- hw/9pfs/9p-proxy.c | 8 +++----- hw/9pfs/9p-synth.c | 23 ++++++++++------------- hw/9pfs/9p-synth.h | 1 + hw/9pfs/9p.c | 21 ++++++--------------- hw/9pfs/codir.c | 10 ++++++---- hw/9pfs/coth.h | 3 +-- 8 files changed, 41 insertions(+), 53 deletions(-) (limited to 'hw') diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c index c5df053007..3d77594f92 100644 --- a/hw/9pfs/9p-handle.c +++ b/hw/9pfs/9p-handle.c @@ -149,11 +149,9 @@ static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs) return telldir(fs->dir.stream); } -static int handle_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, - struct dirent *entry, - struct dirent **result) +static struct dirent *handle_readdir(FsContext *ctx, V9fsFidOpenState *fs) { - return readdir_r(fs->dir.stream, entry, result); + return readdir(fs->dir.stream); } static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) @@ -681,7 +679,7 @@ FileOperations handle_ops = { .opendir = handle_opendir, .rewinddir = handle_rewinddir, .telldir = handle_telldir, - .readdir_r = handle_readdir_r, + .readdir = handle_readdir, .seekdir = handle_seekdir, .preadv = handle_preadv, .pwritev = handle_pwritev, diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index 3281acdef1..3f271fcbd2 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -388,25 +388,27 @@ static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs) return telldir(fs->dir.stream); } -static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, - struct dirent *entry, - struct dirent **result) +static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs) { - int ret; + struct dirent *entry; again: - ret = readdir_r(fs->dir.stream, entry, result); + entry = readdir(fs->dir.stream); + if (!entry) { + return NULL; + } + if (ctx->export_flags & V9FS_SM_MAPPED) { entry->d_type = DT_UNKNOWN; } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { - if (!ret && *result != NULL && - !strcmp(entry->d_name, VIRTFS_META_DIR)) { + if (!strcmp(entry->d_name, VIRTFS_META_DIR)) { /* skp the meta data directory */ goto again; } entry->d_type = DT_UNKNOWN; } - return ret; + + return entry; } static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) @@ -1254,7 +1256,7 @@ FileOperations local_ops = { .opendir = local_opendir, .rewinddir = local_rewinddir, .telldir = local_telldir, - .readdir_r = local_readdir_r, + .readdir = local_readdir, .seekdir = local_seekdir, .preadv = local_preadv, .pwritev = local_pwritev, diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c index 63b0747815..f265501eac 100644 --- a/hw/9pfs/9p-proxy.c +++ b/hw/9pfs/9p-proxy.c @@ -678,11 +678,9 @@ static off_t proxy_telldir(FsContext *ctx, V9fsFidOpenState *fs) return telldir(fs->dir.stream); } -static int proxy_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, - struct dirent *entry, - struct dirent **result) +static struct dirent *proxy_readdir(FsContext *ctx, V9fsFidOpenState *fs) { - return readdir_r(fs->dir.stream, entry, result); + return readdir(fs->dir.stream); } static void proxy_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) @@ -1192,7 +1190,7 @@ FileOperations proxy_ops = { .opendir = proxy_opendir, .rewinddir = proxy_rewinddir, .telldir = proxy_telldir, - .readdir_r = proxy_readdir_r, + .readdir = proxy_readdir, .seekdir = proxy_seekdir, .preadv = proxy_preadv, .pwritev = proxy_pwritev, diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c index 8e504130d9..73c8be816b 100644 --- a/hw/9pfs/9p-synth.c +++ b/hw/9pfs/9p-synth.c @@ -223,8 +223,8 @@ static void v9fs_synth_direntry(V9fsSynthNode *node, entry->d_off = off + 1; } -static int v9fs_synth_get_dentry(V9fsSynthNode *dir, struct dirent *entry, - struct dirent **result, off_t off) +static struct dirent *v9fs_synth_get_dentry(V9fsSynthNode *dir, + struct dirent *entry, off_t off) { int i = 0; V9fsSynthNode *node; @@ -240,25 +240,22 @@ static int v9fs_synth_get_dentry(V9fsSynthNode *dir, struct dirent *entry, rcu_read_unlock(); if (!node) { /* end of directory */ - *result = NULL; - return 0; + return NULL; } v9fs_synth_direntry(node, entry, off); - *result = entry; - return 0; + return entry; } -static int v9fs_synth_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, - struct dirent *entry, struct dirent **result) +static struct dirent *v9fs_synth_readdir(FsContext *ctx, V9fsFidOpenState *fs) { - int ret; + struct dirent *entry; V9fsSynthOpenState *synth_open = fs->private; V9fsSynthNode *node = synth_open->node; - ret = v9fs_synth_get_dentry(node, entry, result, synth_open->offset); - if (!ret && *result != NULL) { + entry = v9fs_synth_get_dentry(node, &synth_open->dent, synth_open->offset); + if (entry) { synth_open->offset++; } - return ret; + return entry; } static int v9fs_synth_open(FsContext *ctx, V9fsPath *fs_path, @@ -544,7 +541,7 @@ FileOperations synth_ops = { .opendir = v9fs_synth_opendir, .rewinddir = v9fs_synth_rewinddir, .telldir = v9fs_synth_telldir, - .readdir_r = v9fs_synth_readdir_r, + .readdir = v9fs_synth_readdir, .seekdir = v9fs_synth_seekdir, .preadv = v9fs_synth_preadv, .pwritev = v9fs_synth_pwritev, diff --git a/hw/9pfs/9p-synth.h b/hw/9pfs/9p-synth.h index 82962512a1..7c8441bd6c 100644 --- a/hw/9pfs/9p-synth.h +++ b/hw/9pfs/9p-synth.h @@ -40,6 +40,7 @@ struct V9fsSynthNode { typedef struct V9fsSynthOpenState { off_t offset; V9fsSynthNode *node; + struct dirent dent; } V9fsSynthOpenState; extern int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode, diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 11085f45ad..9acff9293c 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -1627,7 +1627,7 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, int32_t count = 0; struct stat stbuf; off_t saved_dir_pos; - struct dirent *dent, *result; + struct dirent *dent; /* save the directory position */ saved_dir_pos = v9fs_co_telldir(pdu, fidp); @@ -1635,15 +1635,13 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, return saved_dir_pos; } - dent = g_malloc(sizeof(struct dirent)); - while (1) { v9fs_path_init(&path); v9fs_readdir_lock(&fidp->fs.dir); - err = v9fs_co_readdir_r(pdu, fidp, dent, &result); - if (err || !result) { + err = v9fs_co_readdir(pdu, fidp, &dent); + if (err || !dent) { break; } err = v9fs_co_name_to_path(pdu, &fidp->path, dent->d_name, &path); @@ -1668,7 +1666,6 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_stat_free(&v9stat); v9fs_path_free(&path); - g_free(dent); return count; } count += len; @@ -1679,7 +1676,6 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, v9fs_readdir_unlock(&fidp->fs.dir); - g_free(dent); v9fs_path_free(&path); if (err < 0) { return err; @@ -1815,7 +1811,7 @@ static int v9fs_do_readdir(V9fsPDU *pdu, int len, err = 0; int32_t count = 0; off_t saved_dir_pos; - struct dirent *dent, *result; + struct dirent *dent; /* save the directory position */ saved_dir_pos = v9fs_co_telldir(pdu, fidp); @@ -1823,13 +1819,11 @@ static int v9fs_do_readdir(V9fsPDU *pdu, return saved_dir_pos; } - dent = g_malloc(sizeof(struct dirent)); - while (1) { v9fs_readdir_lock(&fidp->fs.dir); - err = v9fs_co_readdir_r(pdu, fidp, dent, &result); - if (err || !result) { + err = v9fs_co_readdir(pdu, fidp, &dent); + if (err || !dent) { break; } v9fs_string_init(&name); @@ -1840,7 +1834,6 @@ static int v9fs_do_readdir(V9fsPDU *pdu, /* Ran out of buffer. Set dir back to old position and return */ v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_string_free(&name); - g_free(dent); return count; } /* @@ -1864,7 +1857,6 @@ static int v9fs_do_readdir(V9fsPDU *pdu, if (len < 0) { v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_string_free(&name); - g_free(dent); return len; } count += len; @@ -1874,7 +1866,6 @@ static int v9fs_do_readdir(V9fsPDU *pdu, v9fs_readdir_unlock(&fidp->fs.dir); - g_free(dent); if (err < 0) { return err; } diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c index 8e3ba17bae..d91f9ad6eb 100644 --- a/hw/9pfs/codir.c +++ b/hw/9pfs/codir.c @@ -17,8 +17,7 @@ #include "qemu/coroutine.h" #include "coth.h" -int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent, - struct dirent **result) +int v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent **dent) { int err; V9fsState *s = pdu->s; @@ -28,11 +27,14 @@ int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent, } v9fs_co_run_in_worker( { + struct dirent *entry; + errno = 0; - err = s->ops->readdir_r(&s->ctx, &fidp->fs, dent, result); - if (!*result && errno) { + entry = s->ops->readdir(&s->ctx, &fidp->fs); + if (!entry && errno) { err = -errno; } else { + *dent = entry; err = 0; } }); diff --git a/hw/9pfs/coth.h b/hw/9pfs/coth.h index 6adc773d46..5b02a63ad9 100644 --- a/hw/9pfs/coth.h +++ b/hw/9pfs/coth.h @@ -49,8 +49,7 @@ extern void co_run_in_worker_bh(void *); extern int v9fs_co_readlink(V9fsPDU *, V9fsPath *, V9fsString *); -extern int v9fs_co_readdir_r(V9fsPDU *, V9fsFidState *, - struct dirent *, struct dirent **result); +extern int v9fs_co_readdir(V9fsPDU *, V9fsFidState *, struct dirent **); extern off_t v9fs_co_telldir(V9fsPDU *, V9fsFidState *); extern void v9fs_co_seekdir(V9fsPDU *, V9fsFidState *, off_t); extern void v9fs_co_rewinddir(V9fsPDU *, V9fsFidState *); -- cgit v1.2.3