Commit cc720ddb authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V
Browse files

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: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
parent 2c74c2cb
Loading
Loading
Loading
Loading
+19 −13
Original line number Diff line number Diff line
@@ -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);
+8 −8
Original line number Diff line number Diff line
@@ -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;
            }
+17 −20
Original line number Diff line number Diff line
@@ -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;
            }
+3 −3
Original line number Diff line number Diff line
@@ -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 *);
+55 −41
Original line number Diff line number Diff line
@@ -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;
}

Loading