readdir_r() to readdir() conversion, various minor cleanups

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iEYEABECAAYFAldVR/QACgkQAvw66wEB28JwVQCgiTy4bpShd9GiFgJ+eoSgJnt5
 lLcAn3rnv44g0SpW5M7aK4I8RzyEig0X
 =vbbR
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging

readdir_r() to readdir() conversion, various minor cleanups

# gpg: Signature made Mon 06 Jun 2016 10:52:52 BST
# gpg:                using DSA key 0x02FC3AEB0101DBC2
# gpg: Good signature from "Greg Kurz <gkurz@fr.ibm.com>"
# gpg:                 aka "Greg Kurz <groug@free.fr>"
# gpg:                 aka "Greg Kurz <gkurz@linux.vnet.ibm.com>"
# gpg:                 aka "Gregory Kurz (Groug) <groug@free.fr>"
# gpg:                 aka "Gregory Kurz (Cimai Technology) <gkurz@cimai.com>"
# gpg:                 aka "Gregory Kurz (Meiosys Technology) <gkurz@meiosys.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 2BD4 3B44 535E C0A7 9894  DBA2 02FC 3AEB 0101 DBC2

* remotes/gkurz/tags/for-upstream:
  9p: switch back to readdir()
  9p: add locking to V9fsDir
  9p: introduce the V9fsDir type
  9p: drop useless out: label
  9p: drop useless inclusion of hw/i386/pc.h
  9p/fsdev: remove obsolete references to virtio
  9p: some more cleanup in #include directives

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2016-06-06 15:17:52 +01:00
commit 280b2358cd
19 changed files with 131 additions and 114 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Virtio 9p * 9p
* *
* Copyright IBM, Corp. 2010 * Copyright IBM, Corp. 2010
* *
@ -118,8 +118,7 @@ struct FileOperations
int, FsCred *, V9fsFidOpenState *); int, FsCred *, V9fsFidOpenState *);
void (*rewinddir)(FsContext *, V9fsFidOpenState *); void (*rewinddir)(FsContext *, V9fsFidOpenState *);
off_t (*telldir)(FsContext *, V9fsFidOpenState *); off_t (*telldir)(FsContext *, V9fsFidOpenState *);
int (*readdir_r)(FsContext *, V9fsFidOpenState *, struct dirent * (*readdir)(FsContext *, V9fsFidOpenState *);
struct dirent *, struct dirent **);
void (*seekdir)(FsContext *, V9fsFidOpenState *, off_t); void (*seekdir)(FsContext *, V9fsFidOpenState *, off_t);
ssize_t (*preadv)(FsContext *, V9fsFidOpenState *, ssize_t (*preadv)(FsContext *, V9fsFidOpenState *,
const struct iovec *, int, off_t); const struct iovec *, int, off_t);

View File

