提交 cc720ddb 编写于 作者: A Aneesh Kumar K.V

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: NAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
上级 2c74c2cb
...@@ -78,6 +78,8 @@ typedef struct V9fsPath { ...@@ -78,6 +78,8 @@ typedef struct V9fsPath {
char *data; char *data;
} V9fsPath; } V9fsPath;
typedef union V9fsFidOpenState V9fsFidOpenState;
void cred_init(FsCred *); void cred_init(FsCred *);
typedef struct FileOperations typedef struct FileOperations
...@@ -94,22 +96,26 @@ typedef struct FileOperations ...@@ -94,22 +96,26 @@ typedef struct FileOperations
const char *, FsCred *); const char *, FsCred *);
int (*link)(FsContext *, V9fsPath *, V9fsPath *, const char *); int (*link)(FsContext *, V9fsPath *, V9fsPath *, const char *);
int (*setuid)(FsContext *, uid_t); int (*setuid)(FsContext *, uid_t);
int (*close)(FsContext *, int); int (*close)(FsContext *, V9fsFidOpenState *);
int (*closedir)(FsContext *, DIR *); int (*closedir)(FsContext *, V9fsFidOpenState *);
DIR *(*opendir)(FsContext *, V9fsPath *); int (*opendir)(FsContext *, V9fsPath *, V9fsFidOpenState *);
int (*open)(FsContext *, V9fsPath *, int); int (*open)(FsContext *, V9fsPath *, int, V9fsFidOpenState *);
int (*open2)(FsContext *, V9fsPath *, const char *, int, FsCred *); int (*open2)(FsContext *, V9fsPath *, const char *,
void (*rewinddir)(FsContext *, DIR *); int, FsCred *, V9fsFidOpenState *);
off_t (*telldir)(FsContext *, DIR *); void (*rewinddir)(FsContext *, V9fsFidOpenState *);
int (*readdir_r)(FsContext *, DIR *, struct dirent *, struct dirent **); off_t (*telldir)(FsContext *, V9fsFidOpenState *);
void (*seekdir)(FsContext *, DIR *, off_t); int (*readdir_r)(FsContext *, V9fsFidOpenState *,
ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t); struct dirent *, struct dirent **);
ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t); 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 (*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 (*rename)(FsContext *, const char *, const char *);
int (*truncate)(FsContext *, V9fsPath *, off_t); 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); int (*statfs)(FsContext *s, V9fsPath *path, struct statfs *stbuf);
ssize_t (*lgetxattr)(FsContext *, V9fsPath *, ssize_t (*lgetxattr)(FsContext *, V9fsPath *,
const char *, void *, size_t); const char *, void *, size_t);
......
...@@ -29,7 +29,7 @@ int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent, ...@@ -29,7 +29,7 @@ int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
errno = 0; 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) { if (!*result && errno) {
err = -errno; err = -errno;
} else { } else {
...@@ -49,7 +49,7 @@ off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp) ...@@ -49,7 +49,7 @@ off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
} }
v9fs_co_run_in_worker( 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) { if (err < 0) {
err = -errno; err = -errno;
} }
...@@ -65,7 +65,7 @@ void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset) ...@@ -65,7 +65,7 @@ void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset)
} }
v9fs_co_run_in_worker( 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) ...@@ -77,7 +77,7 @@ void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
} }
v9fs_co_run_in_worker( 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) ...@@ -129,8 +129,8 @@ int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
v9fs_path_read_lock(s); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
fidp->fs.dir = s->ops->opendir(&s->ctx, &fidp->path); err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs);
if (!fidp->fs.dir) { if (err < 0) {
err = -errno; err = -errno;
} else { } else {
err = 0; err = 0;
...@@ -146,7 +146,7 @@ int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp) ...@@ -146,7 +146,7 @@ int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
return err; return err;
} }
int v9fs_co_closedir(V9fsPDU *pdu, DIR *dir) int v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs)
{ {
int err; int err;
V9fsState *s = pdu->s; V9fsState *s = pdu->s;
...@@ -156,7 +156,7 @@ int v9fs_co_closedir(V9fsPDU *pdu, DIR *dir) ...@@ -156,7 +156,7 @@ int v9fs_co_closedir(V9fsPDU *pdu, DIR *dir)
} }
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->closedir(&s->ctx, dir); err = s->ops->closedir(&s->ctx, fs);
if (err < 0) { if (err < 0) {
err = -errno; err = -errno;
} }
......
...@@ -61,7 +61,7 @@ int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf) ...@@ -61,7 +61,7 @@ int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf)
return err; 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; int err;
V9fsState *s = pdu->s; V9fsState *s = pdu->s;
...@@ -71,7 +71,7 @@ int v9fs_co_fstat(V9fsPDU *pdu, int fd, struct stat *stbuf) ...@@ -71,7 +71,7 @@ int v9fs_co_fstat(V9fsPDU *pdu, int fd, struct stat *stbuf)
} }
v9fs_co_run_in_worker( 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) { if (err < 0) {
err = -errno; err = -errno;
} }
...@@ -90,8 +90,8 @@ int v9fs_co_open(V9fsPDU *pdu, V9fsFidState *fidp, int flags) ...@@ -90,8 +90,8 @@ int v9fs_co_open(V9fsPDU *pdu, V9fsFidState *fidp, int flags)
v9fs_path_read_lock(s); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
fidp->fs.fd = s->ops->open(&s->ctx, &fidp->path, flags); err = s->ops->open(&s->ctx, &fidp->path, flags, &fidp->fs);
if (fidp->fs.fd == -1) { if (err == -1) {
err = -errno; err = -errno;
} else { } else {
err = 0; err = 0;
...@@ -130,9 +130,9 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid, ...@@ -130,9 +130,9 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid,
v9fs_path_read_lock(s); v9fs_path_read_lock(s);
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
fidp->fs.fd = s->ops->open2(&s->ctx, &fidp->path, err = s->ops->open2(&s->ctx, &fidp->path,
name->data, flags, &cred); name->data, flags, &cred, &fidp->fs);
if (fidp->fs.fd == -1) { if (err < 0) {
err = -errno; err = -errno;
} else { } else {
v9fs_path_init(&path); v9fs_path_init(&path);
...@@ -141,12 +141,12 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid, ...@@ -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); err = s->ops->lstat(&s->ctx, &path, stbuf);
if (err < 0) { if (err < 0) {
err = -errno; err = -errno;
s->ops->close(&s->ctx, fidp->fs.fd); s->ops->close(&s->ctx, &fidp->fs);
} else { } else {
v9fs_path_copy(&fidp->path, &path); v9fs_path_copy(&fidp->path, &path);
} }
} else { } else {
s->ops->close(&s->ctx, fidp->fs.fd); s->ops->close(&s->ctx, &fidp->fs);
} }
v9fs_path_free(&path); v9fs_path_free(&path);
} }
...@@ -161,7 +161,7 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid, ...@@ -161,7 +161,7 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid,
return err; return err;
} }
int v9fs_co_close(V9fsPDU *pdu, int fd) int v9fs_co_close(V9fsPDU *pdu, V9fsFidOpenState *fs)
{ {
int err; int err;
V9fsState *s = pdu->s; V9fsState *s = pdu->s;
...@@ -171,7 +171,7 @@ int v9fs_co_close(V9fsPDU *pdu, int fd) ...@@ -171,7 +171,7 @@ int v9fs_co_close(V9fsPDU *pdu, int fd)
} }
v9fs_co_run_in_worker( v9fs_co_run_in_worker(
{ {
err = s->ops->close(&s->ctx, fd); err = s->ops->close(&s->ctx, fs);
if (err < 0) { if (err < 0) {
err = -errno; err = -errno;
} }
...@@ -184,16 +184,15 @@ int v9fs_co_close(V9fsPDU *pdu, int fd) ...@@ -184,16 +184,15 @@ int v9fs_co_close(V9fsPDU *pdu, int fd)
int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync) int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync)
{ {
int fd, err; int err;
V9fsState *s = pdu->s; V9fsState *s = pdu->s;
if (v9fs_request_cancelled(pdu)) { if (v9fs_request_cancelled(pdu)) {
return -EINTR; return -EINTR;
} }
fd = fidp->fs.fd;
v9fs_co_run_in_worker( 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) { if (err < 0) {
err = -errno; err = -errno;
} }
...@@ -226,16 +225,15 @@ int v9fs_co_link(V9fsPDU *pdu, V9fsFidState *oldfid, ...@@ -226,16 +225,15 @@ int v9fs_co_link(V9fsPDU *pdu, V9fsFidState *oldfid,
int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp, int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp,
struct iovec *iov, int iovcnt, int64_t offset) struct iovec *iov, int iovcnt, int64_t offset)
{ {
int fd, err; int err;
V9fsState *s = pdu->s; V9fsState *s = pdu->s;
if (v9fs_request_cancelled(pdu)) { if (v9fs_request_cancelled(pdu)) {
return -EINTR; return -EINTR;
} }
fd = fidp->fs.fd;
v9fs_co_run_in_worker( 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) { if (err < 0) {
err = -errno; err = -errno;
} }
...@@ -246,16 +244,15 @@ int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp, ...@@ -246,16 +244,15 @@ int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp,
int v9fs_co_preadv(V9fsPDU *pdu, V9fsFidState *fidp, int v9fs_co_preadv(V9fsPDU *pdu, V9fsFidState *fidp,
struct iovec *iov, int iovcnt, int64_t offset) struct iovec *iov, int iovcnt, int64_t offset)
{ {
int fd, err; int err;
V9fsState *s = pdu->s; V9fsState *s = pdu->s;
if (v9fs_request_cancelled(pdu)) { if (v9fs_request_cancelled(pdu)) {
return -EINTR; return -EINTR;
} }
fd = fidp->fs.fd;
v9fs_co_run_in_worker( 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) { if (err < 0) {
err = -errno; err = -errno;
} }
......
...@@ -80,7 +80,7 @@ extern int v9fs_co_rename(V9fsPDU *, V9fsPath *, V9fsPath *); ...@@ -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_unlinkat(V9fsPDU *, V9fsPath *, V9fsString *, int flags);
extern int v9fs_co_renameat(V9fsPDU *, V9fsPath *, V9fsString *, extern int v9fs_co_renameat(V9fsPDU *, V9fsPath *, V9fsString *,
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_opendir(V9fsPDU *, V9fsFidState *);
extern int v9fs_co_open(V9fsPDU *, V9fsFidState *, int); extern int v9fs_co_open(V9fsPDU *, V9fsFidState *, int);
extern int v9fs_co_open2(V9fsPDU *, V9fsFidState *, V9fsString *, extern int v9fs_co_open2(V9fsPDU *, V9fsFidState *, V9fsString *,
...@@ -88,8 +88,8 @@ 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 *, extern int v9fs_co_lsetxattr(V9fsPDU *, V9fsPath *, V9fsString *,
void *, size_t, int); void *, size_t, int);
extern int v9fs_co_lremovexattr(V9fsPDU *, V9fsPath *, V9fsString *); extern int v9fs_co_lremovexattr(V9fsPDU *, V9fsPath *, V9fsString *);
extern int v9fs_co_closedir(V9fsPDU *, DIR *); extern int v9fs_co_closedir(V9fsPDU *, V9fsFidOpenState *);
extern int v9fs_co_close(V9fsPDU *, int); extern int v9fs_co_close(V9fsPDU *, V9fsFidOpenState *);
extern int v9fs_co_fsync(V9fsPDU *, V9fsFidState *, int); extern int v9fs_co_fsync(V9fsPDU *, V9fsFidState *, int);
extern int v9fs_co_symlink(V9fsPDU *, V9fsFidState *, V9fsString *, extern int v9fs_co_symlink(V9fsPDU *, V9fsFidState *, V9fsString *,
const char *, gid_t, struct stat *); const char *, gid_t, struct stat *);
......
...@@ -133,81 +133,91 @@ static ssize_t handle_readlink(FsContext *fs_ctx, V9fsPath *fs_path, ...@@ -133,81 +133,91 @@ static ssize_t handle_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
return ret; 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; 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; int ret;
fd = handle_open(ctx, fs_path, O_DIRECTORY); ret = handle_open(ctx, fs_path, O_DIRECTORY, fs);
if (fd < 0) { if (ret < 0) {
return NULL; 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) 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) int iovcnt, off_t offset)
{ {
#ifdef CONFIG_PREADV #ifdef CONFIG_PREADV
return preadv(fd, iov, iovcnt, offset); return preadv(fs->fd, iov, iovcnt, offset);
#else #else
int err = lseek(fd, offset, SEEK_SET); int err = lseek(fs->fd, offset, SEEK_SET);
if (err == -1) { if (err == -1) {
return err; return err;
} else { } else {
return readv(fd, iov, iovcnt); return readv(fs->fd, iov, iovcnt);
} }
#endif #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) int iovcnt, off_t offset)
{ {
ssize_t ret; ssize_t ret;
#ifdef CONFIG_PREADV #ifdef CONFIG_PREADV
ret = pwritev(fd, iov, iovcnt, offset); ret = pwritev(fs->fd, iov, iovcnt, offset);
#else #else
int err = lseek(fd, offset, SEEK_SET); int err = lseek(fs->fd, offset, SEEK_SET);
if (err == -1) { if (err == -1) {
return err; return err;
} else { } else {
ret = writev(fd, iov, iovcnt); ret = writev(fs->fd, iov, iovcnt);
} }
#endif #endif
#ifdef CONFIG_SYNC_FILE_RANGE #ifdef CONFIG_SYNC_FILE_RANGE
...@@ -217,7 +227,7 @@ static ssize_t handle_pwritev(FsContext *ctx, int fd, const struct iovec *iov, ...@@ -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 * We want to ensure that we don't leave dirty pages in the cache
* after write when writeout=immediate is sepcified. * 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); SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE);
} }
#endif #endif
...@@ -274,13 +284,14 @@ static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, ...@@ -274,13 +284,14 @@ static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
return ret; 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, 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 ret;
int dirfd, fd; int dirfd, fd;
...@@ -296,6 +307,8 @@ static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, ...@@ -296,6 +307,8 @@ static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
if (ret < 0) { if (ret < 0) {
close(fd); close(fd);
fd = ret; fd = ret;
} else {
fs->fd = fd;
} }
} }
close(dirfd); close(dirfd);
...@@ -411,12 +424,12 @@ static int handle_remove(FsContext *ctx, const char *path) ...@@ -411,12 +424,12 @@ static int handle_remove(FsContext *ctx, const char *path)
return -1; return -1;
} }
static int handle_fsync(FsContext *ctx, int fd, int datasync) static int handle_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
{ {
if (datasync) { if (datasync) {
return qemu_fdatasync(fd); return qemu_fdatasync(fs->fd);
} else { } else {
return fsync(fd); return fsync(fs->fd);
} }
} }
...@@ -575,7 +588,8 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir, ...@@ -575,7 +588,8 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir,
static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
mode_t st_mode, uint64_t *st_gen) 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 * 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, ...@@ -584,12 +598,12 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) { if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
return 0; return 0;
} }
fd = handle_open(ctx, path, O_RDONLY); err = handle_open(ctx, path, O_RDONLY, &fid_open);
if (fd < 0) { if (err < 0) {
return fd; return err;
} }
err = ioctl(fd, FS_IOC_GETVERSION, st_gen); err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
handle_close(ctx, fd); handle_close(ctx, &fid_open);
return err; return err;
} }
......
...@@ -156,81 +156,91 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path, ...@@ -156,81 +156,91 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
return tsize; 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 buffer[PATH_MAX];
char *path = fs_path->data; 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 buffer[PATH_MAX];
char *path = fs_path->data; 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) 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) int iovcnt, off_t offset)
{ {
#ifdef CONFIG_PREADV #ifdef CONFIG_PREADV
return preadv(fd, iov, iovcnt, offset); return preadv(fs->fd, iov, iovcnt, offset);
#else #else
int err = lseek(fd, offset, SEEK_SET); int err = lseek(fs->fd, offset, SEEK_SET);
if (err == -1) { if (err == -1) {
return err; return err;
} else { } else {
return readv(fd, iov, iovcnt); return readv(fs->fd, iov, iovcnt);
} }
#endif #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) int iovcnt, off_t offset)
{ {
ssize_t ret ssize_t ret
; ;
#ifdef CONFIG_PREADV #ifdef CONFIG_PREADV
ret = pwritev(fd, iov, iovcnt, offset); ret = pwritev(fs->fd, iov, iovcnt, offset);
#else #else
int err = lseek(fd, offset, SEEK_SET); int err = lseek(fs->fd, offset, SEEK_SET);
if (err == -1) { if (err == -1) {
return err; return err;
} else { } else {
ret = writev(fd, iov, iovcnt); ret = writev(fs->fd, iov, iovcnt);
} }
#endif #endif
#ifdef CONFIG_SYNC_FILE_RANGE #ifdef CONFIG_SYNC_FILE_RANGE
...@@ -240,7 +250,7 @@ static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov, ...@@ -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 * We want to ensure that we don't leave dirty pages in the cache
* after write when writeout=immediate is sepcified. * 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); SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE);
} }
#endif #endif
...@@ -356,10 +366,11 @@ out: ...@@ -356,10 +366,11 @@ out:
return err; 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; int err;
err = fstat(fd, stbuf); err = fstat(fs->fd, stbuf);
if (err) { if (err) {
return err; return err;
} }
...@@ -370,16 +381,20 @@ static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) ...@@ -370,16 +381,20 @@ static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf)
mode_t tmp_mode; mode_t tmp_mode;
dev_t tmp_dev; 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; 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; 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; 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; stbuf->st_rdev = tmp_dev;
} }
} }
...@@ -387,7 +402,7 @@ static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) ...@@ -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, 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; char *path;
int fd = -1; int fd = -1;
...@@ -428,6 +443,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, ...@@ -428,6 +443,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
} }
} }
err = fd; err = fd;
fs->fd = fd;
goto out; goto out;
err_end: err_end:
...@@ -577,12 +593,12 @@ static int local_remove(FsContext *ctx, const char *path) ...@@ -577,12 +593,12 @@ static int local_remove(FsContext *ctx, const char *path)
return remove(rpath(ctx, path, buffer)); 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) { if (datasync) {
return qemu_fdatasync(fd); return qemu_fdatasync(fs->fd);
} else { } else {
return fsync(fd); return fsync(fs->fd);
} }
} }
...@@ -677,7 +693,9 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir, ...@@ -677,7 +693,9 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
mode_t st_mode, uint64_t *st_gen) 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 * Do not try to open special files like device nodes, fifos etc
* We can get fd for regular files and directories only * We can get fd for regular files and directories only
...@@ -685,12 +703,12 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, ...@@ -685,12 +703,12 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) { if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) {
return 0; return 0;
} }
fd = local_open(ctx, path, O_RDONLY); err = local_open(ctx, path, O_RDONLY, &fid_open);
if (fd < 0) { if (err < 0) {
return fd; return err;
} }
err = ioctl(fd, FS_IOC_GETVERSION, st_gen); err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
local_close(ctx, fd); local_close(ctx, &fid_open);
return err; return err;
} }
......
...@@ -455,11 +455,11 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp) ...@@ -455,11 +455,11 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp)
if (fidp->fid_type == P9_FID_FILE) { if (fidp->fid_type == P9_FID_FILE) {
/* If we reclaimed the fd no need to close */ /* If we reclaimed the fd no need to close */
if (fidp->fs.fd != -1) { 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) { } else if (fidp->fid_type == P9_FID_DIR) {
if (fidp->fs.dir != NULL) { 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) { } else if (fidp->fid_type == P9_FID_XATTR) {
retval = v9fs_xattr_fid_clunk(pdu, fidp); retval = v9fs_xattr_fid_clunk(pdu, fidp);
...@@ -567,9 +567,9 @@ void v9fs_reclaim_fd(V9fsPDU *pdu) ...@@ -567,9 +567,9 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
f = reclaim_list; f = reclaim_list;
reclaim_list = f->rclm_lst; reclaim_list = f->rclm_lst;
if (f->fid_type == P9_FID_FILE) { 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) { } 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; f->rclm_lst = NULL;
/* /*
...@@ -3009,7 +3009,7 @@ static void v9fs_lock(void *opaque) ...@@ -3009,7 +3009,7 @@ static void v9fs_lock(void *opaque)
err = -ENOENT; err = -ENOENT;
goto out_nofid; goto out_nofid;
} }
err = v9fs_co_fstat(pdu, fidp->fs.fd, &stbuf); err = v9fs_co_fstat(pdu, fidp, &stbuf);
if (err < 0) { if (err < 0) {
goto out; goto out;
} }
...@@ -3052,7 +3052,7 @@ static void v9fs_getlock(void *opaque) ...@@ -3052,7 +3052,7 @@ static void v9fs_getlock(void *opaque)
err = -ENOENT; err = -ENOENT;
goto out_nofid; goto out_nofid;
} }
err = v9fs_co_fstat(pdu, fidp->fs.fd, &stbuf); err = v9fs_co_fstat(pdu, fidp, &stbuf);
if (err < 0) { if (err < 0) {
goto out; goto out;
} }
......
...@@ -204,20 +204,23 @@ typedef struct V9fsXattr ...@@ -204,20 +204,23 @@ typedef struct V9fsXattr
int flags; int flags;
} V9fsXattr; } V9fsXattr;
/*
* Filled by fs driver on open and other
* calls.
*/
union V9fsFidOpenState {
int fd;
DIR *dir;
V9fsXattr xattr;
};
struct V9fsFidState struct V9fsFidState
{ {
int fid_type; int fid_type;
int32_t fid; int32_t fid;
V9fsPath path; V9fsPath path;
union { V9fsFidOpenState fs;
int fd; V9fsFidOpenState fs_reclaim;
DIR *dir;
V9fsXattr xattr;
} fs;
union {
int fd;
DIR *dir;
} fs_reclaim;
int flags; int flags;
int open_flags; int open_flags;
uid_t uid; uid_t uid;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册