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;
|
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
|
||||||
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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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 *);
|
||||||
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 *,
|
||||||
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,
|
||||||
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,
|
||||||
* 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,
|
||||||
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,
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
* 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:
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue