From aa2ad378297b9f0a71d380665e6cbaf3d45d83b9 Mon Sep 17 00:00:00 2001 From: Mat King Date: Wed, 23 Oct 2024 11:59:24 -0600 Subject: [PATCH] Crude ioctl support for lklfuse --- tools/lkl/include/lkl.h | 2 ++ tools/lkl/lib/fs.c | 21 ++++++++++++++ tools/lkl/lklfuse.c | 64 +++++++++++++++++++++++++++++------------ 3 files changed, 68 insertions(+), 19 deletions(-) diff --git a/tools/lkl/include/lkl.h b/tools/lkl/include/lkl.h index 6abc2a698c73..4daddf167df1 100644 --- a/tools/lkl/include/lkl.h +++ b/tools/lkl/include/lkl.h @@ -502,6 +502,8 @@ long lkl_umount_timeout(char *path, int flags, long timeout_ms); */ struct lkl_dir *lkl_opendir(const char *path, int *err); +struct lkl_dir *lkl_open(const char *file, int flags, int mode, int *err); + /** * lkl_fdopendir - open a directory * diff --git a/tools/lkl/lib/fs.c b/tools/lkl/lib/fs.c index 9fefa1f5c542..7a06ffd2f19b 100644 --- a/tools/lkl/lib/fs.c +++ b/tools/lkl/lib/fs.c @@ -369,6 +369,27 @@ struct lkl_dir *lkl_opendir(const char *path, int *err) return dir; } +struct lkl_dir *lkl_open(const char *file, int flags, int mode, int *err) +{ + struct lkl_dir *dir = lkl_dir_alloc(err); + + if (!dir) { + *err = -LKL_ENOMEM; + return NULL; + } + + dir->fd = lkl_sys_open(file, flags, mode); + if (dir->fd < 0) { + *err = dir->fd; + lkl_host_ops.mem_free(dir); + return NULL; + } + + *err = 0; + + return dir; +} + struct lkl_dir *lkl_fdopendir(int fd, int *err) { struct lkl_dir *dir = lkl_dir_alloc(err); diff --git a/tools/lkl/lklfuse.c b/tools/lkl/lklfuse.c index d71b4b0df6ef..24b9b8b81108 100644 --- a/tools/lkl/lklfuse.c +++ b/tools/lkl/lklfuse.c @@ -134,17 +134,24 @@ static void lklfuse_xlat_stat(const struct lkl_stat *in, struct stat *st) static int lklfuse_getattr(const char *path, struct stat *st, struct fuse_file_info *fi) { + struct lkl_dir *dir; long ret; struct lkl_stat lkl_stat; + fprintf(stderr, "getattr: \n\tpath: %s\n\tfi: %p\n", path, fi); /* * With nullpath_ok, path will be provided only if the struct * fuse_file_info argument is NULL. */ - if (fi) - ret = lkl_sys_fstat(fi->fh, &lkl_stat); - else + if (fi) { + dir = (struct lkl_dir *)(uintptr_t)fi->fh; + fprintf(stderr, "getattr: \n\tdir: %p\n", dir); + ret = lkl_sys_fstat(lkl_dirfd(dir), &lkl_stat); + } + else { + fprintf(stderr, "getattr: \n\tpath: %s\n", path); ret = lkl_sys_lstat(path, &lkl_stat); + } if (!ret) lklfuse_xlat_stat(&lkl_stat, st); @@ -209,10 +216,11 @@ static int lklfuse_link(const char *oldname, const char *newname) static int lklfuse_chmod(const char *path, mode_t mode, struct fuse_file_info *fi) { + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; int ret; if (fi) - ret = lkl_sys_fchmod(fi->fh, mode); + ret = lkl_sys_fchmod(lkl_dirfd(dir), mode); else ret = lkl_sys_fchmodat(LKL_AT_FDCWD, path, mode); @@ -222,10 +230,11 @@ static int lklfuse_chmod(const char *path, mode_t mode, static int lklfuse_chown(const char *path, uid_t uid, gid_t gid, struct fuse_file_info *fi) { + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; int ret; if (fi) - ret = lkl_sys_fchown(fi->fh, uid, gid); + ret = lkl_sys_fchown(lkl_dirfd(dir), uid, gid); else ret = lkl_sys_fchownat(LKL_AT_FDCWD, path, uid, gid, LKL_AT_SYMLINK_NOFOLLOW); @@ -235,10 +244,11 @@ static int lklfuse_chown(const char *path, uid_t uid, gid_t gid, static int lklfuse_truncate(const char *path, off_t off, struct fuse_file_info *fi) { + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; int ret; if (fi) - ret = lkl_sys_ftruncate(fi->fh, off); + ret = lkl_sys_ftruncate(lkl_dirfd(dir), off); else ret = lkl_sys_truncate(path, off); @@ -248,7 +258,8 @@ static int lklfuse_truncate(const char *path, off_t off, static int lklfuse_open3(const char *path, bool create, mode_t mode, struct fuse_file_info *fi) { - long ret; + struct lkl_dir *dir; + int err; int flags; if ((fi->flags & O_ACCMODE) == O_RDONLY) @@ -294,11 +305,11 @@ static int lklfuse_open3(const char *path, bool create, mode_t mode, if (fi->flags & O_TMPFILE) flags |= LKL_O_TMPFILE; - ret = lkl_sys_open(path, flags, mode); - if (ret < 0) - return ret; + dir = lkl_open(path, flags, mode, &err); + if (!dir) + return err; - fi->fh = ret; + fi->fh = (uintptr_t)dir; return 0; } @@ -317,11 +328,12 @@ static int lklfuse_open(const char *path, struct fuse_file_info *fi) static int lklfuse_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; long ret; ssize_t orig_size = size; do { - ret = lkl_sys_pread64(fi->fh, buf, size, offset); + ret = lkl_sys_pread64(lkl_dirfd(dir), buf, size, offset); if (ret <= 0) break; size -= ret; @@ -336,11 +348,12 @@ static int lklfuse_read(const char *path, char *buf, size_t size, off_t offset, static int lklfuse_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; long ret; ssize_t orig_size = size; do { - ret = lkl_sys_pwrite64(fi->fh, buf, size, offset); + ret = lkl_sys_pwrite64(lkl_dirfd(dir), buf, size, offset); if (ret <= 0) break; size -= ret; @@ -383,16 +396,19 @@ static int lklfuse_flush(const char *path, struct fuse_file_info *fi) static int lklfuse_release(const char *path, struct fuse_file_info *fi) { - return lkl_sys_close(fi->fh); + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; + + return lkl_closedir(dir); } static int lklfuse_fsync(const char *path, int datasync, struct fuse_file_info *fi) { + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; if (datasync) - return lkl_sys_fdatasync(fi->fh); + return lkl_sys_fdatasync(lkl_dirfd(dir)); else - return lkl_sys_fsync(fi->fh); + return lkl_sys_fsync(lkl_dirfd(dir)); } static int lklfuse_setxattr(const char *path, const char *name, const char *val, @@ -502,6 +518,7 @@ static int lklfuse_access(const char *path, int mode) static int lklfuse_utimens(const char *path, const struct timespec tv[2], struct fuse_file_info *fi) { + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; int ret; struct lkl_timespec ts[2] = { { .tv_sec = tv[0].tv_sec, .tv_nsec = tv[0].tv_nsec }, @@ -509,7 +526,7 @@ static int lklfuse_utimens(const char *path, const struct timespec tv[2], }; if (fi) - ret = lkl_sys_utimensat(fi->fh, NULL, + ret = lkl_sys_utimensat(lkl_dirfd(dir), NULL, (struct __lkl__kernel_timespec *)ts, 0); else @@ -522,7 +539,16 @@ static int lklfuse_utimens(const char *path, const struct timespec tv[2], static int lklfuse_fallocate(const char *path, int mode, off_t offset, off_t len, struct fuse_file_info *fi) { - return lkl_sys_fallocate(fi->fh, mode, offset, len); + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; + return lkl_sys_fallocate(lkl_dirfd(dir), mode, offset, len); +} + +static int lklfuse_ioctl(const char *path, unsigned int cmd, void *arg, + struct fuse_file_info *fi, unsigned int flags, void *data) +{ + struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh; + fprintf(stderr, "ioctl: \n\tpath: %s\n\tfd: %p\n\tcmd: %p\n\targ: %p\n\tflags: %d\n\tdata: %p\n", path, lkl_dirfd(dir), cmd, arg, flags, data); + return lkl_sys_ioctl(lkl_dirfd(dir), cmd, data); } static void *lklfuse_init(struct fuse_conn_info *conn, struct fuse_config *cfg) @@ -573,7 +599,7 @@ const struct fuse_operations lklfuse_ops = { /* .lock, */ .utimens = lklfuse_utimens, /* .bmap, */ - /* .ioctl, */ + .ioctl = lklfuse_ioctl, /* .poll, */ /* .write_buf, (SG io) */ /* .read_buf, (SG io) */ -- 2.39.5