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);
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)
.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,
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)
.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,
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)
.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,
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;
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,
.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,
typedef struct V9fsSynthOpenState {
off_t offset;
V9fsSynthNode *node;
+ struct dirent dent;
} V9fsSynthOpenState;
extern int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,
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);
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);
v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
v9fs_stat_free(&v9stat);
v9fs_path_free(&path);
- g_free(dent);
return count;
}
count += len;
v9fs_readdir_unlock(&fidp->fs.dir);
- g_free(dent);
v9fs_path_free(&path);
if (err < 0) {
return err;
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);
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);
/* 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;
}
/*
if (len < 0) {
v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
v9fs_string_free(&name);
- g_free(dent);
return len;
}
count += len;
v9fs_readdir_unlock(&fidp->fs.dir);
- g_free(dent);
if (err < 0) {
return err;
}
#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;
}
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;
}
});
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 *);