@ -1,5 +1,5 @@
/* /*
* Virtio 9p * 9p
* *
* Copyright IBM, Corp. 2010 * Copyright IBM, Corp. 2010
* *

View File

@ -1,5 +1,5 @@
/* /*
* Virtio 9p * 9p
* *
* This work is licensed under the terms of the GNU GPL, version 2 or * This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory. * later. See the COPYING file in the top-level directory.

View File

@ -1,5 +1,5 @@
/* /*
* Virtio 9p * 9p
* *
* Copyright IBM, Corp. 2010 * Copyright IBM, Corp. 2010
* *

View File

@ -1,5 +1,5 @@
/* /*
* Virtio 9p * 9p
* *
* Copyright IBM, Corp. 2010 * Copyright IBM, Corp. 2010
* *

View File

@ -112,7 +112,7 @@ static int handle_close(FsContext *ctx, V9fsFidOpenState *fs)
static int handle_closedir(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, static int handle_open(FsContext *ctx, V9fsPath *fs_path,
@ -132,8 +132,8 @@ static int handle_opendir(FsContext *ctx,
if (ret < 0) { if (ret < 0) {
return -1; return -1;
} }
fs->dir = fdopendir(ret); fs->dir.stream = fdopendir(ret);
if (!fs->dir) { if (!fs->dir.stream) {
return -1; return -1;
} }
return 0; return 0;
@ -141,24 +141,22 @@ static int handle_opendir(FsContext *ctx,
static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
{ {
rewinddir(fs->dir); rewinddir(fs->dir.stream);
} }
static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs) 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, static struct dirent *handle_readdir(FsContext *ctx, V9fsFidOpenState *fs)
struct dirent *entry,
struct dirent **result)
{ {
return readdir_r(fs->dir, entry, result); return readdir(fs->dir.stream);
} }
static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) 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, static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@ -262,7 +260,7 @@ static int handle_fstat(FsContext *fs_ctx, int fid_type,
int fd; int fd;
if (fid_type == P9_FID_DIR) { if (fid_type == P9_FID_DIR) {
fd = dirfd(fs->dir); fd = dirfd(fs->dir.stream);
} else { } else {
fd = fs->fd; fd = fs->fd;
} }
@ -409,7 +407,7 @@ static int handle_fsync(FsContext *ctx, int fid_type,
int fd; int fd;
if (fid_type == P9_FID_DIR) { if (fid_type == P9_FID_DIR) {
fd = dirfd(fs->dir); fd = dirfd(fs->dir.stream);
} else { } else {
fd = fs->fd; fd = fs->fd;
} }
@ -681,7 +679,7 @@ FileOperations handle_ops = {
.opendir = handle_opendir, .opendir = handle_opendir,
.rewinddir = handle_rewinddir, .rewinddir = handle_rewinddir,
.telldir = handle_telldir, .telldir = handle_telldir,
.readdir_r = handle_readdir_r, .readdir = handle_readdir,
.seekdir = handle_seekdir, .seekdir = handle_seekdir,
.preadv = handle_preadv, .preadv = handle_preadv,
.pwritev = handle_pwritev, .pwritev = handle_pwritev,

View File

@ -348,7 +348,7 @@ static int local_close(FsContext *ctx, V9fsFidOpenState *fs)
static int local_closedir(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, static int local_open(FsContext *ctx, V9fsPath *fs_path,
@ -370,9 +370,9 @@ static int local_opendir(FsContext *ctx,
char *path = fs_path->data; char *path = fs_path->data;
buffer = rpath(ctx, path); buffer = rpath(ctx, path);
fs->dir = opendir(buffer); fs->dir.stream = opendir(buffer);
g_free(buffer); g_free(buffer);
if (!fs->dir) { if (!fs->dir.stream) {
return -1; return -1;
} }
return 0; return 0;
@ -380,38 +380,40 @@ static int local_opendir(FsContext *ctx,
static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
{ {
rewinddir(fs->dir); rewinddir(fs->dir.stream);
} }
static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs) 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, static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
struct dirent *entry,
struct dirent **result)
{ {
int ret; struct dirent *entry;
again: again:
ret = readdir_r(fs->dir, entry, result); entry = readdir(fs->dir.stream);
if (!entry) {
return NULL;
}
if (ctx->export_flags & V9FS_SM_MAPPED) { if (ctx->export_flags & V9FS_SM_MAPPED) {
entry->d_type = DT_UNKNOWN; entry->d_type = DT_UNKNOWN;
} else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
if (!ret && *result != NULL && if (!strcmp(entry->d_name, VIRTFS_META_DIR)) {
!strcmp(entry->d_name, VIRTFS_META_DIR)) {
/* skp the meta data directory */ /* skp the meta data directory */
goto again; goto again;
} }
entry->d_type = DT_UNKNOWN; entry->d_type = DT_UNKNOWN;
} }
return ret;
return entry;
} }
static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) 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, static ssize_t local_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@ -610,7 +612,7 @@ static int local_fstat(FsContext *fs_ctx, int fid_type,
int err, fd; int err, fd;
if (fid_type == P9_FID_DIR) { if (fid_type == P9_FID_DIR) {
fd = dirfd(fs->dir); fd = dirfd(fs->dir.stream);
} else { } else {
fd = fs->fd; fd = fs->fd;
} }
@ -998,7 +1000,7 @@ static int local_fsync(FsContext *ctx, int fid_type,
int fd; int fd;
if (fid_type == P9_FID_DIR) { if (fid_type == P9_FID_DIR) {
fd = dirfd(fs->dir); fd = dirfd(fs->dir.stream);
} else { } else {
fd = fs->fd; fd = fs->fd;
} }
@ -1254,7 +1256,7 @@ FileOperations local_ops = {
.opendir = local_opendir, .opendir = local_opendir,
.rewinddir = local_rewinddir, .rewinddir = local_rewinddir,
.telldir = local_telldir, .telldir = local_telldir,
.readdir_r = local_readdir_r, .readdir = local_readdir,
.seekdir = local_seekdir, .seekdir = local_seekdir,
.preadv = local_preadv, .preadv = local_preadv,
.pwritev = local_pwritev, .pwritev = local_pwritev,

View File

@ -633,7 +633,7 @@ static int proxy_close(FsContext *ctx, V9fsFidOpenState *fs)
static int proxy_closedir(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, static int proxy_open(FsContext *ctx, V9fsPath *fs_path,
@ -652,14 +652,14 @@ static int proxy_opendir(FsContext *ctx,
{ {
int serrno, fd; int serrno, fd;
fs->dir = NULL; fs->dir.stream = NULL;
fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY); fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY);
if (fd < 0) { if (fd < 0) {
errno = -fd; errno = -fd;
return -1; return -1;
} }
fs->dir = fdopendir(fd); fs->dir.stream = fdopendir(fd);
if (!fs->dir) { if (!fs->dir.stream) {
serrno = errno; serrno = errno;
close(fd); close(fd);
errno = serrno; errno = serrno;
@ -670,24 +670,22 @@ static int proxy_opendir(FsContext *ctx,
static void proxy_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) static void proxy_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
{ {
rewinddir(fs->dir); rewinddir(fs->dir.stream);
} }
static off_t proxy_telldir(FsContext *ctx, V9fsFidOpenState *fs) 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, static struct dirent *proxy_readdir(FsContext *ctx, V9fsFidOpenState *fs)
struct dirent *entry,
struct dirent **result)
{ {
return readdir_r(fs->dir, entry, result); return readdir(fs->dir.stream);
} }
static void proxy_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) 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, static ssize_t proxy_preadv(FsContext *ctx, V9fsFidOpenState *fs,
@ -791,7 +789,7 @@ static int proxy_fstat(FsContext *fs_ctx, int fid_type,
int fd; int fd;
if (fid_type == P9_FID_DIR) { if (fid_type == P9_FID_DIR) {
fd = dirfd(fs->dir); fd = dirfd(fs->dir.stream);
} else { } else {
fd = fs->fd; fd = fs->fd;
} }
@ -936,7 +934,7 @@ static int proxy_fsync(FsContext *ctx, int fid_type,
int fd; int fd;
if (fid_type == P9_FID_DIR) { if (fid_type == P9_FID_DIR) {
fd = dirfd(fs->dir); fd = dirfd(fs->dir.stream);
} else { } else {
fd = fs->fd; fd = fs->fd;
} }
@ -1192,7 +1190,7 @@ FileOperations proxy_ops = {
.opendir = proxy_opendir, .opendir = proxy_opendir,
.rewinddir = proxy_rewinddir, .rewinddir = proxy_rewinddir,
.telldir = proxy_telldir, .telldir = proxy_telldir,
.readdir_r = proxy_readdir_r, .readdir = proxy_readdir,
.seekdir = proxy_seekdir, .seekdir = proxy_seekdir,
.preadv = proxy_preadv, .preadv = proxy_preadv,
.pwritev = proxy_pwritev, .pwritev = proxy_pwritev,

View File

@ -1,5 +1,5 @@
/* /*
* Virtio 9p synthetic file system support * 9p synthetic file system support
* *
* Copyright IBM, Corp. 2011 * Copyright IBM, Corp. 2011
* *
@ -13,9 +13,7 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "hw/virtio/virtio.h"
#include "9p.h" #include "9p.h"
#include "9p-xattr.h"
#include "fsdev/qemu-fsdev.h" #include "fsdev/qemu-fsdev.h"
#include "9p-synth.h" #include "9p-synth.h"
#include "qemu/rcu.h" #include "qemu/rcu.h"
@ -225,8 +223,8 @@ static void v9fs_synth_direntry(V9fsSynthNode *node,
entry->d_off = off + 1; entry->d_off = off + 1;
} }
static int v9fs_synth_get_dentry(V9fsSynthNode *dir, struct dirent *entry, static struct dirent *v9fs_synth_get_dentry(V9fsSynthNode *dir,
struct dirent **result, off_t off) struct dirent *entry, off_t off)
{ {
int i = 0; int i = 0;
V9fsSynthNode *node; V9fsSynthNode *node;
@ -242,25 +240,22 @@ static int v9fs_synth_get_dentry(V9fsSynthNode *dir, struct dirent *entry,
rcu_read_unlock(); rcu_read_unlock();
if (!node) { if (!node) {
/* end of directory */ /* end of directory */
*result = NULL; return NULL;
return 0;
} }
v9fs_synth_direntry(node, entry, off); v9fs_synth_direntry(node, entry, off);
*result = entry; return entry;
return 0;
} }
static int v9fs_synth_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, static struct dirent *v9fs_synth_readdir(FsContext *ctx, V9fsFidOpenState *fs)
struct dirent *entry, struct dirent **result)
{ {
int ret; struct dirent *entry;
V9fsSynthOpenState *synth_open = fs->private; V9fsSynthOpenState *synth_open = fs->private;
V9fsSynthNode *node = synth_open->node; V9fsSynthNode *node = synth_open->node;
ret = v9fs_synth_get_dentry(node, entry, result, synth_open->offset); entry = v9fs_synth_get_dentry(node, &synth_open->dent, synth_open->offset);
if (!ret && *result != NULL) { if (entry) {
synth_open->offset++; synth_open->offset++;
} }
return ret; return entry;
} }
static int v9fs_synth_open(FsContext *ctx, V9fsPath *fs_path, static int v9fs_synth_open(FsContext *ctx, V9fsPath *fs_path,
@ -546,7 +541,7 @@ FileOperations synth_ops = {
.opendir = v9fs_synth_opendir, .opendir = v9fs_synth_opendir,
.rewinddir = v9fs_synth_rewinddir, .rewinddir = v9fs_synth_rewinddir,
.telldir = v9fs_synth_telldir, .telldir = v9fs_synth_telldir,
.readdir_r = v9fs_synth_readdir_r, .readdir = v9fs_synth_readdir,
.seekdir = v9fs_synth_seekdir, .seekdir = v9fs_synth_seekdir,
.preadv = v9fs_synth_preadv, .preadv = v9fs_synth_preadv,
.pwritev = v9fs_synth_pwritev, .pwritev = v9fs_synth_pwritev,

View File

@ -40,6 +40,7 @@ struct V9fsSynthNode {
typedef struct V9fsSynthOpenState { typedef struct V9fsSynthOpenState {
off_t offset; off_t offset;
V9fsSynthNode *node; V9fsSynthNode *node;
struct dirent dent;
} V9fsSynthOpenState; } V9fsSynthOpenState;
extern int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode, extern int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,

View File

@ -13,7 +13,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "hw/virtio/virtio.h" #include "hw/virtio/virtio.h"
#include "hw/i386/pc.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "qemu/iov.h" #include "qemu/iov.h"
@ -232,7 +231,7 @@ static int v9fs_reopen_fid(V9fsPDU *pdu, V9fsFidState *f)
} while (err == -EINTR && !pdu->cancelled); } while (err == -EINTR && !pdu->cancelled);
} }
} else if (f->fid_type == P9_FID_DIR) { } else if (f->fid_type == P9_FID_DIR) {
if (f->fs.dir == NULL) { if (f->fs.dir.stream == NULL) {
do { do {
err = v9fs_co_opendir(pdu, f); err = v9fs_co_opendir(pdu, f);
} while (err == -EINTR && !pdu->cancelled); } while (err == -EINTR && !pdu->cancelled);
@ -301,6 +300,9 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
f->next = s->fid_list; f->next = s->fid_list;
s->fid_list = f; s->fid_list = f;
v9fs_readdir_init(&f->fs.dir);
v9fs_readdir_init(&f->fs_reclaim.dir);
return f; return f;
} }
@ -346,7 +348,7 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp)
retval = v9fs_co_close(pdu, &fidp->fs); retval = v9fs_co_close(pdu, &fidp->fs);
} }
} else if (fidp->fid_type == P9_FID_DIR) { } 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); retval = v9fs_co_closedir(pdu, &fidp->fs);
} }
} else if (fidp->fid_type == P9_FID_XATTR) { } else if (fidp->fid_type == P9_FID_XATTR) {
@ -444,7 +446,7 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
reclaim_count++; reclaim_count++;
} }
} else if (f->fid_type == P9_FID_DIR) { } 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 * Up the reference count so that
* a clunk request won't free this fid * a clunk request won't free this fid
@ -452,8 +454,8 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
f->ref++; f->ref++;
f->rclm_lst = reclaim_list; f->rclm_lst = reclaim_list;
reclaim_list = f; reclaim_list = f;
f->fs_reclaim.dir = f->fs.dir; f->fs_reclaim.dir.stream = f->fs.dir.stream;
f->fs.dir = NULL; f->fs.dir.stream = NULL;
reclaim_count++; reclaim_count++;
} }
} }
@ -1625,7 +1627,7 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
int32_t count = 0; int32_t count = 0;
struct stat stbuf; struct stat stbuf;
off_t saved_dir_pos; off_t saved_dir_pos;
struct dirent *dent, *result; struct dirent *dent;
/* save the directory position */ /* save the directory position */
saved_dir_pos = v9fs_co_telldir(pdu, fidp); saved_dir_pos = v9fs_co_telldir(pdu, fidp);
@ -1633,34 +1635,37 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
return saved_dir_pos; return saved_dir_pos;
} }
dent = g_malloc(sizeof(struct dirent));
while (1) { while (1) {
v9fs_path_init(&path); v9fs_path_init(&path);
err = v9fs_co_readdir_r(pdu, fidp, dent, &result);
if (err || !result) { v9fs_readdir_lock(&fidp->fs.dir);
err = v9fs_co_readdir(pdu, fidp, &dent);
if (err || !dent) {
break; break;
} }
err = v9fs_co_name_to_path(pdu, &fidp->path, dent->d_name, &path); err = v9fs_co_name_to_path(pdu, &fidp->path, dent->d_name, &path);
if (err < 0) { if (err < 0) {
goto out; break;
} }
err = v9fs_co_lstat(pdu, &path, &stbuf); err = v9fs_co_lstat(pdu, &path, &stbuf);
if (err < 0) { if (err < 0) {
goto out; break;
} }
err = stat_to_v9stat(pdu, &path, &stbuf, &v9stat); err = stat_to_v9stat(pdu, &path, &stbuf, &v9stat);
if (err < 0) { if (err < 0) {
goto out; break;
} }
/* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */ /* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */
len = pdu_marshal(pdu, 11 + count, "S", &v9stat); len = pdu_marshal(pdu, 11 + count, "S", &v9stat);
v9fs_readdir_unlock(&fidp->fs.dir);
if ((len != (v9stat.size + 2)) || ((count + len) > max_count)) { if ((len != (v9stat.size + 2)) || ((count + len) > max_count)) {
/* Ran out of buffer. Set dir back to old position and return */ /* Ran out of buffer. Set dir back to old position and return */
v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
v9fs_stat_free(&v9stat); v9fs_stat_free(&v9stat);
v9fs_path_free(&path); v9fs_path_free(&path);
g_free(dent);
return count; return count;
} }
count += len; count += len;
@ -1668,8 +1673,9 @@ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
v9fs_path_free(&path); v9fs_path_free(&path);
saved_dir_pos = dent->d_off; saved_dir_pos = dent->d_off;
} }
out:
g_free(dent); v9fs_readdir_unlock(&fidp->fs.dir);
v9fs_path_free(&path); v9fs_path_free(&path);
if (err < 0) { if (err < 0) {
return err; return err;
@ -1805,7 +1811,7 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
int len, err = 0; int len, err = 0;
int32_t count = 0; int32_t count = 0;
off_t saved_dir_pos; off_t saved_dir_pos;
struct dirent *dent, *result; struct dirent *dent;
/* save the directory position */ /* save the directory position */
saved_dir_pos = v9fs_co_telldir(pdu, fidp); saved_dir_pos = v9fs_co_telldir(pdu, fidp);
@ -1813,20 +1819,21 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
return saved_dir_pos; return saved_dir_pos;
} }
dent = g_malloc(sizeof(struct dirent));
while (1) { while (1) {
err = v9fs_co_readdir_r(pdu, fidp, dent, &result); v9fs_readdir_lock(&fidp->fs.dir);
if (err || !result) {
err = v9fs_co_readdir(pdu, fidp, &dent);
if (err || !dent) {
break; break;
} }
v9fs_string_init(&name); v9fs_string_init(&name);
v9fs_string_sprintf(&name, "%s", dent->d_name); v9fs_string_sprintf(&name, "%s", dent->d_name);
if ((count + v9fs_readdir_data_size(&name)) > max_count) { 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 */ /* Ran out of buffer. Set dir back to old position and return */
v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
v9fs_string_free(&name); v9fs_string_free(&name);
g_free(dent);
return count; return count;
} }
/* /*
@ -1844,17 +1851,21 @@ static int v9fs_do_readdir(V9fsPDU *pdu,
len = pdu_marshal(pdu, 11 + count, "Qqbs", len = pdu_marshal(pdu, 11 + count, "Qqbs",
&qid, dent->d_off, &qid, dent->d_off,
dent->d_type, &name); dent->d_type, &name);
v9fs_readdir_unlock(&fidp->fs.dir);
if (len < 0) { if (len < 0) {
v9fs_co_seekdir(pdu, fidp, saved_dir_pos); v9fs_co_seekdir(pdu, fidp, saved_dir_pos);
v9fs_string_free(&name); v9fs_string_free(&name);
g_free(dent);
return len; return len;
} }
count += len; count += len;
v9fs_string_free(&name); v9fs_string_free(&name);
saved_dir_pos = dent->d_off; saved_dir_pos = dent->d_off;
} }
g_free(dent);
v9fs_readdir_unlock(&fidp->fs.dir);
if (err < 0) { if (err < 0) {
return err; return err;
} }
@ -1884,7 +1895,7 @@ static void v9fs_readdir(void *opaque)
retval = -EINVAL; retval = -EINVAL;
goto out_nofid; goto out_nofid;
} }
if (!fidp->fs.dir) { if (!fidp->fs.dir.stream) {
retval = -EINVAL; retval = -EINVAL;
goto out; goto out;
} }

View File

@ -5,8 +5,6 @@
#include <utime.h> #include <utime.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <glib.h> #include <glib.h>
#include "standard-headers/linux/virtio_9p.h"
#include "hw/virtio/virtio.h"
#include "fsdev/file-op-9p.h" #include "fsdev/file-op-9p.h"
#include "fsdev/9p-iov-marshal.h" #include "fsdev/9p-iov-marshal.h"
#include "qemu/thread.h" #include "qemu/thread.h"
@ -169,13 +167,33 @@ typedef struct V9fsXattr
int flags; int flags;
} V9fsXattr; } 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 * Filled by fs driver on open and other
* calls. * calls.
*/ */
union V9fsFidOpenState { union V9fsFidOpenState {
int fd; int fd;
DIR *dir; V9fsDir dir;
V9fsXattr xattr; V9fsXattr xattr;
/* /*
* private pointer for fs drivers, that * private pointer for fs drivers, that

View File

@ -1,6 +1,5 @@
/* /*
* Virtio 9p backend * 9p backend
* *
* Copyright IBM, Corp. 2011 * Copyright IBM, Corp. 2011
* *
@ -18,8 +17,7 @@
#include "qemu/coroutine.h" #include "qemu/coroutine.h"
#include "coth.h" #include "coth.h"
int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent, int v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent **dent)
struct dirent **result)
{ {
int err; int err;
V9fsState *s = pdu->s; V9fsState *s = pdu->s;
@ -29,11 +27,14 @@ int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
} }
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
struct dirent *entry;
errno = 0; errno = 0;
err = s->ops->readdir_r(&s->ctx, &fidp->fs, dent, result); entry = s->ops->readdir(&s->ctx, &fidp->fs);
if (!*result && errno) { if (!entry && errno) {
err = -errno; err = -errno;
} else { } else {
*dent = entry;
err = 0; err = 0;
} }
}); });

View File

@ -1,6 +1,5 @@
/* /*
* Virtio 9p backend * 9p backend
* *
* Copyright IBM, Corp. 2011 * Copyright IBM, Corp. 2011
* *

View File

@ -1,6 +1,5 @@
/* /*
* Virtio 9p backend * 9p backend
* *
* Copyright IBM, Corp. 2011 * Copyright IBM, Corp. 2011
* *

View File

@ -16,7 +16,6 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "block/thread-pool.h" #include "block/thread-pool.h"
#include "qemu/coroutine.h" #include "qemu/coroutine.h"
#include "qemu/main-loop.h"
#include "coth.h" #include "coth.h"
/* Called from QEMU I/O thread. */ /* Called from QEMU I/O thread. */

View File

@ -17,7 +17,8 @@
#include "qemu/thread.h" #include "qemu/thread.h"
#include "qemu/coroutine.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 * we want to use bottom half because we want to make sure the below
@ -48,8 +49,7 @@
extern void co_run_in_worker_bh(void *); extern void co_run_in_worker_bh(void *);
extern int v9fs_co_readlink(V9fsPDU *, V9fsPath *, V9fsString *); extern int v9fs_co_readlink(V9fsPDU *, V9fsPath *, V9fsString *);
extern int v9fs_co_readdir_r(V9fsPDU *, V9fsFidState *, extern int v9fs_co_readdir(V9fsPDU *, V9fsFidState *, struct dirent **);
struct dirent *, struct dirent **result);
extern off_t v9fs_co_telldir(V9fsPDU *, V9fsFidState *); extern off_t v9fs_co_telldir(V9fsPDU *, V9fsFidState *);
extern void v9fs_co_seekdir(V9fsPDU *, V9fsFidState *, off_t); extern void v9fs_co_seekdir(V9fsPDU *, V9fsFidState *, off_t);
extern void v9fs_co_rewinddir(V9fsPDU *, V9fsFidState *); extern void v9fs_co_rewinddir(V9fsPDU *, V9fsFidState *);

View File

@ -1,6 +1,5 @@
/* /*
* Virtio 9p backend * 9p backend
* *
* Copyright IBM, Corp. 2011 * Copyright IBM, Corp. 2011
* *

View File

@ -13,11 +13,9 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "hw/virtio/virtio.h" #include "hw/virtio/virtio.h"
#include "hw/i386/pc.h"
#include "qemu/sockets.h" #include "qemu/sockets.h"
#include "virtio-9p.h" #include "virtio-9p.h"
#include "fsdev/qemu-fsdev.h" #include "fsdev/qemu-fsdev.h"
#include "9p-xattr.h"
#include "coth.h" #include "coth.h"
#include "hw/virtio/virtio-access.h" #include "hw/virtio/virtio-access.h"
#include "qemu/iov.h" #include "qemu/iov.h"