From d57ee3ae693448387e3022fdd07bd741b2db818a Mon Sep 17 00:00:00 2001 From: Minep Date: Sat, 20 Aug 2022 17:30:33 +0100 Subject: [PATCH] feat: ability to manipulate extended attribute chore: minor refactoring and fix. --- README.md | 34 ++-- lunaix-os/includes/lib/hash.h | 4 +- lunaix-os/includes/lunaix/ds/hstr.h | 2 +- lunaix-os/includes/lunaix/fctrl.h | 44 +++++ lunaix-os/includes/lunaix/fs.h | 54 ++++++ lunaix-os/includes/lunaix/status.h | 7 +- lunaix-os/includes/lunaix/syscall.h | 4 + lunaix-os/kernel/asm/x86/syscall.S | 4 + lunaix-os/kernel/fs/path_walk.c | 187 ++++++++++++++++++++ lunaix-os/kernel/fs/vfs.c | 219 ++---------------------- lunaix-os/kernel/fs/xattr.c | 257 ++++++++++++++++++++++++++++ lunaix-os/libs/hash.c | 2 +- 12 files changed, 594 insertions(+), 224 deletions(-) create mode 100644 lunaix-os/kernel/fs/path_walk.c create mode 100644 lunaix-os/kernel/fs/xattr.c diff --git a/README.md b/README.md index ebaf251..1a71e57 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ LunaixOS - 一个简单的,详细的,POSIX兼容的(但愿!),带有 + 内存管理与按需分页(Demand Paging) + 键盘输入 + 多进程 -+ 40个常见的Linux/POSIX系统调用([附录1](#appendix1)) ++ 44个常见的Linux/POSIX系统调用([附录1](#appendix1)) + 用户模式 + 信号机制 + PCI 3.0 @@ -148,7 +148,7 @@ qemu-img create -f vdi machine/disk0.vdi 128M ## 附录1:支持的系统调用 -### Unix/Linux/POSIX +**Unix/Linux/POSIX** 1. `sleep(3)` 1. `wait(2)` 1. `waitpid(2)` @@ -170,32 +170,38 @@ qemu-img create -f vdi machine/disk0.vdi 128M 2. `write(2)` 2. `open(2)` 2. `close(2)` -2. `mkdir(2)` +2. `mkdir(2)`※ 2. `lseek(2)` 2. `readdir(2)` -2. `readlink(2)` -2. `readlinkat(2)` -2. `rmdir(2)` -2. `unlink(2)` -2. `unlinkat(2)` -2. `link(2)` -2. `fsync(2)` +2. `readlink(2)`※ +2. `readlinkat(2)`※ +2. `rmdir(2)`※ +2. `unlink(2)`※ +2. `unlinkat(2)`※ +2. `link(2)`※ +2. `fsync(2)`※ 2. `dup(2)` 2. `dup2(2)` -2. `symlink(2)` +2. `symlink(2)`※ 2. `chdir(2)` 2. `fchdir(2)` 2. `getcwd(2)` -2. `rename(2)` +2. `rename(2)`※ 2. `mount(2)` -2. `unmount` (a.k.a `umount(2)`) +2. `unmount` (a.k.a `umount(2)`)※ +2. `getxattr(2)`※ +2. `setxattr(2)`※ +2. `fgetxattr(2)`※ +2. `fsetxattr(2)`※ -### LunaixOS自有 +**LunaixOS自有** 1. `yield` 2. `geterrno` 3. `realpathat` +( **※**:该系统调用暂未经过测试 ) + ## 附录2:编译gcc作为交叉编译器 注意,gcc需要从源码构建,并配置为交叉编译器,即目标平台为`i686-elf`。你可以使用本项目提供的[自动化脚本](slides/c0-workspace/gcc-build.sh),这将会涵盖gcc和binutils源码的下载,配置和编译(没什么时间去打磨脚本,目前只知道在笔者的Ubuntu系统上可以运行)。 diff --git a/lunaix-os/includes/lib/hash.h b/lunaix-os/includes/lib/hash.h index 22998f7..f98fe28 100644 --- a/lunaix-os/includes/lib/hash.h +++ b/lunaix-os/includes/lib/hash.h @@ -6,7 +6,7 @@ #define HASH_SIZE_BITS 32 uint32_t -strhash_32(char* str, uint32_t truncate_to); +strhash_32(const char* str, uint32_t truncate_to); /** * @brief Simple generic hash function @@ -18,7 +18,7 @@ strhash_32(char* str, uint32_t truncate_to); * @return uint32_t */ inline uint32_t -hash_32(uint32_t val, uint32_t truncate_to) +hash_32(const uint32_t val, uint32_t truncate_to) { return (val * 0x61C88647u) >> (HASH_SIZE_BITS - truncate_to); } diff --git a/lunaix-os/includes/lunaix/ds/hstr.h b/lunaix-os/includes/lunaix/ds/hstr.h index 4b6947e..5dab1cb 100644 --- a/lunaix-os/includes/lunaix/ds/hstr.h +++ b/lunaix-os/includes/lunaix/ds/hstr.h @@ -9,7 +9,7 @@ struct hstr { uint32_t hash; uint32_t len; - char* value; + const char* value; }; #define HSTR(str, length) \ diff --git a/lunaix-os/includes/lunaix/fctrl.h b/lunaix-os/includes/lunaix/fctrl.h index 85f49ac..8a46058 100644 --- a/lunaix-os/includes/lunaix/fctrl.h +++ b/lunaix-os/includes/lunaix/fctrl.h @@ -36,4 +36,48 @@ __LXSYSCALL3(int, __LXSYSCALL1(int, unmount, const char*, target) +__LXSYSCALL4(int, + getxattr, + const char*, + path, + const char*, + name, + void*, + value, + size_t, + len) + +__LXSYSCALL4(int, + setxattr, + const char*, + path, + const char*, + name, + void*, + value, + size_t, + len) + +__LXSYSCALL4(int, + fgetxattr, + int, + fd, + const char*, + name, + void*, + value, + size_t, + len) + +__LXSYSCALL4(int, + fsetxattr, + int, + fd, + const char*, + name, + void*, + value, + size_t, + len) + #endif /* __LUNAIX_FCTRL_H */ diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index d43293b..c86c6bc 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,8 @@ #define VFS_HASH_MASK (VFS_HASHTABLE_SIZE - 1) #define VFS_HASHBITS (32 - VFS_HASHTABLE_BITS) +#define VFS_PATH_DELIM '/' + #define FSTYPE_ROFS 0x1 #define DO_STATUS(errno) SYSCALL_ESTATUS(__current->k_status = errno) @@ -43,6 +46,20 @@ ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' || \ (chr) == '-') +#define unlock_inode(inode) mutex_unlock(&inode->lock) +#define lock_inode(inode) \ + ({ \ + mutex_lock(&inode->lock); \ + lru_use_one(inode_lru, &inode->lru); \ + }) + +#define unlock_dnode(dnode) mutex_unlock(&dnode->lock) +#define lock_dnode(dnode) \ + ({ \ + mutex_lock(&dnode->lock); \ + lru_use_one(dnode_lru, &dnode->lru); \ + }) + typedef uint32_t inode_t; struct v_dnode; @@ -53,6 +70,7 @@ struct v_file_ops; struct v_inode_ops; struct v_fd; struct pcache; +struct v_xattr_entry; extern struct v_file_ops default_file_ops; extern struct v_inode_ops default_inode_ops; @@ -122,6 +140,17 @@ struct v_inode_ops int (*rename)(struct v_inode* from_inode, struct v_dnode* from_dnode, struct v_dnode* to_dnode); + int (*getxattr)(struct v_inode* this, struct v_xattr_entry* entry); + int (*setxattr)(struct v_inode* this, struct v_xattr_entry* entry); + int (*delxattr)(struct v_inode* this, struct v_xattr_entry* entry); +}; + +struct v_xattr_entry +{ + struct llist_header entries; + struct hstr name; + const void* value; + size_t len; }; struct v_file @@ -153,6 +182,7 @@ struct v_inode uint32_t link_count; uint32_t lb_usage; uint32_t fsize; + struct llist_header xattrs; struct v_superblock* sb; struct hlist_node hash_list; struct lru_node lru; @@ -241,6 +271,12 @@ vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str); void vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode); +void +vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode); + +void +vfs_dcache_remove(struct v_dnode* dnode); + int vfs_walk(struct v_dnode* start, const char* path, @@ -248,6 +284,12 @@ vfs_walk(struct v_dnode* start, struct hstr* component, int walk_options); +int +vfs_walk_proc(const char* path, + struct v_dnode** dentry, + struct hstr* component, + int options); + int vfs_mount(const char* target, const char* fs_name, struct device* device); @@ -304,6 +346,9 @@ vfs_i_free(struct v_inode* inode); int vfs_dup_fd(struct v_fd* old, struct v_fd** new); +int +vfs_getfd(int fd, struct v_fd** fd_s); + void pcache_init(struct pcache* pcache); @@ -397,4 +442,13 @@ default_inode_rmdir(struct v_inode* this, struct v_dnode* dir); int default_inode_mkdir(struct v_inode* this, struct v_dnode* dir); +struct v_xattr_entry* +xattr_new(struct hstr* name); + +struct v_xattr_entry* +xattr_getcache(struct v_inode* inode, struct hstr* name); + +void +xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr); + #endif /* __LUNAIX_VFS_H */ diff --git a/lunaix-os/includes/lunaix/status.h b/lunaix-os/includes/lunaix/status.h index a108ea2..2368156 100644 --- a/lunaix-os/includes/lunaix/status.h +++ b/lunaix-os/includes/lunaix/status.h @@ -24,10 +24,9 @@ #define EISDIR -19 #define EBUSY -20 #define EXDEV -21 -#define ELOOP -22 -#define ENODEV -23 -#define ERANGE -24 +#define ENODEV -22 +#define ERANGE -23 #define ENOMEM LXOUTOFMEM -#define ENOTDEV -25 +#define ENOTDEV -24 #endif /* __LUNAIX_CODE_H */ diff --git a/lunaix-os/includes/lunaix/syscall.h b/lunaix-os/includes/lunaix/syscall.h index 5e0272f..98f5585 100644 --- a/lunaix-os/includes/lunaix/syscall.h +++ b/lunaix-os/includes/lunaix/syscall.h @@ -49,6 +49,10 @@ #define __SYSCALL_rename 41 #define __SYSCALL_mount 42 #define __SYSCALL_unmount 43 +#define __SYSCALL_getxattr 44 +#define __SYSCALL_setxattr 45 +#define __SYSCALL_fgetxattr 46 +#define __SYSCALL_fsetxattr 47 #define __SYSCALL_MAX 0x100 diff --git a/lunaix-os/kernel/asm/x86/syscall.S b/lunaix-os/kernel/asm/x86/syscall.S index 2d78828..b8d0219 100644 --- a/lunaix-os/kernel/asm/x86/syscall.S +++ b/lunaix-os/kernel/asm/x86/syscall.S @@ -51,6 +51,10 @@ .long __lxsys_rename .long __lxsys_mount .long __lxsys_unmount + .long __lxsys_getxattr + .long __lxsys_setxattr /* 45 */ + .long __lxsys_fgetxattr + .long __lxsys_fsetxattr 2: .rept __SYSCALL_MAX - (2b - 1b)/4 .long 0 diff --git a/lunaix-os/kernel/fs/path_walk.c b/lunaix-os/kernel/fs/path_walk.c new file mode 100644 index 0000000..0ffbabb --- /dev/null +++ b/lunaix-os/kernel/fs/path_walk.c @@ -0,0 +1,187 @@ +#include +#include +#include + +#include + +#define VFS_SYMLINK_DEPTH 16 + +extern struct lru_zone *dnode_lru, *inode_lru; + +int +__vfs_walk(struct v_dnode* start, + const char* path, + struct v_dnode** dentry, + struct hstr* component, + int walk_options, + size_t depth, + char* fname_buffer) +{ + int errno = 0; + int i = 0, j = 0; + + if (depth >= VFS_SYMLINK_DEPTH) { + return ENAMETOOLONG; + } + + if (path[0] == VFS_PATH_DELIM || !start) { + if ((walk_options & VFS_WALK_FSRELATIVE) && start) { + start = start->super_block->root; + } else { + start = vfs_sysroot; + if (!vfs_sysroot->mnt) { + panick("vfs: no root"); + } + } + i++; + } + + struct v_dnode* dnode; + struct v_inode* current_inode; + struct v_dnode* current_level = start; + + struct hstr name = HSTR(fname_buffer, 0); + + char current = path[i++], lookahead; + while (current && current_level) { + lookahead = path[i++]; + if (current != VFS_PATH_DELIM) { + if (j >= VFS_NAME_MAXLEN - 1) { + return ENAMETOOLONG; + } + if (!VFS_VALID_CHAR(current)) { + return EINVAL; + } + fname_buffer[j++] = current; + if (lookahead) { + goto cont; + } + } + + // handling cases like /^.*(\/+).*$/ + if (lookahead == VFS_PATH_DELIM) { + goto cont; + } + + fname_buffer[j] = 0; + name.len = j; + hstr_rehash(&name, HSTR_FULL_HASH); + + if (!lookahead && (walk_options & VFS_WALK_PARENT)) { + if (component) { + component->hash = name.hash; + component->len = j; + strcpy(component->value, fname_buffer); + } + break; + } + + current_inode = current_level->inode; + + if ((current_inode->itype & VFS_IFSYMLINK) && + !(walk_options & VFS_WALK_NOFOLLOW)) { + const char* link; + + lock_inode(current_inode); + if ((errno = + current_inode->ops->read_symlink(current_inode, &link))) { + unlock_inode(current_inode); + goto error; + } + unlock_inode(current_inode); + + errno = __vfs_walk(current_level->parent, + link, + &dnode, + NULL, + 0, + depth + 1, + fname_buffer + name.len + 1); + + if (errno) { + goto error; + } + + // reposition the resolved subtree pointed by symlink + vfs_dcache_rehash(current_level->parent, dnode); + current_level = dnode; + current_inode = dnode->inode; + } + + lock_dnode(current_level); + + dnode = vfs_dcache_lookup(current_level, &name); + + if (!dnode) { + dnode = vfs_d_alloc(current_level, &name); + + if (!dnode) { + errno = ENOMEM; + goto error; + } + + lock_inode(current_inode); + + errno = current_inode->ops->dir_lookup(current_inode, dnode); + + if (errno == ENOENT && (walk_options & VFS_WALK_MKPARENT)) { + if (!current_inode->ops->mkdir) { + errno = ENOTSUP; + } else { + errno = current_inode->ops->mkdir(current_inode, dnode); + } + } + + vfs_dcache_add(current_level, dnode); + unlock_inode(current_inode); + + if (errno) { + unlock_dnode(current_level); + goto cleanup; + } + } + + unlock_dnode(current_level); + + j = 0; + current_level = dnode; + cont: + current = lookahead; + }; + + *dentry = current_level; + return 0; + +cleanup: + vfs_d_free(dnode); +error: + *dentry = NULL; + return errno; +} + +int +vfs_walk(struct v_dnode* start, + const char* path, + struct v_dnode** dentry, + struct hstr* component, + int options) +{ + // allocate a file name stack for path walking and recursion to resolve + // symlink + char* name_buffer = valloc(2048); + + int errno = + __vfs_walk(start, path, dentry, component, options, 0, name_buffer); + + vfree(name_buffer); + return errno; +} + +int +vfs_walk_proc(const char* path, + struct v_dnode** dentry, + struct hstr* component, + int options) +{ + return vfs_walk(__current->cwd, path, dentry, component, options); +} \ No newline at end of file diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index c13b8d3..a69803e 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -56,22 +56,6 @@ #include -#define PATH_DELIM '/' - -#define unlock_inode(inode) mutex_unlock(&inode->lock) -#define lock_inode(inode) \ - ({ \ - mutex_lock(&inode->lock); \ - lru_use_one(inode_lru, &inode->lru); \ - }) - -#define unlock_dnode(dnode) mutex_unlock(&dnode->lock) -#define lock_dnode(dnode) \ - ({ \ - mutex_lock(&dnode->lock); \ - lru_use_one(dnode_lru, &dnode->lru); \ - }) - static struct cake_pile* dnode_pile; static struct cake_pile* inode_pile; static struct cake_pile* file_pile; @@ -81,7 +65,7 @@ static struct cake_pile* fd_pile; struct v_dnode* vfs_sysroot; static struct hbucket* dnode_cache; -static struct lru_zone *dnode_lru, *inode_lru; +struct lru_zone *dnode_lru, *inode_lru; struct hstr vfs_ddot = HSTR("..", 2); struct hstr vfs_dot = HSTR(".", 1); @@ -194,176 +178,6 @@ vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode) vfs_dcache_add(new_parent, dnode); } -#define VFS_SYMLINK_DEPTH 16 - -int -__vfs_walk(struct v_dnode* start, - const char* path, - struct v_dnode** dentry, - struct hstr* component, - int walk_options, - size_t depth, - char* fname_buffer) -{ - int errno = 0; - int i = 0, j = 0; - - if (depth >= VFS_SYMLINK_DEPTH) { - return ENAMETOOLONG; - } - - if (path[0] == PATH_DELIM || !start) { - if ((walk_options & VFS_WALK_FSRELATIVE) && start) { - start = start->super_block->root; - } else { - start = vfs_sysroot; - if (!vfs_sysroot->mnt) { - panick("vfs: no root"); - } - } - i++; - } - - struct v_dnode* dnode; - struct v_inode* current_inode; - struct v_dnode* current_level = start; - - struct hstr name = HSTR(fname_buffer, 0); - - char current = path[i++], lookahead; - while (current && current_level) { - lookahead = path[i++]; - if (current != PATH_DELIM) { - if (j >= VFS_NAME_MAXLEN - 1) { - return ENAMETOOLONG; - } - if (!VFS_VALID_CHAR(current)) { - return EINVAL; - } - fname_buffer[j++] = current; - if (lookahead) { - goto cont; - } - } - - // handling cases like /^.*(\/+).*$/ - if (lookahead == PATH_DELIM) { - goto cont; - } - - fname_buffer[j] = 0; - name.len = j; - hstr_rehash(&name, HSTR_FULL_HASH); - - if (!lookahead && (walk_options & VFS_WALK_PARENT)) { - if (component) { - component->hash = name.hash; - component->len = j; - strcpy(component->value, fname_buffer); - } - break; - } - - current_inode = current_level->inode; - - if ((current_inode->itype & VFS_IFSYMLINK)) { - const char* link; - - lock_inode(current_inode); - if ((errno = - current_inode->ops->read_symlink(current_inode, &link))) { - unlock_inode(current_inode); - goto error; - } - unlock_inode(current_inode); - - errno = __vfs_walk(current_level->parent, - link, - &dnode, - NULL, - 0, - depth + 1, - fname_buffer + name.len + 1); - - if (errno) { - goto error; - } - - // reposition the resolved subtree pointed by symlink - vfs_dcache_rehash(current_level->parent, dnode); - current_level = dnode; - current_inode = dnode->inode; - } - - lock_dnode(current_level); - - dnode = vfs_dcache_lookup(current_level, &name); - - if (!dnode) { - dnode = vfs_d_alloc(current_level, &name); - - if (!dnode) { - errno = ENOMEM; - goto error; - } - - lock_inode(current_inode); - - errno = current_inode->ops->dir_lookup(current_inode, dnode); - - if (errno == ENOENT && (walk_options & VFS_WALK_MKPARENT)) { - if (!current_inode->ops->mkdir) { - errno = ENOTSUP; - } else { - errno = current_inode->ops->mkdir(current_inode, dnode); - } - } - - vfs_dcache_add(current_level, dnode); - unlock_inode(current_inode); - - if (errno) { - unlock_dnode(current_level); - goto cleanup; - } - } - - unlock_dnode(current_level); - - j = 0; - current_level = dnode; - cont: - current = lookahead; - }; - - *dentry = current_level; - return 0; - -cleanup: - vfs_d_free(dnode); -error: - *dentry = NULL; - return errno; -} - -int -vfs_walk(struct v_dnode* start, - const char* path, - struct v_dnode** dentry, - struct hstr* component, - int options) -{ - // allocate a file name stack for path walking and recursion to resolve - // symlink - char* name_buffer = valloc(2048); - - int errno = - __vfs_walk(start, path, dentry, component, options, 0, name_buffer); - - vfree(name_buffer); - return errno; -} - int vfs_open(struct v_dnode* dnode, struct v_file** file) { @@ -614,6 +428,7 @@ vfs_i_alloc(struct v_superblock* sb) memset(inode, 0, sizeof(*inode)); mutex_init(&inode->lock); + llist_init_head(&inode->xattrs); sb->ops.init_inode(sb, inode); @@ -644,7 +459,7 @@ vfs_i_free(struct v_inode* inode) #define FLOCATE_CREATE_EMPTY 1 int -__vfs_getfd(int fd, struct v_fd** fd_s) +vfs_getfd(int fd, struct v_fd** fd_s) { if (TEST_FD(fd) && (*fd_s = __current->fdtable->fds[fd])) { return 0; @@ -730,7 +545,7 @@ __DEFINE_LXSYSCALL1(int, close, int, fd) { struct v_fd* fd_s; int errno = 0; - if ((errno = __vfs_getfd(fd, &fd_s))) { + if ((errno = vfs_getfd(fd, &fd_s))) { goto done_err; } @@ -764,7 +579,7 @@ __DEFINE_LXSYSCALL2(int, readdir, int, fd, struct dirent*, dent) struct v_fd* fd_s; int errno; - if ((errno = __vfs_getfd(fd, &fd_s))) { + if ((errno = vfs_getfd(fd, &fd_s))) { goto done; } @@ -805,7 +620,7 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count) { int errno = 0; struct v_fd* fd_s; - if ((errno = __vfs_getfd(fd, &fd_s))) { + if ((errno = vfs_getfd(fd, &fd_s))) { goto done; } @@ -843,7 +658,7 @@ __DEFINE_LXSYSCALL3(int, write, int, fd, void*, buf, size_t, count) { int errno = 0; struct v_fd* fd_s; - if ((errno = __vfs_getfd(fd, &fd_s))) { + if ((errno = vfs_getfd(fd, &fd_s))) { goto done; } @@ -881,7 +696,7 @@ __DEFINE_LXSYSCALL3(int, lseek, int, fd, int, offset, int, options) { int errno = 0; struct v_fd* fd_s; - if ((errno = __vfs_getfd(fd, &fd_s))) { + if ((errno = vfs_getfd(fd, &fd_s))) { goto done; } @@ -933,7 +748,7 @@ vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth) len += cpy_size; if (len < size) { - buf[len++] = PATH_DELIM; + buf[len++] = VFS_PATH_DELIM; } return len; @@ -960,7 +775,7 @@ __DEFINE_LXSYSCALL3(int, realpathat, int, fd, char*, buf, size_t, size) { int errno; struct v_fd* fd_s; - if ((errno = __vfs_getfd(fd, &fd_s))) { + if ((errno = vfs_getfd(fd, &fd_s))) { goto done; } @@ -1004,7 +819,7 @@ __DEFINE_LXSYSCALL4(int, { int errno; struct v_fd* fd_s; - if ((errno = __vfs_getfd(dirfd, &fd_s))) { + if ((errno = vfs_getfd(dirfd, &fd_s))) { goto done; } @@ -1176,7 +991,7 @@ __DEFINE_LXSYSCALL2(int, unlinkat, int, fd, const char*, pathname) { int errno; struct v_fd* fd_s; - if ((errno = __vfs_getfd(fd, &fd_s))) { + if ((errno = vfs_getfd(fd, &fd_s))) { goto done; } @@ -1211,7 +1026,7 @@ __DEFINE_LXSYSCALL1(int, fsync, int, fildes) { int errno; struct v_fd* fd_s; - if (!(errno = __vfs_getfd(fildes, &fd_s))) { + if (!(errno = vfs_getfd(fildes, &fd_s))) { errno = vfs_fsync(fd_s->file); } @@ -1242,7 +1057,7 @@ vfs_dup2(int oldfd, int newfd) int errno; struct v_fd *oldfd_s, *newfd_s; - if ((errno = __vfs_getfd(oldfd, &oldfd_s))) { + if ((errno = vfs_getfd(oldfd, &oldfd_s))) { goto done; } @@ -1274,7 +1089,7 @@ __DEFINE_LXSYSCALL1(int, dup, int, oldfd) { int errno, newfd; struct v_fd *oldfd_s, *newfd_s; - if ((errno = __vfs_getfd(oldfd, &oldfd_s))) { + if ((errno = vfs_getfd(oldfd, &oldfd_s))) { goto done; } @@ -1366,7 +1181,7 @@ __DEFINE_LXSYSCALL1(int, fchdir, int, fd) struct v_fd* fd_s; int errno = 0; - if ((errno = __vfs_getfd(fd, &fd_s))) { + if ((errno = vfs_getfd(fd, &fd_s))) { goto done; } @@ -1388,7 +1203,7 @@ __DEFINE_LXSYSCALL2(char*, getcwd, char*, buf, size_t, size) size_t len = 0; if (!__current->cwd) { - *buf = PATH_DELIM; + *buf = VFS_PATH_DELIM; len = 1; } else { len = vfs_get_path(__current->cwd, buf, size, 0); diff --git a/lunaix-os/kernel/fs/xattr.c b/lunaix-os/kernel/fs/xattr.c new file mode 100644 index 0000000..94f85b7 --- /dev/null +++ b/lunaix-os/kernel/fs/xattr.c @@ -0,0 +1,257 @@ +#include +#include +#include +#include + +struct v_xattr_entry* +xattr_new(struct hstr* name) +{ + struct v_xattr_entry* entry = valloc(sizeof(*entry)); + if (!entry) { + return NULL; + } + *entry = + (struct v_xattr_entry){ .name = HHSTR(valloc(VFS_NAME_MAXLEN), 0, 0) }; + + hstrcpy(&entry->name, name); + return entry; +} + +void +xattr_free(struct v_xattr_entry* entry) +{ + vfree(entry->name.value); + vfree(entry); +} + +struct v_xattr_entry* +xattr_getcache(struct v_inode* inode, struct hstr* name) +{ + struct v_xattr_entry *pos, *n; + llist_for_each(pos, n, &inode->xattrs, entries) + { + if (HSTR_EQ(&pos->name, name)) { + return pos; + } + } + + return NULL; +} + +void +xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr) +{ + llist_append(&inode->xattrs, &xattr->entries); +} + +void +xattr_delcache(struct v_inode* inode, struct v_xattr_entry* xattr) +{ + llist_delete(&xattr->entries); +} + +int +__vfs_getxattr(struct v_inode* inode, + struct v_xattr_entry** xentry, + const char* name) +{ + if (!inode->ops->getxattr) { + return ENOTSUP; + } + + int errno = 0; + size_t len = strlen(name); + + if (len > VFS_NAME_MAXLEN) { + return ERANGE; + } + + struct hstr hname = HSTR(name, len); + + hstr_rehash(&hname, HSTR_FULL_HASH); + + struct v_xattr_entry* entry = xattr_getcache(inode, &hname); + if (!entry) { + if (!(entry = xattr_new(&hname))) { + return ENOMEM; + } + } + + if (!(errno = inode->ops->getxattr(inode, entry))) { + *xentry = entry; + xattr_addcache(inode, entry); + } else { + xattr_free(entry); + } + return errno; +} + +int +__vfs_setxattr(struct v_inode* inode, + const char* name, + const void* data, + size_t len) +{ + if (!inode->ops->setxattr || !inode->ops->delxattr) { + return ENOTSUP; + } + + int errno = 0; + size_t slen = strlen(name); + + if (slen > VFS_NAME_MAXLEN) { + return ERANGE; + } + + struct hstr hname = HSTR(name, slen); + + hstr_rehash(&hname, HSTR_FULL_HASH); + + struct v_xattr_entry* entry = xattr_getcache(inode, &hname); + if (!entry) { + if (!(entry = xattr_new(&hname))) { + return ENOMEM; + } + } else { + xattr_delcache(inode, entry); + } + + if ((errno = inode->ops->delxattr(inode, entry))) { + xattr_free(entry); + goto done; + } + + entry->value = data; + entry->len = len; + + if ((errno = inode->ops->setxattr(inode, entry))) { + xattr_free(entry); + goto done; + } + + xattr_addcache(inode, entry); +done: + return errno; +} + +__DEFINE_LXSYSCALL4(int, + getxattr, + const char*, + path, + const char*, + name, + void*, + value, + size_t, + len) +{ + struct v_dnode* dnode; + struct v_xattr_entry* xattr; + int errno = 0; + + if ((errno = vfs_walk_proc(path, &dnode, NULL, 0))) { + goto done; + } + + if ((errno = __vfs_getxattr(dnode->inode, &xattr, name))) { + goto done; + } + + if (len < xattr->len) { + errno = ERANGE; + goto done; + } + + memcpy(value, xattr->value, len); + +done: + return DO_STATUS(errno); +} + +__DEFINE_LXSYSCALL4(int, + setxattr, + const char*, + path, + const char*, + name, + void*, + value, + size_t, + len) +{ + struct v_dnode* dnode; + struct v_xattr_entry* xattr; + int errno = 0; + + if ((errno = vfs_walk_proc(path, &dnode, NULL, 0))) { + goto done; + } + + if ((errno = __vfs_setxattr(dnode->inode, name, value, len))) { + goto done; + } + +done: + return DO_STATUS(errno); +} + +__DEFINE_LXSYSCALL4(int, + fgetxattr, + int, + fd, + const char*, + name, + void*, + value, + size_t, + len) +{ + struct v_fd* fd_s; + struct v_xattr_entry* xattr; + int errno = 0; + + if ((errno = vfs_getfd(fd, &fd_s))) { + goto done; + } + + if ((errno = __vfs_getxattr(fd_s->file->inode, &xattr, name))) { + goto done; + } + + if (len < xattr->len) { + errno = ERANGE; + goto done; + } + + memcpy(value, xattr->value, len); + +done: + return DO_STATUS(errno); +} + +__DEFINE_LXSYSCALL4(int, + fsetxattr, + int, + fd, + const char*, + name, + void*, + value, + size_t, + len) +{ + struct v_fd* fd_s; + struct v_xattr_entry* xattr; + int errno = 0; + + if ((errno = vfs_getfd(fd, &fd_s))) { + goto done; + } + + if ((errno = __vfs_setxattr(fd_s->file->inode, name, value, len))) { + goto done; + } + +done: + return DO_STATUS(errno); +} \ No newline at end of file diff --git a/lunaix-os/libs/hash.c b/lunaix-os/libs/hash.c index 277efb3..dc1b3cc 100644 --- a/lunaix-os/libs/hash.c +++ b/lunaix-os/libs/hash.c @@ -9,7 +9,7 @@ * @return unsigned int */ uint32_t -strhash_32(char* str, uint32_t truncate_to) +strhash_32(const char* str, uint32_t truncate_to) { if (!str) return 0; -- 2.27.0