1 #include <lunaix/fs/taskfs.h>
2 #include <lunaix/fs/twimap.h>
3 #include <lunaix/mm/valloc.h>
4 #include <lunaix/process.h>
5 #include <lunaix/sched.h>
7 #include <klibc/strfmt.h>
8 #include <klibc/string.h>
10 #include <usr/lunaix/dirent_defs.h>
12 #define COUNTER_MASK ((1 << 16) - 1)
14 static struct hbucket* attr_export_table;
15 static DEFINE_LLIST(attributes);
16 static volatile int ino_cnt = 1;
21 return (ino_cnt = ((ino_cnt + 1) & COUNTER_MASK) + 1);
25 taskfs_inode_id(pid_t pid, int sub_counter)
27 return ((pid & (MAX_PROCESS - 1)) << 16) | (sub_counter & COUNTER_MASK);
31 taskfs_mknod(struct v_dnode* dnode, pid_t pid, int sub_counter, int itype)
33 inode_t ino = taskfs_inode_id(pid, sub_counter);
35 struct v_superblock* vsb = dnode->super_block;
36 struct v_inode* inode = vfs_i_find(vsb, ino);
38 if (!(inode = vfs_i_alloc(vsb))) {
46 vfs_assign_inode(dnode, inode);
51 taskfs_readdir(struct v_file* file, struct dir_context* dctx)
53 struct v_inode* inode = file->inode;
54 pid_t pid = inode->id >> 16;
57 if ((inode->id & COUNTER_MASK)) {
62 struct task_attribute *pos, *n;
63 llist_for_each(pos, n, &attributes, siblings)
65 if (counter == dctx->index) {
66 dctx->read_complete_callback(
67 dctx, pos->key_val, VFS_NAME_MAXLEN, DT_FILE);
75 char name[VFS_NAME_MAXLEN];
76 struct proc_info *root = get_process(pid), *pos, *n;
77 llist_for_each(pos, n, &root->tasks, tasks)
79 if (counter == dctx->index) {
80 ksnprintf(name, VFS_NAME_MAXLEN, "%d", pos->pid);
81 dctx->read_complete_callback(dctx, name, VFS_NAME_MAXLEN, DT_DIR);
91 taskfs_atop(const char* str)
96 while ((c = str[i++])) {
97 if ('0' > c || c > '9') {
100 t = t * 10 + (c - '0');
106 taskfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
108 pid_t pid = this->id >> 16;
109 struct proc_info* proc;
112 struct task_attribute* tattr = taskfs_get_attr(&dnode->name);
113 if (!tattr || !(proc = get_process(pid)))
117 taskfs_mknod(dnode, pid, taskfs_next_counter(), VFS_IFSEQDEV);
119 tattr->map_file->data = proc;
120 dnode->inode->data = tattr->map_file;
121 dnode->inode->default_fops = &twimap_file_ops;
126 pid = taskfs_atop(dnode->name.value);
128 if (pid <= 0 || !(proc = get_process(pid))) {
132 return taskfs_mknod(dnode, pid, 0, F_DIR);
135 static struct v_file_ops taskfs_file_ops = { .close = default_file_close,
136 .read = default_file_read,
137 .read_page = default_file_read,
138 .write = default_file_write,
139 .write_page = default_file_write,
140 .readdir = taskfs_readdir,
141 .seek = default_file_seek };
142 static struct v_inode_ops taskfs_inode_ops = { .dir_lookup = taskfs_dirlookup,
143 .open = default_inode_open,
144 .mkdir = default_inode_mkdir,
145 .rmdir = default_inode_rmdir,
146 .rename = default_inode_rename };
149 taskfs_init_inode(struct v_superblock* vsb, struct v_inode* inode)
151 inode->default_fops = &taskfs_file_ops;
152 inode->ops = &taskfs_inode_ops;
155 static volatile struct v_superblock* taskfs_sb;
158 taskfs_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
161 vsb->ops.init_inode = taskfs_init_inode;
163 return taskfs_mknod(mount_point, 0, 0, VFS_IFDIR);
167 taskfs_invalidate(pid_t pid)
169 struct v_dnode *pos, *n;
170 struct v_inode* inode = vfs_i_find(taskfs_sb, taskfs_inode_id(pid, 0));
175 llist_for_each(pos, n, &inode->aka_dnodes, aka_list)
177 if (pos->ref_count > 1) {
184 #define ATTR_TABLE_LEN 16
187 taskfs_export_attr(const char* key, struct twimap* attr_map_file)
189 struct task_attribute* tattr = valloc(sizeof(*tattr));
191 tattr->map_file = attr_map_file;
192 tattr->key = HSTR(tattr->key_val, 0);
193 strncpy(tattr->key_val, key, 32);
194 hstr_rehash(&tattr->key, HSTR_FULL_HASH);
196 struct hbucket* slot = &attr_export_table[tattr->key.hash % ATTR_TABLE_LEN];
197 hlist_add(&slot->head, &tattr->attrs);
198 llist_append(&attributes, &tattr->siblings);
201 struct task_attribute*
202 taskfs_get_attr(struct hstr* key)
204 struct hbucket* slot = &attr_export_table[key->hash % ATTR_TABLE_LEN];
205 struct task_attribute *pos, *n;
206 hashtable_bucket_foreach(slot, pos, n, attrs)
208 if (HSTR_EQ(&pos->key, key)) {
221 struct filesystem* taskfs = fsm_new_fs("taskfs", 5);
222 taskfs->mount = taskfs_mount;
224 fsm_register(taskfs);
226 attr_export_table = vcalloc(ATTR_TABLE_LEN, sizeof(struct hbucket));
230 EXPORT_FILE_SYSTEM(taskfs, taskfs_init);