feat: taskfs for export process to filesystem
authorMinep <zelong56@gmail.com>
Mon, 29 Aug 2022 12:53:49 +0000 (13:53 +0100)
committerMinep <zelong56@gmail.com>
Mon, 29 Aug 2022 12:53:49 +0000 (13:53 +0100)
chore: refactor, fixes and cleanup

24 files changed:
lunaix-os/includes/lunaix/common.h
lunaix-os/includes/lunaix/dirent.h
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/fs/taskfs.h [new file with mode: 0644]
lunaix-os/includes/lunaix/fs/twifs.h
lunaix-os/includes/lunaix/fs/twimap.h [new file with mode: 0644]
lunaix-os/includes/lunaix/mm/page.h
lunaix-os/includes/lunaix/process.h
lunaix-os/includes/lunaix/sched.h
lunaix-os/kernel/demos/simple_sh.c
lunaix-os/kernel/device/devfs.c
lunaix-os/kernel/fs/fs_setup.c
lunaix-os/kernel/fs/mount.c
lunaix-os/kernel/fs/ramfs/ramfs.c
lunaix-os/kernel/fs/twifs/twifs.c
lunaix-os/kernel/fs/twimap.c [moved from lunaix-os/kernel/fs/twifs/twimap.c with 74% similarity]
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/k_init.c
lunaix-os/kernel/process/process.c [moved from lunaix-os/kernel/process.c with 100% similarity]
lunaix-os/kernel/process/sched.c [moved from lunaix-os/kernel/sched.c with 98% similarity]
lunaix-os/kernel/process/signal.c [moved from lunaix-os/kernel/signal.c with 100% similarity]
lunaix-os/kernel/process/task_attr.c [new file with mode: 0644]
lunaix-os/kernel/process/taskfs.c [new file with mode: 0644]
lunaix-os/libs/klibc/stdio/ksprintf.c

index 8873a73ba35b12f90959381cfa0ea5f5be69862e..f5a24a7bdab924bd9d286998f7b8217814051823 100644 (file)
@@ -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
index faa56a6ceee5cae0abe21dbf1b90a8a39def4cda..160365d6c3db97bbee27dbf90f005ca0086a81d7 100644 (file)
@@ -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;
index b497954abce0373140bc97cf4f800dfab89f8561..94c6e6bbd918d112bb3d1761a810e2d2ceb8b3e9 100644 (file)
@@ -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 (file)
index 0000000..0afc048
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __LUNAIX_TASKFS_H
+#define __LUNAIX_TASKFS_H
+
+#include <lunaix/fs.h>
+#include <lunaix/fs/twimap.h>
+
+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 */
index b194066afe07c791902f1e71e8365376737ad761..a8117ef7cddb61ff4c67b59598c45365ef128691 100644 (file)
@@ -2,6 +2,7 @@
 #define __LUNAIX_TWIFS_H
 
 #include <lunaix/fs.h>
+#include <lunaix/fs/twimap.h>
 #include <lunaix/spike.h>
 
 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 (file)
index 0000000..7adbc53
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef __LUNAIX_TWIMAP_H
+#define __LUNAIX_TWIMAP_H
+
+#include <lunaix/types.h>
+
+#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 */
index ad7354245d36a172e766665e96e4b938eb38939b..9458277eac1db33a61b8bfc6fd31f929bb7d2724 100644 (file)
@@ -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)
index 9686ee074de99ec4fb88c1e4e42703d627d7c907..c7b925ef59651532d3da80ab6a6f0fbc68fe0f28 100644 (file)
@@ -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;
index c1ffddd110a72f6f756555bf0621dee0a6fe405d..f31eab52daa9ce7ddc34b2d220812b64c9a27985 100644 (file)
@@ -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;
index 195117af3c211029439b2f6749858130edb5ca6e..693bb75b63bec8ccfeae625834f2999fd4c7b061 100644 (file)
@@ -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");
index af2a5f7f41de687e7a1f6fd4a2a9ac126af8b385..012f9190f7b1b54433eba624adf4fca4987dd07a 100644 (file)
@@ -1,4 +1,5 @@
 #include <lunaix/device.h>
+#include <lunaix/dirent.h>
 #include <lunaix/fs.h>
 #include <lunaix/fs/devfs.h>
 #include <lunaix/spike.h>
@@ -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;
 }
 
index 6de3f381d7aec49b10c80da02c03efd36c821c65..5b3a35d040ac9f3a7bea4f92c8f878fd98e98132 100644 (file)
@@ -1,6 +1,7 @@
 #include <lunaix/fs.h>
 #include <lunaix/fs/devfs.h>
 #include <lunaix/fs/ramfs.h>
+#include <lunaix/fs/taskfs.h>
 #include <lunaix/fs/twifs.h>
 
 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
index 486d6954152126b3ddad1e24fdd5a08c3bb00be7..38258ee68d831a6a52114b4a3d42ae2819406545 100644 (file)
@@ -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;
 }
index 11ec8463aa4f8db47097bc8eb3e936e6d45aa7c4..a1018daa7fcd22dd04503d5a39b490d31dd7fdb7 100644 (file)
@@ -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;
         }
     }
index 4952e9df62516f447bae49721c4293f5805db4eb..437ab0ba541560d81b1d12aeb495818e499ed995 100644 (file)
@@ -13,6 +13,7 @@
 #include <lunaix/clock.h>
 #include <lunaix/fs.h>
 #include <lunaix/fs/twifs.h>
+#include <lunaix/fs/twimap.h>
 #include <lunaix/mm/cake.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/spike.h>
@@ -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,
similarity index 74%
rename from lunaix-os/kernel/fs/twifs/twimap.c
rename to lunaix-os/kernel/fs/twimap.c
index 24460140d98f459dae4186dd094f83a41c663b4c..e32ec333c3b7d1965b2d75dc95f303d1ff256077 100644 (file)
@@ -1,5 +1,7 @@
-#include <lunaix/fs/twifs.h>
+#include <lunaix/fs.h>
+#include <lunaix/fs/twimap.h>
 #include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
 
 #include <klibc/stdio.h>
 #include <klibc/string.h>
@@ -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
index eaf35e03087e963dea8c5509dc543f8c43b40798..3592dc8e2fd9a43e43637b131d0929fca1fb4782 100644 (file)
@@ -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;
index a82df947d16a40f6164508b60fb90f1ff75c0e52..fc6c51cc221c129bac5ae880ab4f3dc8c9638180 100644 (file)
@@ -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();
 
similarity index 98%
rename from lunaix-os/kernel/sched.c
rename to lunaix-os/kernel/process/sched.c
index 9061e8032c156bcdd61d7c5b30df2b73e66e4dba..f58710ee347387eee1629214b8b3c270c25b1a62 100644 (file)
@@ -17,9 +17,6 @@
 #include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
 
-#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/process/task_attr.c b/lunaix-os/kernel/process/task_attr.c
new file mode 100644 (file)
index 0000000..f90ed35
--- /dev/null
@@ -0,0 +1,100 @@
+#include <lunaix/fs/taskfs.h>
+
+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 (file)
index 0000000..1e4ad2d
--- /dev/null
@@ -0,0 +1,203 @@
+#include <lunaix/dirent.h>
+#include <lunaix/fs/taskfs.h>
+#include <lunaix/fs/twimap.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/process.h>
+#include <lunaix/sched.h>
+
+#include <klibc/stdio.h>
+#include <klibc/string.h>
+
+#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
index 38b90319d82aa33e737f0060b4a2c70f6374f33a..2497e107b7821eba1ebe3eb7f09d49a2d3ce8b10 100644 (file)
@@ -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;