From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:49154) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QPNtZ-0008Jo-Ui for qemu-devel@nongnu.org; Wed, 25 May 2011 19:53:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QPNtV-0007Z0-UY for qemu-devel@nongnu.org; Wed, 25 May 2011 19:53:45 -0400 Received: from e34.co.us.ibm.com ([32.97.110.152]:39677) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QPNtV-0007YR-6c for qemu-devel@nongnu.org; Wed, 25 May 2011 19:53:41 -0400 Received: from d03relay02.boulder.ibm.com (d03relay02.boulder.ibm.com [9.17.195.227]) by e34.co.us.ibm.com (8.14.4/8.13.1) with ESMTP id p4PNf19n030312 for ; Wed, 25 May 2011 17:41:01 -0600 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay02.boulder.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id p4PNraWD156536 for ; Wed, 25 May 2011 17:53:36 -0600 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p4PHr8Mv018687 for ; Wed, 25 May 2011 11:53:09 -0600 From: "Venkateswararao Jujjuri (JV)" Date: Wed, 25 May 2011 16:53:17 -0700 Message-Id: <1306367597-797-30-git-send-email-jvrao@linux.vnet.ibm.com> In-Reply-To: <1306367597-797-1-git-send-email-jvrao@linux.vnet.ibm.com> References: <1306367597-797-1-git-send-email-jvrao@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 29/29] use readdir_r instead of readdir for reentrancy List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Harsh Prateek Bora , "Venkateswararao Jujjuri \"" , stefanha@linux.vnet.ibm.com From: Harsh Prateek Bora This patch is created on top of Aneesh's coroutine work. LTP test for readdir passed. Signed-off-by: Harsh Prateek Bora Signed-off-by: Venkateswararao Jujjuri " --- fsdev/file-op-9p.h | 2 +- hw/9pfs/codir.c | 7 ++++--- hw/9pfs/virtio-9p-coth.h | 4 ++-- hw/9pfs/virtio-9p-local.c | 7 ++++--- hw/9pfs/virtio-9p.c | 22 ++++++++++++++++------ 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h index af9daf7..1eda342 100644 --- a/fsdev/file-op-9p.h +++ b/fsdev/file-op-9p.h @@ -78,7 +78,7 @@ typedef struct FileOperations int (*open2)(FsContext *, const char *, int, FsCred *); void (*rewinddir)(FsContext *, DIR *); off_t (*telldir)(FsContext *, DIR *); - struct dirent *(*readdir)(FsContext *, DIR *); + int (*readdir_r)(FsContext *, DIR *, struct dirent *, struct dirent **); void (*seekdir)(FsContext *, DIR *, off_t); ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t); ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t); diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c index 0c31db3..783d279 100644 --- a/hw/9pfs/codir.c +++ b/hw/9pfs/codir.c @@ -17,7 +17,8 @@ #include "qemu-coroutine.h" #include "virtio-9p-coth.h" -int v9fs_co_readdir(V9fsState *s, V9fsFidState *fidp, struct dirent **dent) +int v9fs_co_readdir_r(V9fsState *s, V9fsFidState *fidp, struct dirent *dent, + struct dirent **result) { int err; @@ -25,8 +26,8 @@ int v9fs_co_readdir(V9fsState *s, V9fsFidState *fidp, struct dirent **dent) { errno = 0; /*FIXME!! need to switch to readdir_r */ - *dent = s->ops->readdir(&s->ctx, fidp->fs.dir); - if (!*dent && errno) { + err = s->ops->readdir_r(&s->ctx, fidp->fs.dir, dent, result); + if (!*result && errno) { err = -errno; } else { err = 0; diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h index 5fa2972..48defb7 100644 --- a/hw/9pfs/virtio-9p-coth.h +++ b/hw/9pfs/virtio-9p-coth.h @@ -57,8 +57,8 @@ typedef struct V9fsThPool { extern void co_run_in_worker_bh(void *); extern int v9fs_init_worker_threads(void); extern int v9fs_co_readlink(V9fsState *, V9fsString *, V9fsString *); -extern int v9fs_co_readdir(V9fsState *, V9fsFidState *, - struct dirent **); +extern int v9fs_co_readdir_r(V9fsState *, V9fsFidState *, + struct dirent *, struct dirent **result); extern off_t v9fs_co_telldir(V9fsState *, V9fsFidState *); extern void v9fs_co_seekdir(V9fsState *, V9fsFidState *, off_t); extern void v9fs_co_rewinddir(V9fsState *, V9fsFidState *); diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index 77904c3..61cbf8d 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -165,9 +165,10 @@ static off_t local_telldir(FsContext *ctx, DIR *dir) return telldir(dir); } -static struct dirent *local_readdir(FsContext *ctx, DIR *dir) +static int local_readdir_r(FsContext *ctx, DIR *dir, struct dirent *entry, + struct dirent **result) { - return readdir(dir); + return readdir_r(dir, entry, result); } static void local_seekdir(FsContext *ctx, DIR *dir, off_t off) @@ -532,7 +533,7 @@ FileOperations local_ops = { .opendir = local_opendir, .rewinddir = local_rewinddir, .telldir = local_telldir, - .readdir = local_readdir, + .readdir_r = local_readdir_r, .seekdir = local_seekdir, .preadv = local_preadv, .pwritev = local_pwritev, diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 4c084fa..b48bb13 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -1496,17 +1496,20 @@ static int v9fs_do_readdir_with_stat(V9fsState *s, V9fsPDU *pdu, int32_t count = 0; struct stat stbuf; off_t saved_dir_pos; - struct dirent *dent; + struct dirent *dent, *result; /* save the directory position */ saved_dir_pos = v9fs_co_telldir(s, fidp); if (saved_dir_pos < 0) { return saved_dir_pos; } + + dent = qemu_malloc(sizeof(struct dirent)); + while (1) { v9fs_string_init(&name); - err = v9fs_co_readdir(s, fidp, &dent); - if (err || !dent) { + err = v9fs_co_readdir_r(s, fidp, dent, &result); + if (err || !result) { break; } v9fs_string_sprintf(&name, "%s/%s", fidp->path.data, dent->d_name); @@ -1525,6 +1528,7 @@ static int v9fs_do_readdir_with_stat(V9fsState *s, V9fsPDU *pdu, v9fs_co_seekdir(s, fidp, saved_dir_pos); v9fs_stat_free(&v9stat); v9fs_string_free(&name); + qemu_free(dent); return count; } count += len; @@ -1533,6 +1537,7 @@ static int v9fs_do_readdir_with_stat(V9fsState *s, V9fsPDU *pdu, saved_dir_pos = dent->d_off; } out: + qemu_free(dent); v9fs_string_free(&name); if (err < 0) { return err; @@ -1630,16 +1635,19 @@ static int v9fs_do_readdir(V9fsState *s, V9fsPDU *pdu, int len, err = 0; int32_t count = 0; off_t saved_dir_pos; - struct dirent *dent; + struct dirent *dent, *result; /* save the directory position */ saved_dir_pos = v9fs_co_telldir(s, fidp); if (saved_dir_pos < 0) { return saved_dir_pos; } + + dent = qemu_malloc(sizeof(struct dirent)); + while (1) { - err = v9fs_co_readdir(s, fidp, &dent); - if (err || !dent) { + err = v9fs_co_readdir_r(s, fidp, dent, &result); + if (err || !result) { break; } v9fs_string_init(&name); @@ -1648,6 +1656,7 @@ static int v9fs_do_readdir(V9fsState *s, V9fsPDU *pdu, /* Ran out of buffer. Set dir back to old position and return */ v9fs_co_seekdir(s, fidp, saved_dir_pos); v9fs_string_free(&name); + qemu_free(dent); return count; } /* @@ -1669,6 +1678,7 @@ static int v9fs_do_readdir(V9fsState *s, V9fsPDU *pdu, v9fs_string_free(&name); saved_dir_pos = dent->d_off; } + qemu_free(dent); if (err < 0) { return err; } -- 1.7.1