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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Greg Kurz
						Greg Kurz