fix: dnode cache syncing for pseudo fs
authorMinep <zelong56@gmail.com>
Sat, 17 Sep 2022 11:30:24 +0000 (12:30 +0100)
committerMinep <zelong56@gmail.com>
Sat, 17 Sep 2022 11:30:24 +0000 (12:30 +0100)
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/fs/taskfs.h
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/process/sched.c
lunaix-os/kernel/process/taskfs.c

index d106178bcd5786e4f502ed6a9587e12bd6d5a5ae..539f0a8aa0d8ccd658e522751319606440f936b8 100644 (file)
@@ -197,12 +197,13 @@ struct v_inode
     uint32_t link_count;
     uint32_t lb_usage;
     uint32_t fsize;
+    void* data; // 允许底层FS绑定他的一些专有数据
+    struct llist_header aka_dnodes;
     struct llist_header xattrs;
     struct v_superblock* sb;
     struct hlist_node hash_list;
     struct lru_node lru;
     struct pcache* pg_cache;
-    void* data; // 允许底层FS绑定他的一些专有数据
     struct v_inode_ops* ops;
     struct v_file_ops* default_fops;
 };
@@ -228,6 +229,7 @@ struct v_dnode
     struct v_inode* inode;
     struct v_dnode* parent;
     struct hlist_node hash_list;
+    struct llist_header aka_list;
     struct llist_header children;
     struct llist_header siblings;
     struct v_superblock* super_block;
@@ -262,7 +264,7 @@ struct pcache_pg
     uint32_t flags;
     uint32_t fpos;
 };
-/* --- file system manager --- */
+
 void
 fsm_init();
 
index 0afc048b569cbaa08fd1bc6b56f9055b9f3ed054..0d50be3e4c3a277eea6b4ac3a05bc269367a8d32 100644 (file)
@@ -22,4 +22,7 @@ taskfs_export_attr(const char* key, struct twimap* attr_map_file);
 struct task_attribute*
 taskfs_get_attr(struct hstr* key);
 
+void
+taskfs_invalidate(pid_t pid);
+
 #endif /* __LUNAIX_TASKFS_H */
index c9431bac944992c215230aa31861699e5916ee91..df374cdf41ad41fcf3cd15592a8419c1f22c4c3d 100644 (file)
@@ -163,6 +163,7 @@ vfs_dcache_remove(struct v_dnode* dnode)
     assert(dnode->ref_count == 1);
 
     llist_delete(&dnode->siblings);
+    llist_delete(&dnode->aka_list);
     hlist_delete(&dnode->hash_list);
 
     dnode->parent = NULL;
@@ -225,8 +226,10 @@ void
 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode)
 {
     if (assign_to->inode) {
+        llist_delete(&assign_to->aka_list);
         assign_to->inode->link_count--;
     }
+    llist_append(&inode->aka_dnodes, &assign_to->aka_list);
     assign_to->inode = inode;
     inode->link_count++;
 }
@@ -387,6 +390,7 @@ vfs_d_alloc(struct v_dnode* parent, struct hstr* name)
     memset(dnode, 0, sizeof(*dnode));
     llist_init_head(&dnode->children);
     llist_init_head(&dnode->siblings);
+    llist_init_head(&dnode->aka_list);
     mutex_init(&dnode->lock);
 
     dnode->ref_count = ATOMIC_VAR_INIT(0);
@@ -469,6 +473,7 @@ vfs_i_alloc(struct v_superblock* sb)
     memset(inode, 0, sizeof(*inode));
     mutex_init(&inode->lock);
     llist_init_head(&inode->xattrs);
+    llist_init_head(&inode->aka_dnodes);
 
     sb->ops.init_inode(sb, inode);
 
index 0a9cea2f9643b5c16a904ae5f2fe32daa1276b10..3ee0e7666c32eafe97c3436ac1c2a9ccc103f64b 100644 (file)
@@ -4,6 +4,7 @@
 #include <hal/apic.h>
 #include <hal/cpu.h>
 
+#include <lunaix/fs/taskfs.h>
 #include <lunaix/mm/cake.h>
 #include <lunaix/mm/kalloc.h>
 #include <lunaix/mm/pmm.h>
@@ -335,6 +336,8 @@ destroy_process(pid_t pid)
     llist_delete(&proc->tasks);
     llist_delete(&proc->sleep.sleepers);
 
+    taskfs_invalidate(pid);
+
     if (proc->cwd) {
         vfs_unref_dnode(proc->cwd);
     }
index 14ca61c1c802cac01b2b1f8e382a18f019e645be..28c371346478a5cb83922e35662ccb3246eee4ef 100644 (file)
@@ -85,6 +85,7 @@ taskfs_readdir(struct v_file* file, struct dir_context* dctx)
     return 0;
 }
 
+// ascii to pid
 pid_t
 taskfs_atop(const char* str)
 {
@@ -148,14 +149,35 @@ taskfs_init_inode(struct v_superblock* vsb, struct v_inode* inode)
     inode->ops = &taskfs_inode_ops;
 }
 
+static volatile struct v_superblock* taskfs_sb;
+
 int
 taskfs_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
 {
+    taskfs_sb = vsb;
     vsb->ops.init_inode = taskfs_init_inode;
 
     return taskfs_mknod(mount_point, 0, 0, VFS_IFDIR);
 }
 
+void
+taskfs_invalidate(pid_t pid)
+{
+    struct v_dnode *pos, *n;
+    struct v_inode* inode = vfs_i_find(taskfs_sb, taskfs_inode_id(pid, 0));
+
+    if (!inode)
+        return;
+
+    llist_for_each(pos, n, &inode->aka_dnodes, aka_list)
+    {
+        if (pos->ref_count > 1) {
+            continue;
+        }
+        vfs_d_free(pos);
+    }
+}
+
 #define ATTR_TABLE_LEN 16
 
 void