From 635324e83e238598e86628dba5ab62ce910e6f72 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 6 Jun 2016 11:52:34 +0200 Subject: [PATCH] 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 --- fsdev/file-op-9p.h | 3 +-- 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 +-- 9 files changed, 42 insertions(+), 55 deletions(-) diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h index 1095fcc957..5561494974 100644 --- a/fsdev/file-op-9p.h +++ b/fsdev/file-op-9p.h @@ -118,8 +118,7 @@ struct FileOperations int, FsCred *, V9fsFidOpenState *); void (*rewinddir)(FsContext *, V9fsFidOpenState *); off_t (*telldir)(FsContext *, V9fsFidOpenState *); - int (*readdir_r)(FsContext *, V9fsFidOpenState *, - struct dirent *, struct dirent **); + struct dirent * (*readdir)(FsContext *, V9fsFidOpenState *); void (*seekdir)(FsContext *, V9fsFidOpenState *, off_t); ssize_t (*preadv)(FsContext *, V9fsFidOpenState *, const struct iovec *, int, off_t); 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 *);