diff options
Diffstat (limited to 'hw/9pfs/virtio-9p-local.c')
-rw-r--r-- | hw/9pfs/virtio-9p-local.c | 113 |
1 files changed, 64 insertions, 49 deletions
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index d561de88f0..782dc0ab21 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -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 @@ -281,7 +291,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, if (err == -1) { goto out; } - local_set_xattr(rpath(fs_ctx, path, buffer), credp); + err = local_set_xattr(rpath(fs_ctx, path, buffer), credp); if (err == -1) { serrno = errno; goto err_end; @@ -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: @@ -551,15 +567,12 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) char *path = fs_path->data; if ((credp->fc_uid == -1 && credp->fc_gid == -1) || - (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH)) { - return lchown(rpath(fs_ctx, path, buffer), credp->fc_uid, - credp->fc_gid); + (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || + (fs_ctx->export_flags & V9FS_SM_NONE)) { + return lchown(rpath(fs_ctx, path, buffer), + credp->fc_uid, credp->fc_gid); } else if (fs_ctx->export_flags & V9FS_SM_MAPPED) { return local_set_xattr(rpath(fs_ctx, path, buffer), credp); - } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || - (fs_ctx->export_flags & V9FS_SM_NONE)) { - return lchown(rpath(fs_ctx, path, buffer), credp->fc_uid, - credp->fc_gid); } return -1; } @@ -580,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); } } @@ -680,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 @@ -688,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; } |