hw/9pfs: Abstract open state of fid to V9fsFidOpenState
To implement synthetic file system in Qemu we may not really require file descriptor and Dir *. Make generic code use V9fsFidOpenState instead. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
This commit is contained in:
		
							parent
							
								
									2c74c2cb4b
								
							
						
					
					
						commit
						cc720ddb54
					
				| @ -78,6 +78,8 @@ typedef struct V9fsPath { | ||||
|     char *data; | ||||
| } V9fsPath; | ||||
| 
 | ||||
| typedef union V9fsFidOpenState V9fsFidOpenState; | ||||
| 
 | ||||
| void cred_init(FsCred *); | ||||
| 
 | ||||
| typedef struct FileOperations | ||||
| @ -94,22 +96,26 @@ typedef struct FileOperations | ||||
|                    const char *, FsCred *); | ||||
|     int (*link)(FsContext *, V9fsPath *, V9fsPath *, const char *); | ||||
|     int (*setuid)(FsContext *, uid_t); | ||||
|     int (*close)(FsContext *, int); | ||||
|     int (*closedir)(FsContext *, DIR *); | ||||
|     DIR *(*opendir)(FsContext *, V9fsPath *); | ||||
|     int (*open)(FsContext *, V9fsPath *, int); | ||||
|     int (*open2)(FsContext *, V9fsPath *, const char *, int, FsCred *); | ||||
|     void (*rewinddir)(FsContext *, DIR *); | ||||
|     off_t (*telldir)(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); | ||||
|     int (*close)(FsContext *, V9fsFidOpenState *); | ||||
|     int (*closedir)(FsContext *, V9fsFidOpenState *); | ||||
|     int (*opendir)(FsContext *, V9fsPath *, V9fsFidOpenState *); | ||||
|     int (*open)(FsContext *, V9fsPath *, int, V9fsFidOpenState *); | ||||
|     int (*open2)(FsContext *, V9fsPath *, const char *, | ||||
|                  int, FsCred *, V9fsFidOpenState *); | ||||
|     void (*rewinddir)(FsContext *, V9fsFidOpenState *); | ||||
|     off_t (*telldir)(FsContext *, V9fsFidOpenState *); | ||||
|     int (*readdir_r)(FsContext *, V9fsFidOpenState *, | ||||
|                      struct dirent *, struct dirent **); | ||||
|     void (*seekdir)(FsContext *, V9fsFidOpenState *, off_t); | ||||
|     ssize_t (*preadv)(FsContext *, V9fsFidOpenState *, | ||||
|                       const struct iovec *, int, off_t); | ||||
|     ssize_t (*pwritev)(FsContext *, V9fsFidOpenState *, | ||||
|                        const struct iovec *, int, off_t); | ||||
|     int (*mkdir)(FsContext *, V9fsPath *, const char *, FsCred *); | ||||
|     int (*fstat)(FsContext *, int, struct stat *); | ||||
|     int (*fstat)(FsContext *, V9fsFidOpenState *, struct stat *); | ||||
|     int (*rename)(FsContext *, const char *, const char *); | ||||
|     int (*truncate)(FsContext *, V9fsPath *, off_t); | ||||
|     int (*fsync)(FsContext *, int, int); | ||||
|     int (*fsync)(FsContext *, V9fsFidOpenState *, int); | ||||
|     int (*statfs)(FsContext *s, V9fsPath *path, struct statfs *stbuf); | ||||
|     ssize_t (*lgetxattr)(FsContext *, V9fsPath *, | ||||
|                          const char *, void *, size_t); | ||||
|  | ||||
| @ -29,7 +29,7 @@ int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent, | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             errno = 0; | ||||
|             err = s->ops->readdir_r(&s->ctx, fidp->fs.dir, dent, result); | ||||
|             err = s->ops->readdir_r(&s->ctx, &fidp->fs, dent, result); | ||||
|             if (!*result && errno) { | ||||
|                 err = -errno; | ||||
|             } else { | ||||
| @ -49,7 +49,7 @@ off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp) | ||||
|     } | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             err = s->ops->telldir(&s->ctx, fidp->fs.dir); | ||||
|             err = s->ops->telldir(&s->ctx, &fidp->fs); | ||||
|             if (err < 0) { | ||||
|                 err = -errno; | ||||
|             } | ||||
| @ -65,7 +65,7 @@ void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset) | ||||
|     } | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             s->ops->seekdir(&s->ctx, fidp->fs.dir, offset); | ||||
|             s->ops->seekdir(&s->ctx, &fidp->fs, offset); | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| @ -77,7 +77,7 @@ void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp) | ||||
|     } | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             s->ops->rewinddir(&s->ctx, fidp->fs.dir); | ||||
|             s->ops->rewinddir(&s->ctx, &fidp->fs); | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| @ -129,8 +129,8 @@ int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp) | ||||
|     v9fs_path_read_lock(s); | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             fidp->fs.dir = s->ops->opendir(&s->ctx, &fidp->path); | ||||
|             if (!fidp->fs.dir) { | ||||
|             err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs); | ||||
|             if (err < 0) { | ||||
|                 err = -errno; | ||||
|             } else { | ||||
|                 err = 0; | ||||
| @ -146,7 +146,7 @@ int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp) | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
| int v9fs_co_closedir(V9fsPDU *pdu, DIR *dir) | ||||
| int v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs) | ||||
| { | ||||
|     int err; | ||||
|     V9fsState *s = pdu->s; | ||||
| @ -156,7 +156,7 @@ int v9fs_co_closedir(V9fsPDU *pdu, DIR *dir) | ||||
|     } | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             err = s->ops->closedir(&s->ctx, dir); | ||||
|             err = s->ops->closedir(&s->ctx, fs); | ||||
|             if (err < 0) { | ||||
|                 err = -errno; | ||||
|             } | ||||
|  | ||||
| @ -61,7 +61,7 @@ int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf) | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
| int v9fs_co_fstat(V9fsPDU *pdu, int fd, struct stat *stbuf) | ||||
| int v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp, struct stat *stbuf) | ||||
| { | ||||
|     int err; | ||||
|     V9fsState *s = pdu->s; | ||||
| @ -71,7 +71,7 @@ int v9fs_co_fstat(V9fsPDU *pdu, int fd, struct stat *stbuf) | ||||
|     } | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             err = s->ops->fstat(&s->ctx, fd, stbuf); | ||||
|             err = s->ops->fstat(&s->ctx, &fidp->fs, stbuf); | ||||
|             if (err < 0) { | ||||
|                 err = -errno; | ||||
|             } | ||||
| @ -90,8 +90,8 @@ int v9fs_co_open(V9fsPDU *pdu, V9fsFidState *fidp, int flags) | ||||
|     v9fs_path_read_lock(s); | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             fidp->fs.fd = s->ops->open(&s->ctx, &fidp->path, flags); | ||||
|             if (fidp->fs.fd == -1) { | ||||
|             err = s->ops->open(&s->ctx, &fidp->path, flags, &fidp->fs); | ||||
|             if (err == -1) { | ||||
|                 err = -errno; | ||||
|             } else { | ||||
|                 err = 0; | ||||
| @ -130,9 +130,9 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid, | ||||
|     v9fs_path_read_lock(s); | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             fidp->fs.fd = s->ops->open2(&s->ctx, &fidp->path, | ||||
|                                         name->data, flags, &cred); | ||||
|             if (fidp->fs.fd == -1) { | ||||
|             err = s->ops->open2(&s->ctx, &fidp->path, | ||||
|                                 name->data, flags, &cred, &fidp->fs); | ||||
|             if (err < 0) { | ||||
|                 err = -errno; | ||||
|             } else { | ||||
|                 v9fs_path_init(&path); | ||||
| @ -141,12 +141,12 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid, | ||||
|                     err = s->ops->lstat(&s->ctx, &path, stbuf); | ||||
|                     if (err < 0) { | ||||
|                         err = -errno; | ||||
|                         s->ops->close(&s->ctx, fidp->fs.fd); | ||||
|                         s->ops->close(&s->ctx, &fidp->fs); | ||||
|                     } else { | ||||
|                         v9fs_path_copy(&fidp->path, &path); | ||||
|                     } | ||||
|                 } else { | ||||
|                     s->ops->close(&s->ctx, fidp->fs.fd); | ||||
|                     s->ops->close(&s->ctx, &fidp->fs); | ||||
|                 } | ||||
|                 v9fs_path_free(&path); | ||||
|             } | ||||
| @ -161,7 +161,7 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid, | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
| int v9fs_co_close(V9fsPDU *pdu, int fd) | ||||
| int v9fs_co_close(V9fsPDU *pdu, V9fsFidOpenState *fs) | ||||
| { | ||||
|     int err; | ||||
|     V9fsState *s = pdu->s; | ||||
| @ -171,7 +171,7 @@ int v9fs_co_close(V9fsPDU *pdu, int fd) | ||||
|     } | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             err = s->ops->close(&s->ctx, fd); | ||||
|             err = s->ops->close(&s->ctx, fs); | ||||
|             if (err < 0) { | ||||
|                 err = -errno; | ||||
|             } | ||||
| @ -184,16 +184,15 @@ int v9fs_co_close(V9fsPDU *pdu, int fd) | ||||
| 
 | ||||
| int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync) | ||||
| { | ||||
|     int fd, err; | ||||
|     int err; | ||||
|     V9fsState *s = pdu->s; | ||||
| 
 | ||||
|     if (v9fs_request_cancelled(pdu)) { | ||||
|         return -EINTR; | ||||
|     } | ||||
|     fd = fidp->fs.fd; | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             err = s->ops->fsync(&s->ctx, fd, datasync); | ||||
|             err = s->ops->fsync(&s->ctx, &fidp->fs, datasync); | ||||
|             if (err < 0) { | ||||
|                 err = -errno; | ||||
|             } | ||||
| @ -226,16 +225,15 @@ int v9fs_co_link(V9fsPDU *pdu, V9fsFidState *oldfid, | ||||
| int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp, | ||||
|                     struct iovec *iov, int iovcnt, int64_t offset) | ||||
| { | ||||
|     int fd, err; | ||||
|     int err; | ||||
|     V9fsState *s = pdu->s; | ||||
| 
 | ||||
|     if (v9fs_request_cancelled(pdu)) { | ||||
|         return -EINTR; | ||||
|     } | ||||
|     fd = fidp->fs.fd; | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             err = s->ops->pwritev(&s->ctx, fd, iov, iovcnt, offset); | ||||
|             err = s->ops->pwritev(&s->ctx, &fidp->fs, iov, iovcnt, offset); | ||||
|             if (err < 0) { | ||||
|                 err = -errno; | ||||
|             } | ||||
| @ -246,16 +244,15 @@ int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp, | ||||
| int v9fs_co_preadv(V9fsPDU *pdu, V9fsFidState *fidp, | ||||
|                    struct iovec *iov, int iovcnt, int64_t offset) | ||||
| { | ||||
|     int fd, err; | ||||
|     int err; | ||||
|     V9fsState *s = pdu->s; | ||||
| 
 | ||||
|     if (v9fs_request_cancelled(pdu)) { | ||||
|         return -EINTR; | ||||
|     } | ||||
|     fd = fidp->fs.fd; | ||||
|     v9fs_co_run_in_worker( | ||||
|         { | ||||
|             err = s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset); | ||||
|             err = s->ops->preadv(&s->ctx, &fidp->fs, iov, iovcnt, offset); | ||||
|             if (err < 0) { | ||||
|                 err = -errno; | ||||
|             } | ||||
|  | ||||
| @ -80,7 +80,7 @@ extern int v9fs_co_rename(V9fsPDU *, V9fsPath *, V9fsPath *); | ||||
| extern int v9fs_co_unlinkat(V9fsPDU *, V9fsPath *, V9fsString *, int flags); | ||||
| extern int v9fs_co_renameat(V9fsPDU *, V9fsPath *, V9fsString *, | ||||
|                             V9fsPath *, V9fsString *); | ||||
| extern int v9fs_co_fstat(V9fsPDU *, int, struct stat *); | ||||
| extern int v9fs_co_fstat(V9fsPDU *, V9fsFidState *, struct stat *); | ||||
| extern int v9fs_co_opendir(V9fsPDU *, V9fsFidState *); | ||||
| extern int v9fs_co_open(V9fsPDU *, V9fsFidState *, int); | ||||
| extern int v9fs_co_open2(V9fsPDU *, V9fsFidState *, V9fsString *, | ||||
| @ -88,8 +88,8 @@ extern int v9fs_co_open2(V9fsPDU *, V9fsFidState *, V9fsString *, | ||||
| extern int v9fs_co_lsetxattr(V9fsPDU *, V9fsPath *, V9fsString *, | ||||
|                              void *, size_t, int); | ||||
| extern int v9fs_co_lremovexattr(V9fsPDU *, V9fsPath *, V9fsString *); | ||||
| extern int v9fs_co_closedir(V9fsPDU *, DIR *); | ||||
| extern int v9fs_co_close(V9fsPDU *, int); | ||||
| extern int v9fs_co_closedir(V9fsPDU *, V9fsFidOpenState *); | ||||
| extern int v9fs_co_close(V9fsPDU *, V9fsFidOpenState *); | ||||
| extern int v9fs_co_fsync(V9fsPDU *, V9fsFidState *, int); | ||||
| extern int v9fs_co_symlink(V9fsPDU *, V9fsFidState *, V9fsString *, | ||||
|                            const char *, gid_t, struct stat *); | ||||
|  | ||||
| @ -133,81 +133,91 @@ static ssize_t handle_readlink(FsContext *fs_ctx, V9fsPath *fs_path, | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static int handle_close(FsContext *ctx, int fd) | ||||
| static int handle_close(FsContext *ctx, V9fsFidOpenState *fs) | ||||
| { | ||||
|     return close(fd); | ||||
|     return close(fs->fd); | ||||
| } | ||||
| 
 | ||||
| static int handle_closedir(FsContext *ctx, DIR *dir) | ||||
| static int handle_closedir(FsContext *ctx, V9fsFidOpenState *fs) | ||||
| { | ||||
|     return closedir(dir); | ||||
|     return closedir(fs->dir); | ||||
| } | ||||
| 
 | ||||
| static int handle_open(FsContext *ctx, V9fsPath *fs_path, int flags) | ||||
| static int handle_open(FsContext *ctx, V9fsPath *fs_path, | ||||
|                        int flags, V9fsFidOpenState *fs) | ||||
| { | ||||
|     struct handle_data *data = (struct handle_data *)ctx->private; | ||||
| 
 | ||||
|     return open_by_handle(data->mountfd, fs_path->data, flags); | ||||
|     fs->fd = open_by_handle(data->mountfd, fs_path->data, flags); | ||||
|     return fs->fd; | ||||
| } | ||||
| 
 | ||||
| static DIR *handle_opendir(FsContext *ctx, V9fsPath *fs_path) | ||||
| static int handle_opendir(FsContext *ctx, | ||||
|                           V9fsPath *fs_path, V9fsFidOpenState *fs) | ||||
| { | ||||
|     int fd; | ||||
|     fd = handle_open(ctx, fs_path, O_DIRECTORY); | ||||
|     if (fd < 0) { | ||||
|         return NULL; | ||||
|     int ret; | ||||
|     ret = handle_open(ctx, fs_path, O_DIRECTORY, fs); | ||||
|     if (ret < 0) { | ||||
|         return -1; | ||||
|     } | ||||
|     return fdopendir(fd); | ||||
|     fs->dir = fdopendir(ret); | ||||
|     if (!fs->dir) { | ||||
|         return -1; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static void handle_rewinddir(FsContext *ctx, DIR *dir) | ||||
| static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) | ||||
| { | ||||
|     return rewinddir(dir); | ||||
|     return rewinddir(fs->dir); | ||||
| } | ||||
| 
 | ||||
| static off_t handle_telldir(FsContext *ctx, DIR *dir) | ||||
| static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs) | ||||
| { | ||||
|     return telldir(dir); | ||||
|     return telldir(fs->dir); | ||||
| } | ||||
| 
 | ||||
| static int handle_readdir_r(FsContext *ctx, DIR *dir, struct dirent *entry, | ||||
| static int handle_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, | ||||
|                             struct dirent *entry, | ||||
|                             struct dirent **result) | ||||
| { | ||||
|     return readdir_r(dir, entry, result); | ||||
|     return readdir_r(fs->dir, entry, result); | ||||
| } | ||||
| 
 | ||||
| static void handle_seekdir(FsContext *ctx, DIR *dir, off_t off) | ||||
| static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) | ||||
| { | ||||
|     return seekdir(dir, off); | ||||
|     return seekdir(fs->dir, off); | ||||
| } | ||||
| 
 | ||||
| static ssize_t handle_preadv(FsContext *ctx, int fd, const struct iovec *iov, | ||||
| static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs, | ||||
|                              const struct iovec *iov, | ||||
|                              int iovcnt, off_t offset) | ||||
| { | ||||
| #ifdef CONFIG_PREADV | ||||
|     return preadv(fd, iov, iovcnt, offset); | ||||
|     return preadv(fs->fd, iov, iovcnt, offset); | ||||
| #else | ||||
|     int err = lseek(fd, offset, SEEK_SET); | ||||
|     int err = lseek(fs->fd, offset, SEEK_SET); | ||||
|     if (err == -1) { | ||||
|         return err; | ||||
|     } else { | ||||
|         return readv(fd, iov, iovcnt); | ||||
|         return readv(fs->fd, iov, iovcnt); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static ssize_t handle_pwritev(FsContext *ctx, int fd, const struct iovec *iov, | ||||
| static ssize_t handle_pwritev(FsContext *ctx, V9fsFidOpenState *fs, | ||||
|                               const struct iovec *iov, | ||||
|                               int iovcnt, off_t offset) | ||||
| { | ||||
|     ssize_t ret; | ||||
| #ifdef CONFIG_PREADV | ||||
|     ret = pwritev(fd, iov, iovcnt, offset); | ||||
|     ret = pwritev(fs->fd, iov, iovcnt, offset); | ||||
| #else | ||||
|     int err = lseek(fd, offset, SEEK_SET); | ||||
|     int err = lseek(fs->fd, offset, SEEK_SET); | ||||
|     if (err == -1) { | ||||
|         return err; | ||||
|     } else { | ||||
|         ret = writev(fd, iov, iovcnt); | ||||
|         ret = writev(fs->fd, iov, iovcnt); | ||||
|     } | ||||
| #endif | ||||
| #ifdef CONFIG_SYNC_FILE_RANGE | ||||
| @ -217,7 +227,7 @@ static ssize_t handle_pwritev(FsContext *ctx, int fd, const struct iovec *iov, | ||||
|          * We want to ensure that we don't leave dirty pages in the cache | ||||
|          * after write when writeout=immediate is sepcified. | ||||
|          */ | ||||
|         sync_file_range(fd, offset, ret, | ||||
|         sync_file_range(fs->fd, offset, ret, | ||||
|                         SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE); | ||||
|     } | ||||
| #endif | ||||
| @ -274,13 +284,14 @@ static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static int handle_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) | ||||
| static int handle_fstat(FsContext *fs_ctx, V9fsFidOpenState *fs, | ||||
|                         struct stat *stbuf) | ||||
| { | ||||
|     return fstat(fd, stbuf); | ||||
|     return fstat(fs->fd, stbuf); | ||||
| } | ||||
| 
 | ||||
| static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, | ||||
|                        int flags, FsCred *credp) | ||||
|                         int flags, FsCred *credp, V9fsFidOpenState *fs) | ||||
| { | ||||
|     int ret; | ||||
|     int dirfd, fd; | ||||
| @ -296,6 +307,8 @@ static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, | ||||
|         if (ret < 0) { | ||||
|             close(fd); | ||||
|             fd = ret; | ||||
|         } else { | ||||
|             fs->fd = fd; | ||||
|         } | ||||
|     } | ||||
|     close(dirfd); | ||||
| @ -411,12 +424,12 @@ static int handle_remove(FsContext *ctx, const char *path) | ||||
|     return -1; | ||||
| } | ||||
| 
 | ||||
| static int handle_fsync(FsContext *ctx, int fd, int datasync) | ||||
| static int handle_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync) | ||||
| { | ||||
|     if (datasync) { | ||||
|         return qemu_fdatasync(fd); | ||||
|         return qemu_fdatasync(fs->fd); | ||||
|     } else { | ||||
|         return fsync(fd); | ||||
|         return fsync(fs->fd); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -575,7 +588,8 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir, | ||||
| static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, | ||||
|                                  mode_t st_mode, uint64_t *st_gen) | ||||
| { | ||||
|     int err, fd; | ||||
|     int err; | ||||
|     V9fsFidOpenState fid_open; | ||||
| 
 | ||||
|     /*
 | ||||
|      * Do not try to open special files like device nodes, fifos etc | ||||
| @ -584,12 +598,12 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, | ||||
|     if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) { | ||||
|             return 0; | ||||
|     } | ||||
|     fd = handle_open(ctx, path, O_RDONLY); | ||||
|     if (fd < 0) { | ||||
|         return fd; | ||||
|     err = handle_open(ctx, path, O_RDONLY, &fid_open); | ||||
|     if (err < 0) { | ||||
|         return err; | ||||
|     } | ||||
|     err = ioctl(fd, FS_IOC_GETVERSION, st_gen); | ||||
|     handle_close(ctx, fd); | ||||
|     err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); | ||||
|     handle_close(ctx, &fid_open); | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -156,81 +156,91 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path, | ||||
|     return tsize; | ||||
| } | ||||
| 
 | ||||
| static int local_close(FsContext *ctx, int fd) | ||||
| static int local_close(FsContext *ctx, V9fsFidOpenState *fs) | ||||
| { | ||||
|     return close(fd); | ||||
|     return close(fs->fd); | ||||
| } | ||||
| 
 | ||||
| static int local_closedir(FsContext *ctx, DIR *dir) | ||||
| static int local_closedir(FsContext *ctx, V9fsFidOpenState *fs) | ||||
| { | ||||
|     return closedir(dir); | ||||
|     return closedir(fs->dir); | ||||
| } | ||||
| 
 | ||||
| static int local_open(FsContext *ctx, V9fsPath *fs_path, int flags) | ||||
| static int local_open(FsContext *ctx, V9fsPath *fs_path, | ||||
|                       int flags, V9fsFidOpenState *fs) | ||||
| { | ||||
|     char buffer[PATH_MAX]; | ||||
|     char *path = fs_path->data; | ||||
| 
 | ||||
|     return open(rpath(ctx, path, buffer), flags); | ||||
|     fs->fd = open(rpath(ctx, path, buffer), flags); | ||||
|     return fs->fd; | ||||
| } | ||||
| 
 | ||||
| static DIR *local_opendir(FsContext *ctx, V9fsPath *fs_path) | ||||
| static int local_opendir(FsContext *ctx, | ||||
|                          V9fsPath *fs_path, V9fsFidOpenState *fs) | ||||
| { | ||||
|     char buffer[PATH_MAX]; | ||||
|     char *path = fs_path->data; | ||||
| 
 | ||||
|     return opendir(rpath(ctx, path, buffer)); | ||||
|     fs->dir = opendir(rpath(ctx, path, buffer)); | ||||
|     if (!fs->dir) { | ||||
|         return -1; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static void local_rewinddir(FsContext *ctx, DIR *dir) | ||||
| static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) | ||||
| { | ||||
|     return rewinddir(dir); | ||||
|     return rewinddir(fs->dir); | ||||
| } | ||||
| 
 | ||||
| static off_t local_telldir(FsContext *ctx, DIR *dir) | ||||
| static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs) | ||||
| { | ||||
|     return telldir(dir); | ||||
|     return telldir(fs->dir); | ||||
| } | ||||
| 
 | ||||
| static int local_readdir_r(FsContext *ctx, DIR *dir, struct dirent *entry, | ||||
| static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, | ||||
|                            struct dirent *entry, | ||||
|                            struct dirent **result) | ||||
| { | ||||
|     return readdir_r(dir, entry, result); | ||||
|     return readdir_r(fs->dir, entry, result); | ||||
| } | ||||
| 
 | ||||
| static void local_seekdir(FsContext *ctx, DIR *dir, off_t off) | ||||
| static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) | ||||
| { | ||||
|     return seekdir(dir, off); | ||||
|     return seekdir(fs->dir, off); | ||||
| } | ||||
| 
 | ||||
| static ssize_t local_preadv(FsContext *ctx, int fd, const struct iovec *iov, | ||||
| static ssize_t local_preadv(FsContext *ctx, V9fsFidOpenState *fs, | ||||
|                             const struct iovec *iov, | ||||
|                             int iovcnt, off_t offset) | ||||
| { | ||||
| #ifdef CONFIG_PREADV | ||||
|     return preadv(fd, iov, iovcnt, offset); | ||||
|     return preadv(fs->fd, iov, iovcnt, offset); | ||||
| #else | ||||
|     int err = lseek(fd, offset, SEEK_SET); | ||||
|     int err = lseek(fs->fd, offset, SEEK_SET); | ||||
|     if (err == -1) { | ||||
|         return err; | ||||
|     } else { | ||||
|         return readv(fd, iov, iovcnt); | ||||
|         return readv(fs->fd, iov, iovcnt); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov, | ||||
| static ssize_t local_pwritev(FsContext *ctx, V9fsFidOpenState *fs, | ||||
|                              const struct iovec *iov, | ||||
|                              int iovcnt, off_t offset) | ||||
| { | ||||
|     ssize_t ret | ||||
| ; | ||||
| #ifdef CONFIG_PREADV | ||||
|     ret = pwritev(fd, iov, iovcnt, offset); | ||||
|     ret = pwritev(fs->fd, iov, iovcnt, offset); | ||||
| #else | ||||
|     int err = lseek(fd, offset, SEEK_SET); | ||||
|     int err = lseek(fs->fd, offset, SEEK_SET); | ||||
|     if (err == -1) { | ||||
|         return err; | ||||
|     } else { | ||||
|         ret = writev(fd, iov, iovcnt); | ||||
|         ret = writev(fs->fd, iov, iovcnt); | ||||
|     } | ||||
| #endif | ||||
| #ifdef CONFIG_SYNC_FILE_RANGE | ||||
| @ -240,7 +250,7 @@ static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov, | ||||
|          * We want to ensure that we don't leave dirty pages in the cache | ||||
|          * after write when writeout=immediate is sepcified. | ||||
|          */ | ||||
|         sync_file_range(fd, offset, ret, | ||||
|         sync_file_range(fs->fd, offset, ret, | ||||
|                         SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE); | ||||
|     } | ||||
| #endif | ||||
| @ -356,10 +366,11 @@ out: | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
| static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) | ||||
| static int local_fstat(FsContext *fs_ctx, | ||||
|                        V9fsFidOpenState *fs, struct stat *stbuf) | ||||
| { | ||||
|     int err; | ||||
|     err = fstat(fd, stbuf); | ||||
|     err = fstat(fs->fd, stbuf); | ||||
|     if (err) { | ||||
|         return err; | ||||
|     } | ||||
| @ -370,16 +381,20 @@ static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) | ||||
|         mode_t tmp_mode; | ||||
|         dev_t tmp_dev; | ||||
| 
 | ||||
|         if (fgetxattr(fd, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) { | ||||
|         if (fgetxattr(fs->fd, "user.virtfs.uid", | ||||
|                       &tmp_uid, sizeof(uid_t)) > 0) { | ||||
|             stbuf->st_uid = tmp_uid; | ||||
|         } | ||||
|         if (fgetxattr(fd, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) { | ||||
|         if (fgetxattr(fs->fd, "user.virtfs.gid", | ||||
|                       &tmp_gid, sizeof(gid_t)) > 0) { | ||||
|             stbuf->st_gid = tmp_gid; | ||||
|         } | ||||
|         if (fgetxattr(fd, "user.virtfs.mode", &tmp_mode, sizeof(mode_t)) > 0) { | ||||
|         if (fgetxattr(fs->fd, "user.virtfs.mode", | ||||
|                       &tmp_mode, sizeof(mode_t)) > 0) { | ||||
|             stbuf->st_mode = tmp_mode; | ||||
|         } | ||||
|         if (fgetxattr(fd, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) { | ||||
|         if (fgetxattr(fs->fd, "user.virtfs.rdev", | ||||
|                       &tmp_dev, sizeof(dev_t)) > 0) { | ||||
|                 stbuf->st_rdev = tmp_dev; | ||||
|         } | ||||
|     } | ||||
| @ -387,7 +402,7 @@ static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) | ||||
| } | ||||
| 
 | ||||
| static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, | ||||
|                        int flags, FsCred *credp) | ||||
|                        int flags, FsCred *credp, V9fsFidOpenState *fs) | ||||
| { | ||||
|     char *path; | ||||
|     int fd = -1; | ||||
| @ -428,6 +443,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, | ||||
|         } | ||||
|     } | ||||
|     err = fd; | ||||
|     fs->fd = fd; | ||||
|     goto out; | ||||
| 
 | ||||
| err_end: | ||||
| @ -577,12 +593,12 @@ static int local_remove(FsContext *ctx, const char *path) | ||||
|     return remove(rpath(ctx, path, buffer)); | ||||
| } | ||||
| 
 | ||||
| static int local_fsync(FsContext *ctx, int fd, int datasync) | ||||
| static int local_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync) | ||||
| { | ||||
|     if (datasync) { | ||||
|         return qemu_fdatasync(fd); | ||||
|         return qemu_fdatasync(fs->fd); | ||||
|     } else { | ||||
|         return fsync(fd); | ||||
|         return fsync(fs->fd); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -677,7 +693,9 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir, | ||||
| static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, | ||||
|                                 mode_t st_mode, uint64_t *st_gen) | ||||
| { | ||||
|     int err, fd; | ||||
|     int err; | ||||
|     V9fsFidOpenState fid_open; | ||||
| 
 | ||||
|     /*
 | ||||
|      * Do not try to open special files like device nodes, fifos etc | ||||
|      * We can get fd for regular files and directories only | ||||
| @ -685,12 +703,12 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, | ||||
|     if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) { | ||||
|             return 0; | ||||
|     } | ||||
|     fd = local_open(ctx, path, O_RDONLY); | ||||
|     if (fd < 0) { | ||||
|         return fd; | ||||
|     err = local_open(ctx, path, O_RDONLY, &fid_open); | ||||
|     if (err < 0) { | ||||
|         return err; | ||||
|     } | ||||
|     err = ioctl(fd, FS_IOC_GETVERSION, st_gen); | ||||
|     local_close(ctx, fd); | ||||
|     err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); | ||||
|     local_close(ctx, &fid_open); | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -455,11 +455,11 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp) | ||||
|     if (fidp->fid_type == P9_FID_FILE) { | ||||
|         /* If we reclaimed the fd no need to close */ | ||||
|         if (fidp->fs.fd != -1) { | ||||
|             retval = v9fs_co_close(pdu, fidp->fs.fd); | ||||
|             retval = v9fs_co_close(pdu, &fidp->fs); | ||||
|         } | ||||
|     } else if (fidp->fid_type == P9_FID_DIR) { | ||||
|         if (fidp->fs.dir != NULL) { | ||||
|             retval = v9fs_co_closedir(pdu, fidp->fs.dir); | ||||
|             retval = v9fs_co_closedir(pdu, &fidp->fs); | ||||
|         } | ||||
|     } else if (fidp->fid_type == P9_FID_XATTR) { | ||||
|         retval = v9fs_xattr_fid_clunk(pdu, fidp); | ||||
| @ -567,9 +567,9 @@ void v9fs_reclaim_fd(V9fsPDU *pdu) | ||||
|         f = reclaim_list; | ||||
|         reclaim_list = f->rclm_lst; | ||||
|         if (f->fid_type == P9_FID_FILE) { | ||||
|             v9fs_co_close(pdu, f->fs_reclaim.fd); | ||||
|             v9fs_co_close(pdu, &f->fs_reclaim); | ||||
|         } else if (f->fid_type == P9_FID_DIR) { | ||||
|             v9fs_co_closedir(pdu, f->fs_reclaim.dir); | ||||
|             v9fs_co_closedir(pdu, &f->fs_reclaim); | ||||
|         } | ||||
|         f->rclm_lst = NULL; | ||||
|         /*
 | ||||
| @ -3009,7 +3009,7 @@ static void v9fs_lock(void *opaque) | ||||
|         err = -ENOENT; | ||||
|         goto out_nofid; | ||||
|     } | ||||
|     err = v9fs_co_fstat(pdu, fidp->fs.fd, &stbuf); | ||||
|     err = v9fs_co_fstat(pdu, fidp, &stbuf); | ||||
|     if (err < 0) { | ||||
|         goto out; | ||||
|     } | ||||
| @ -3052,7 +3052,7 @@ static void v9fs_getlock(void *opaque) | ||||
|         err = -ENOENT; | ||||
|         goto out_nofid; | ||||
|     } | ||||
|     err = v9fs_co_fstat(pdu, fidp->fs.fd, &stbuf); | ||||
|     err = v9fs_co_fstat(pdu, fidp, &stbuf); | ||||
|     if (err < 0) { | ||||
|         goto out; | ||||
|     } | ||||
|  | ||||
| @ -204,20 +204,23 @@ typedef struct V9fsXattr | ||||
|     int flags; | ||||
| } V9fsXattr; | ||||
| 
 | ||||
| /*
 | ||||
|  * Filled by fs driver on open and other | ||||
|  * calls. | ||||
|  */ | ||||
| union V9fsFidOpenState { | ||||
|     int fd; | ||||
|     DIR *dir; | ||||
|     V9fsXattr xattr; | ||||
| }; | ||||
| 
 | ||||
| struct V9fsFidState | ||||
| { | ||||
|     int fid_type; | ||||
|     int32_t fid; | ||||
|     V9fsPath path; | ||||
|     union { | ||||
|         int fd; | ||||
|         DIR *dir; | ||||
|         V9fsXattr xattr; | ||||
|     } fs; | ||||
|     union { | ||||
|         int fd; | ||||
|         DIR *dir; | ||||
|     } fs_reclaim; | ||||
|     V9fsFidOpenState fs; | ||||
|     V9fsFidOpenState fs_reclaim; | ||||
|     int flags; | ||||
|     int open_flags; | ||||
|     uid_t uid; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Aneesh Kumar K.V
						Aneesh Kumar K.V