From 61a1daa59589212608039e2734009870818bacd3 Mon Sep 17 00:00:00 2001 From: Minep Date: Mon, 29 Aug 2022 13:53:49 +0100 Subject: [PATCH] feat: taskfs for export process to filesystem chore: refactor, fixes and cleanup --- lunaix-os/includes/lunaix/common.h | 3 - lunaix-os/includes/lunaix/dirent.h | 5 + lunaix-os/includes/lunaix/fs.h | 15 ++ lunaix-os/includes/lunaix/fs/taskfs.h | 25 +++ lunaix-os/includes/lunaix/fs/twifs.h | 24 +-- lunaix-os/includes/lunaix/fs/twimap.h | 37 +++++ lunaix-os/includes/lunaix/mm/page.h | 2 +- lunaix-os/includes/lunaix/process.h | 1 + lunaix-os/includes/lunaix/sched.h | 3 + lunaix-os/kernel/demos/simple_sh.c | 12 +- lunaix-os/kernel/device/devfs.c | 15 +- lunaix-os/kernel/fs/fs_setup.c | 2 + lunaix-os/kernel/fs/mount.c | 5 +- lunaix-os/kernel/fs/ramfs/ramfs.c | 6 +- lunaix-os/kernel/fs/twifs/twifs.c | 27 ++- lunaix-os/kernel/fs/{twifs => }/twimap.c | 51 +++--- lunaix-os/kernel/fs/vfs.c | 17 +- lunaix-os/kernel/k_init.c | 1 + lunaix-os/kernel/{ => process}/process.c | 0 lunaix-os/kernel/{ => process}/sched.c | 5 +- lunaix-os/kernel/{ => process}/signal.c | 0 lunaix-os/kernel/process/task_attr.c | 100 +++++++++++ lunaix-os/kernel/process/taskfs.c | 203 +++++++++++++++++++++++ lunaix-os/libs/klibc/stdio/ksprintf.c | 3 + 24 files changed, 497 insertions(+), 65 deletions(-) create mode 100644 lunaix-os/includes/lunaix/fs/taskfs.h create mode 100644 lunaix-os/includes/lunaix/fs/twimap.h rename lunaix-os/kernel/fs/{twifs => }/twimap.c (74%) rename lunaix-os/kernel/{ => process}/process.c (100%) rename lunaix-os/kernel/{ => process}/sched.c (98%) rename lunaix-os/kernel/{ => process}/signal.c (100%) create mode 100644 lunaix-os/kernel/process/task_attr.c create mode 100644 lunaix-os/kernel/process/taskfs.c diff --git a/lunaix-os/includes/lunaix/common.h b/lunaix-os/includes/lunaix/common.h index 8873a73..f5a24a7 100644 --- a/lunaix-os/includes/lunaix/common.h +++ b/lunaix-os/includes/lunaix/common.h @@ -14,9 +14,6 @@ // #define KHEAP_START (KERNEL_MM_BASE + KCODE_MAX_SIZE) // #define KHEAP_SIZE_MB 256 -#define PROC_TABLE_SIZE_MB 4 -#define PROC_START (KERNEL_MM_BASE + KCODE_MAX_SIZE) - #define VGA_FRAMEBUFFER 0xB8000 #define KCODE_SEG 0x08 diff --git a/lunaix-os/includes/lunaix/dirent.h b/lunaix-os/includes/lunaix/dirent.h index faa56a6..160365d 100644 --- a/lunaix-os/includes/lunaix/dirent.h +++ b/lunaix-os/includes/lunaix/dirent.h @@ -3,6 +3,11 @@ #define DIRENT_NAME_MAX_LEN 256 +#define DT_FILE 0x0 +#define DT_DIR 0x1 +#define DT_SYMLINK 0x2 +#define DT_PIPE 0x2 + struct dirent { unsigned int d_type; diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index b497954..94c6e6b 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -172,6 +172,18 @@ struct v_fd int flags; }; +// FIXME how do we invalidate corresponding v_dnodes given the v_inode? +/* + Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow + info of every process being accessible via file system. Each process's + creation will result a creation of a directory under the root of task fs + with it's pid as name. But that dir must delete when process is killed, and + such deletion does not mediated by vfs itself, so there is a need of cache + syncing. + And this is also the case of all ramfs where argumentation to file tree is + performed by third party. +*/ + struct v_inode { inode_t id; @@ -357,6 +369,9 @@ vfs_dup_fd(struct v_fd* old, struct v_fd** new); int vfs_getfd(int fd, struct v_fd** fd_s); +int +vfs_get_dtype(int itype); + void pcache_init(struct pcache* pcache); diff --git a/lunaix-os/includes/lunaix/fs/taskfs.h b/lunaix-os/includes/lunaix/fs/taskfs.h new file mode 100644 index 0000000..0afc048 --- /dev/null +++ b/lunaix-os/includes/lunaix/fs/taskfs.h @@ -0,0 +1,25 @@ +#ifndef __LUNAIX_TASKFS_H +#define __LUNAIX_TASKFS_H + +#include +#include + +struct task_attribute +{ + struct llist_header siblings; + struct hlist_node attrs; + struct hstr key; + struct twimap* map_file; + char key_val[32]; +}; + +void +taskfs_init(); + +void +taskfs_export_attr(const char* key, struct twimap* attr_map_file); + +struct task_attribute* +taskfs_get_attr(struct hstr* key); + +#endif /* __LUNAIX_TASKFS_H */ diff --git a/lunaix-os/includes/lunaix/fs/twifs.h b/lunaix-os/includes/lunaix/fs/twifs.h index b194066..a8117ef 100644 --- a/lunaix-os/includes/lunaix/fs/twifs.h +++ b/lunaix-os/includes/lunaix/fs/twifs.h @@ -2,6 +2,7 @@ #define __LUNAIX_TWIFS_H #include +#include #include struct twifs_node @@ -26,17 +27,6 @@ struct twifs_node } ops; }; -struct twimap -{ - void* index; - void* buffer; - void* data; - size_t size_acc; - void (*read)(struct twimap* mapping); - int (*go_next)(struct twimap* mapping); - void (*reset)(struct twimap* mapping); -}; - #define twinode_getdata(inode, type) \ ({ \ struct twifs_node* twinode = (struct twifs_node*)(inode)->data; \ @@ -59,19 +49,7 @@ twifs_dir_node(struct twifs_node* parent, const char* fmt, ...); int twifs_rm_node(struct twifs_node* node); -#define twimap_index(twimap, type) ((type)((twimap)->index)) -#define twimap_data(twimap, type) ((type)((twimap)->data)) - struct twimap* twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...); -void -twimap_printf(struct twimap* mapping, const char* fmt, ...); - -int -twimap_memcpy(struct twimap* mapping, const void* src, const size_t len); - -int -twimap_memappend(struct twimap* mapping, const void* src, const size_t len); - #endif /* __LUNAIX_TWIFS_H */ diff --git a/lunaix-os/includes/lunaix/fs/twimap.h b/lunaix-os/includes/lunaix/fs/twimap.h new file mode 100644 index 0000000..7adbc53 --- /dev/null +++ b/lunaix-os/includes/lunaix/fs/twimap.h @@ -0,0 +1,37 @@ +#ifndef __LUNAIX_TWIMAP_H +#define __LUNAIX_TWIMAP_H + +#include + +#define twimap_index(twimap, type) ((type)((twimap)->index)) +#define twimap_data(twimap, type) ((type)((twimap)->data)) + +extern struct v_file_ops twimap_file_ops; + +struct twimap +{ + void* index; + void* buffer; + void* data; + size_t size_acc; + void (*read)(struct twimap* mapping); + int (*go_next)(struct twimap* mapping); + void (*reset)(struct twimap* mapping); +}; + +int +twimap_read(struct twimap* map, void* buffer, size_t len, size_t fpos); + +void +twimap_printf(struct twimap* mapping, const char* fmt, ...); + +int +twimap_memcpy(struct twimap* mapping, const void* src, const size_t len); + +int +twimap_memappend(struct twimap* mapping, const void* src, const size_t len); + +struct twimap* +twimap_create(void* data); + +#endif /* __LUNAIX_TWIMAP_H */ diff --git a/lunaix-os/includes/lunaix/mm/page.h b/lunaix-os/includes/lunaix/mm/page.h index ad73542..9458277 100644 --- a/lunaix-os/includes/lunaix/mm/page.h +++ b/lunaix-os/includes/lunaix/mm/page.h @@ -99,7 +99,7 @@ extern void __pg_mount_point; /* 四个页挂载点,两个页目录挂载点: 用于临时创建&编辑页表 */ #define PG_MOUNT_RANGE(l1_index) (701 <= l1_index && l1_index <= 703) -#define PD_MOUNT_1 (PROC_START + MEM_4MB) +#define PD_MOUNT_1 (KERNEL_MM_BASE + MEM_4MB) #define PG_MOUNT_BASE (PD_MOUNT_1 + MEM_4MB) #define PG_MOUNT_1 (PG_MOUNT_BASE) #define PG_MOUNT_2 (PG_MOUNT_BASE + 0x1000) diff --git a/lunaix-os/includes/lunaix/process.h b/lunaix-os/includes/lunaix/process.h index 9686ee0..c7b925e 100644 --- a/lunaix-os/includes/lunaix/process.h +++ b/lunaix-os/includes/lunaix/process.h @@ -58,6 +58,7 @@ struct proc_info /* ---- critical section end ---- */ + struct llist_header tasks; struct llist_header siblings; struct llist_header children; struct llist_header grp_member; diff --git a/lunaix-os/includes/lunaix/sched.h b/lunaix-os/includes/lunaix/sched.h index c1ffddd..f31eab5 100644 --- a/lunaix-os/includes/lunaix/sched.h +++ b/lunaix-os/includes/lunaix/sched.h @@ -3,6 +3,9 @@ #define SCHED_TIME_SLICE 300 +#define PROC_TABLE_SIZE 8192 +#define MAX_PROCESS (PROC_TABLE_SIZE / sizeof(uintptr_t)) + struct scheduler { struct proc_info** _procs; diff --git a/lunaix-os/kernel/demos/simple_sh.c b/lunaix-os/kernel/demos/simple_sh.c index 195117a..693bb75 100644 --- a/lunaix-os/kernel/demos/simple_sh.c +++ b/lunaix-os/kernel/demos/simple_sh.c @@ -98,7 +98,11 @@ sh_main() struct dirent ent = { .d_offset = 0 }; int status; while ((status = readdir(fd, &ent)) == 1) { - printf(" %s\n", ent.d_name); + if (ent.d_type == DT_DIR) { + printf(" \033[3m%s\033[39;49m\n", ent.d_name); + } else { + printf(" %s\n", ent.d_name); + } } if (status < 0) @@ -112,13 +116,11 @@ sh_main() sh_printerr(); } else { int sz; - while ((sz = read(fd, cat_buf, 1024)) == 1024) { - write(stdout, cat_buf, 1024); + while ((sz = read(fd, cat_buf, 1024)) > 0) { + write(stdout, cat_buf, sz); } if (sz < 0) { sh_printerr(); - } else { - write(stdout, cat_buf, sz); } close(fd); printf("\n"); diff --git a/lunaix-os/kernel/device/devfs.c b/lunaix-os/kernel/device/devfs.c index af2a5f7..012f919 100644 --- a/lunaix-os/kernel/device/devfs.c +++ b/lunaix-os/kernel/device/devfs.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -49,6 +50,18 @@ devfs_get_itype(struct device* dev) return itype; } +int +devfs_get_dtype(struct device* dev) +{ + switch (dev->dev_type & DEV_MSKIF) { + case DEV_IFCAT: + return DT_DIR; + + default: + return DT_FILE; + } +} + int devfs_mknod(struct v_dnode* dnode, struct device* dev) { @@ -91,7 +104,7 @@ devfs_readdir(struct v_file* file, struct dir_context* dctx) return 0; } dctx->read_complete_callback( - dctx, dev->name.value, dev->name.len, devfs_get_itype(dev)); + dctx, dev->name.value, dev->name.len, devfs_get_dtype(dev)); return 1; } diff --git a/lunaix-os/kernel/fs/fs_setup.c b/lunaix-os/kernel/fs/fs_setup.c index 6de3f38..5b3a35d 100644 --- a/lunaix-os/kernel/fs/fs_setup.c +++ b/lunaix-os/kernel/fs/fs_setup.c @@ -1,6 +1,7 @@ #include #include #include +#include #include void @@ -9,6 +10,7 @@ fsm_register_all() ramfs_init(); twifs_init(); devfs_init(); + taskfs_init(); // ... more fs implementation } \ No newline at end of file diff --git a/lunaix-os/kernel/fs/mount.c b/lunaix-os/kernel/fs/mount.c index 486d695..38258ee 100644 --- a/lunaix-os/kernel/fs/mount.c +++ b/lunaix-os/kernel/fs/mount.c @@ -145,12 +145,12 @@ vfs_mount_at(const char* fs_name, } struct v_mount* parent_mnt = mnt_point->mnt; - struct v_superblock* sb = vfs_sb_alloc(); + struct v_superblock *sb = vfs_sb_alloc(), *old_sb = mnt_point->super_block; sb->dev = device; + mnt_point->super_block = sb; int errno = 0; if (!(errno = fs->mount(sb, mnt_point))) { - mnt_point->super_block = sb; sb->fs = fs; sb->root = mnt_point; @@ -167,6 +167,7 @@ vfs_mount_at(const char* fs_name, return errno; cleanup: + mnt_point->super_block = old_sb; vfs_sb_free(sb); return errno; } diff --git a/lunaix-os/kernel/fs/ramfs/ramfs.c b/lunaix-os/kernel/fs/ramfs/ramfs.c index 11ec846..a1018da 100644 --- a/lunaix-os/kernel/fs/ramfs/ramfs.c +++ b/lunaix-os/kernel/fs/ramfs/ramfs.c @@ -52,8 +52,10 @@ ramfs_readdir(struct v_file* file, struct dir_context* dctx) llist_for_each(pos, n, &file->dnode->children, siblings) { if (i++ >= dctx->index) { - dctx->read_complete_callback( - dctx, pos->name.value, pos->name.len, 0); + dctx->read_complete_callback(dctx, + pos->name.value, + pos->name.len, + vfs_get_dtype(pos->inode->itype)); return 1; } } diff --git a/lunaix-os/kernel/fs/twifs/twifs.c b/lunaix-os/kernel/fs/twifs/twifs.c index 4952e9d..437ab0b 100644 --- a/lunaix-os/kernel/fs/twifs/twifs.c +++ b/lunaix-os/kernel/fs/twifs/twifs.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -159,7 +160,7 @@ __twifs_iterate_dir(struct v_file* file, struct dir_context* dctx) if (counter++ >= dctx->index) { dctx->index = counter; dctx->read_complete_callback( - dctx, pos->name.value, pos->name.len, pos->itype); + dctx, pos->name.value, pos->name.len, vfs_get_dtype(pos->itype)); return 1; } } @@ -242,6 +243,30 @@ twifs_init() fs_root = twifs_dir_node(NULL, NULL, 0, 0); } +int +__twifs_twimap_file_read(struct v_inode* inode, + void* buf, + size_t len, + size_t fpos) +{ + struct twimap* map = twinode_getdata(inode, struct twimap*); + return twimap_read(map, buf, len, fpos); +} + +struct twimap* +twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + + struct twimap* map = twimap_create(data); + struct twifs_node* node = twifs_file_node_vargs(parent, fmt, args); + node->ops.read = __twifs_twimap_file_read; + node->data = map; + + return map; +} + const struct v_file_ops twifs_file_ops = { .close = default_file_close, .read = __twifs_fread, .write = __twifs_fwrite, diff --git a/lunaix-os/kernel/fs/twifs/twimap.c b/lunaix-os/kernel/fs/twimap.c similarity index 74% rename from lunaix-os/kernel/fs/twifs/twimap.c rename to lunaix-os/kernel/fs/twimap.c index 2446014..e32ec33 100644 --- a/lunaix-os/kernel/fs/twifs/twimap.c +++ b/lunaix-os/kernel/fs/twimap.c @@ -1,5 +1,7 @@ -#include +#include +#include #include +#include #include #include @@ -19,9 +21,15 @@ __twimap_default_gonext(struct twimap* map) } int -__twimap_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos) +__twimap_file_read(struct v_inode* inode, void* buf, size_t len, size_t fpos) +{ + struct twimap* map = (struct twimap*)(inode->data); + return twimap_read(map, buf, len, fpos); +} + +int +twimap_read(struct twimap* map, void* buffer, size_t len, size_t fpos) { - struct twimap* map = twinode_getdata(inode, struct twimap*); map->buffer = valloc(TWIMAP_BUFFER_SIZE); map->reset(map); @@ -58,24 +66,6 @@ __twimap_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos) return acc_size; } -struct twimap* -twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - - struct twimap* map = vzalloc(sizeof(struct twimap)); - struct twifs_node* node = twifs_file_node_vargs(parent, fmt, args); - node->ops.read = __twimap_read; - node->data = map; - - map->reset = __twimap_default_reset; - map->go_next = __twimap_default_gonext; - map->data = data; - - return map; -} - void twimap_printf(struct twimap* mapping, const char* fmt, ...) { @@ -107,4 +97,21 @@ twimap_memappend(struct twimap* mapping, const void* src, const size_t len) mapping->size_acc += cpy_len; return cpy_len; -} \ No newline at end of file +} + +struct twimap* +twimap_create(void* data) +{ + struct twimap* map = vzalloc(sizeof(struct twimap)); + map->reset = __twimap_default_reset; + map->go_next = __twimap_default_gonext; + map->data = data; + + return map; +} + +struct v_file_ops twimap_file_ops = { .close = default_file_close, + .read = __twimap_file_read, + .readdir = default_file_readdir, + .seek = default_file_seek, + .write = default_file_write }; \ No newline at end of file diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index eaf35e0..3592dc8 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -609,9 +609,9 @@ __DEFINE_LXSYSCALL2(int, readdir, int, fd, struct dirent*, dent) __vfs_readdir_callback }; errno = 1; if (dent->d_offset == 0) { - __vfs_readdir_callback(&dctx, vfs_dot.value, vfs_dot.len, 0); + __vfs_readdir_callback(&dctx, vfs_dot.value, vfs_dot.len, DT_DIR); } else if (dent->d_offset == 1) { - __vfs_readdir_callback(&dctx, vfs_ddot.value, vfs_ddot.len, 0); + __vfs_readdir_callback(&dctx, vfs_ddot.value, vfs_ddot.len, DT_DIR); } else { dctx.index -= 2; if ((errno = fd_s->file->ops->readdir(fd_s->file, &dctx)) != 1) { @@ -793,6 +793,19 @@ vfs_readlink(struct v_dnode* dnode, char* buf, size_t size) return 0; } +int +vfs_get_dtype(int itype) +{ + switch (itype) { + case VFS_IFDIR: + return DT_DIR; + case VFS_IFSYMLINK: + return DT_SYMLINK; + default: + return DT_PIPE; + } +} + __DEFINE_LXSYSCALL3(int, realpathat, int, fd, char*, buf, size_t, size) { int errno; diff --git a/lunaix-os/kernel/k_init.c b/lunaix-os/kernel/k_init.c index a82df94..fc6c51c 100644 --- a/lunaix-os/kernel/k_init.c +++ b/lunaix-os/kernel/k_init.c @@ -84,6 +84,7 @@ _kernel_init() vfs_mount("/dev", "devfs", NULL, 0); vfs_mount("/sys", "twifs", NULL, MNT_RO); + vfs_mount("/task", "taskfs", NULL, MNT_RO); lxconsole_init(); diff --git a/lunaix-os/kernel/process.c b/lunaix-os/kernel/process/process.c similarity index 100% rename from lunaix-os/kernel/process.c rename to lunaix-os/kernel/process/process.c diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/process/sched.c similarity index 98% rename from lunaix-os/kernel/sched.c rename to lunaix-os/kernel/process/sched.c index 9061e80..f58710e 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/process/sched.c @@ -17,9 +17,6 @@ #include #include -#define PROC_TABLE_SIZE 8192 -#define MAX_PROCESS (PROC_TABLE_SIZE / sizeof(uintptr_t)) - volatile struct proc_info* __current; struct proc_info dummy; @@ -286,6 +283,7 @@ alloc_process() proc->fdtable = vzalloc(sizeof(struct v_fdtable)); llist_init_head(&proc->mm.regions.head); + llist_init_head(&proc->tasks); llist_init_head(&proc->children); llist_init_head(&proc->grp_member); llist_init_head(&proc->sleep.sleepers); @@ -312,6 +310,7 @@ commit_process(struct proc_info* process) } llist_append(&process->parent->children, &process->siblings); + llist_append(&sched_ctx._procs[0]->tasks, &process->tasks); process->state = PS_READY; } diff --git a/lunaix-os/kernel/signal.c b/lunaix-os/kernel/process/signal.c similarity index 100% rename from lunaix-os/kernel/signal.c rename to lunaix-os/kernel/process/signal.c diff --git a/lunaix-os/kernel/process/task_attr.c b/lunaix-os/kernel/process/task_attr.c new file mode 100644 index 0000000..f90ed35 --- /dev/null +++ b/lunaix-os/kernel/process/task_attr.c @@ -0,0 +1,100 @@ +#include + +void +__read_pending_sig(struct twimap* map) +{ + struct proc_info* proc = twimap_data(map, struct proc_info*); + twimap_printf(map, "%bb", proc->sig_pending); +} + +void +__read_masked_sig(struct twimap* map) +{ + struct proc_info* proc = twimap_data(map, struct proc_info*); + twimap_printf(map, "%bb", proc->sig_mask); +} + +void +__read_parent(struct twimap* map) +{ + struct proc_info* proc = twimap_data(map, struct proc_info*); + twimap_printf(map, "%d", proc->parent->pid); +} + +void +__read_ctimestamp(struct twimap* map) +{ + struct proc_info* proc = twimap_data(map, struct proc_info*); + twimap_printf(map, "%d", proc->created); +} + +void +__read_pgid(struct twimap* map) +{ + struct proc_info* proc = twimap_data(map, struct proc_info*); + twimap_printf(map, "%d", proc->pgid); +} + +void +__read_children(struct twimap* map) +{ + struct proc_info* proc = twimap_index(map, struct proc_info*); + if (!proc) + return; + twimap_printf(map, "%d ", proc->pid); +} + +int +__next_children(struct twimap* map) +{ + struct proc_info* proc = twimap_index(map, struct proc_info*); + if (!proc) + return 0; + map->index = container_of(proc->siblings.next, struct proc_info, siblings); + if (map->index == proc) { + return 0; + } + return 1; +} + +void +__reset_children(struct twimap* map) +{ + struct proc_info* proc = twimap_data(map, struct proc_info*); + if (llist_empty(&proc->children)) { + map->index = 0; + return; + } + map->index = container_of(proc->children.next, struct proc_info, siblings); +} + +void +export_task_attr() +{ + struct twimap* map; + map = twimap_create(NULL); + map->read = __read_pending_sig; + taskfs_export_attr("sig_pending", map); + + map = twimap_create(NULL); + map->read = __read_masked_sig; + taskfs_export_attr("sig_masked", map); + + map = twimap_create(NULL); + map->read = __read_parent; + taskfs_export_attr("parent", map); + + map = twimap_create(NULL); + map->read = __read_ctimestamp; + taskfs_export_attr("created", map); + + map = twimap_create(NULL); + map->read = __read_pgid; + taskfs_export_attr("pgid", map); + + map = twimap_create(NULL); + map->read = __read_children; + map->go_next = __next_children; + map->reset = __reset_children; + taskfs_export_attr("children", map); +} \ No newline at end of file diff --git a/lunaix-os/kernel/process/taskfs.c b/lunaix-os/kernel/process/taskfs.c new file mode 100644 index 0000000..1e4ad2d --- /dev/null +++ b/lunaix-os/kernel/process/taskfs.c @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define COUNTER_MASK ((1 << 16) - 1) + +static struct hbucket* attr_export_table; +static DEFINE_LLIST(attributes); +static volatile int ino_cnt = 1; + +int +taskfs_next_counter() +{ + return (ino_cnt = ((ino_cnt + 1) & COUNTER_MASK) + 1); +} + +inode_t +taskfs_inode_id(pid_t pid, int sub_counter) +{ + return ((pid & (MAX_PROCESS - 1)) << 16) | (sub_counter & COUNTER_MASK); +} + +int +taskfs_mknod(struct v_dnode* dnode, pid_t pid, int sub_counter, int itype) +{ + inode_t ino = taskfs_inode_id(pid, sub_counter); + + struct v_superblock* vsb = dnode->super_block; + struct v_inode* inode = vfs_i_find(vsb, ino); + if (!inode) { + if (!(inode = vfs_i_alloc(vsb))) { + return ENOMEM; + } + inode->id = ino; + inode->itype = itype; + vfs_i_addhash(inode); + } + + vfs_assign_inode(dnode, inode); + return 0; +} + +int +taskfs_readdir(struct v_file* file, struct dir_context* dctx) +{ + struct v_inode* inode = file->inode; + pid_t pid = inode->id >> 16; + int counter = 0; + + if ((inode->id & COUNTER_MASK)) { + return ENOTDIR; + } + + if (pid) { + struct task_attribute *pos, *n; + llist_for_each(pos, n, &attributes, siblings) + { + if (counter == dctx->index) { + dctx->read_complete_callback( + dctx, pos->key_val, VFS_NAME_MAXLEN, DT_FILE); + return 1; + } + counter++; + } + return 0; + } + + char name[VFS_NAME_MAXLEN]; + struct proc_info *root = get_process(pid), *pos, *n; + llist_for_each(pos, n, &root->tasks, tasks) + { + if (counter == dctx->index) { + ksnprintf(name, VFS_NAME_MAXLEN, "%d", pos->pid); + dctx->read_complete_callback(dctx, name, VFS_NAME_MAXLEN, DT_DIR); + return 1; + } + counter++; + } + return 0; +} + +pid_t +taskfs_atop(const char* str) +{ + pid_t t = 0; + int i = 0; + char c; + while ((c = str[i++])) { + if ('0' > c || c > '9') { + return -1; + } + t = t * 10 + (c - '0'); + } + return t; +} + +int +taskfs_dirlookup(struct v_inode* this, struct v_dnode* dnode) +{ + pid_t pid = this->id >> 16; + struct proc_info* proc; + + if (pid) { + struct task_attribute* tattr = taskfs_get_attr(&dnode->name); + if (!tattr || !(proc = get_process(pid))) + return ENOENT; + + int errno = taskfs_mknod(dnode, pid, taskfs_next_counter(), VFS_IFFILE); + if (!errno) { + tattr->map_file->data = proc; + dnode->inode->data = tattr->map_file; + dnode->inode->default_fops = &twimap_file_ops; + } + return errno; + } + + pid = taskfs_atop(dnode->name.value); + + if (pid <= 0 || !(proc = get_process(pid))) { + return ENOENT; + } + + return taskfs_mknod(dnode, pid, 0, VFS_IFDIR); +} + +static struct v_file_ops taskfs_file_ops = { .close = default_file_close, + .read = default_file_read, + .write = default_file_write, + .readdir = taskfs_readdir, + .seek = default_file_seek }; +static struct v_inode_ops taskfs_inode_ops = { .dir_lookup = taskfs_dirlookup, + .open = default_inode_open, + .mkdir = default_inode_mkdir, + .rmdir = default_inode_rmdir, + .rename = default_inode_rename }; + +void +taskfs_init_inode(struct v_superblock* vsb, struct v_inode* inode) +{ + inode->default_fops = &taskfs_file_ops; + inode->ops = &taskfs_inode_ops; +} + +int +taskfs_mount(struct v_superblock* vsb, struct v_dnode* mount_point) +{ + vsb->ops.init_inode = taskfs_init_inode; + + return taskfs_mknod(mount_point, 0, 0, VFS_IFDIR); +} + +#define ATTR_TABLE_LEN 16 + +void +taskfs_export_attr(const char* key, struct twimap* attr_map_file) +{ + struct task_attribute* tattr = valloc(sizeof(*tattr)); + + tattr->map_file = attr_map_file; + tattr->key = HSTR(tattr->key_val, 0); + strncpy(tattr->key_val, key, 32); + hstr_rehash(&tattr->key, HSTR_FULL_HASH); + + struct hbucket* slot = &attr_export_table[tattr->key.hash % ATTR_TABLE_LEN]; + hlist_add(&slot->head, &tattr->attrs); + llist_append(&attributes, &tattr->siblings); +} + +struct task_attribute* +taskfs_get_attr(struct hstr* key) +{ + struct hbucket* slot = &attr_export_table[key->hash % ATTR_TABLE_LEN]; + struct task_attribute *pos, *n; + hashtable_bucket_foreach(slot, pos, n, attrs) + { + if (HSTR_EQ(&pos->key, key)) { + return pos; + } + } + return NULL; +} + +extern void +export_task_attr(); + +void +taskfs_init() +{ + struct filesystem* taskfs = fsm_new_fs("taskfs", 5); + taskfs->mount = taskfs_mount; + + fsm_register(taskfs); + + attr_export_table = vcalloc(ATTR_TABLE_LEN, sizeof(struct hbucket)); + + export_task_attr(); +} \ No newline at end of file diff --git a/lunaix-os/libs/klibc/stdio/ksprintf.c b/lunaix-os/libs/klibc/stdio/ksprintf.c index 38b9031..2497e10 100644 --- a/lunaix-os/libs/klibc/stdio/ksprintf.c +++ b/lunaix-os/libs/klibc/stdio/ksprintf.c @@ -102,6 +102,9 @@ __ksprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs) : va_arg(vargs, unsigned); flags |= FLAG_NUMERIC; break; + case 'b': + base = 2; + goto format_unsigned; case 'x': base = 16; goto format_unsigned; -- 2.27.0