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 <eblake@redhat.com> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
This commit is contained in:
parent
7cde47d4a8
commit
635324e83e
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
21
hw/9pfs/9p.c
21
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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 *);
|
||||
|
|
Loading…
Reference in New Issue