#pragma once #include #include #include #include #include #include #include #include #define NODE_MAJOR(node) (((node) >> 8) & 0xFFU) #define NODE_MINOR(node) ((node) & 0xFFU) namespace fs { constexpr dev_t make_device(uint32_t major, uint32_t minor) { return ((major << 8) & 0xFF00U) | (minor & 0xFFU); } // buf, buf_size, cnt using chrdev_read = std::function; // buf, cnt using chrdev_write = std::function; struct chrdev_ops { chrdev_read read; chrdev_write write; }; struct PACKED user_dirent { ino_t d_ino; // inode number uint32_t d_off; // ignored uint16_t d_reclen; // length of this struct user_dirent char d_name[1]; // file name with a padding zero // uint8_t d_type; // file type, with offset of (d_reclen - 1) }; struct PACKED user_dirent64 { ino64_t d_ino; // inode number uint64_t d_off; // implementation-defined field, ignored uint16_t d_reclen; // length of this struct user_dirent uint8_t d_type; // file type, with offset of (d_reclen - 1) char d_name[1]; // file name with a padding zero }; struct fs_context { dentry_pointer root; }; int register_char_device(dev_t node, const chrdev_ops& ops); ssize_t char_device_read(dev_t node, char* buf, size_t buf_size, size_t n); ssize_t char_device_write(dev_t node, const char* buf, size_t n); extern "C" int fs_creat(struct dentry* at, mode_t mode); extern "C" int fs_mkdir(struct dentry* at, mode_t mode); extern "C" int fs_mknod(struct dentry* at, mode_t mode, dev_t sn); extern "C" int fs_unlink(struct dentry* at); extern "C" int fs_symlink(struct dentry* at, const char* target); extern "C" int fs_statx(const struct rust_inode_handle* inode, struct statx* stat, unsigned int mask); extern "C" int fs_readlink(const struct rust_inode_handle* inode, char* buf, size_t buf_size); extern "C" int fs_truncate(const struct rust_inode_handle* file, size_t size); extern "C" size_t fs_read(const struct rust_inode_handle* file, char* buf, size_t buf_size, size_t offset, size_t n); extern "C" size_t fs_write(const struct rust_inode_handle* file, const char* buf, size_t offset, size_t n); using readdir_callback_fn = std::function; extern "C" ssize_t fs_readdir(const struct rust_inode_handle* file, size_t offset, const readdir_callback_fn* callback); extern "C" int fs_mount(dentry* mnt, const char* source, const char* mount_point, const char* fstype, unsigned long flags, const void* data); extern "C" mode_t r_get_inode_mode(struct rust_inode_handle* inode); extern "C" size_t r_get_inode_size(struct rust_inode_handle* inode); extern "C" bool r_dentry_is_directory(struct dentry* dentry); extern "C" bool r_dentry_is_invalid(struct dentry* dentry); // borrow from dentry->inode extern "C" struct rust_inode_handle* r_dentry_get_inode(struct dentry* dentry); extern "C" struct dentry* r_get_root_dentry(); #define current_open(...) \ fs::open(current_process->fs_context, current_process->cwd, __VA_ARGS__) std::pair open(const fs_context& context, const dentry_pointer& cwd, types::string_view path, bool follow_symlinks = true); } // namespace fs