2
0
Эх сурвалжийг харах

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>
Greg Kurz 9 жил өмнө
parent
commit
635324e83e

+ 1 - 2
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);

+ 3 - 5
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,

+ 11 - 9
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,

+ 3 - 5
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,

+ 10 - 13
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,

+ 1 - 0
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,

+ 6 - 15
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;
     }

+ 6 - 4
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;
             }
         });

+ 1 - 2
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 *);