refactor: make pci device driver loading passive, pci bus scanner will not load them...
[lunaix-os.git] / lunaix-os / kernel / fs / ramfs / ramfs.c
index a1018daa7fcd22dd04503d5a39b490d31dd7fdb7..1a6826eda70f07118caf176084bdfae1ecb33169 100644 (file)
@@ -8,9 +8,11 @@
  * @copyright Copyright (c) 2022
  *
  */
  * @copyright Copyright (c) 2022
  *
  */
+#include <klibc/string.h>
 #include <lunaix/fs.h>
 #include <lunaix/fs/ramfs.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/fs.h>
 #include <lunaix/fs/ramfs.h>
 #include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
 
 /*
     A RAM FS will play a role of being a root.
 
 /*
     A RAM FS will play a role of being a root.
@@ -22,7 +24,7 @@
     case, our rootfs will be something like ext2.
 
     RamFS vs. TwiFS: Indeed, they are both fs that lives in RAM so
     case, our rootfs will be something like ext2.
 
     RamFS vs. TwiFS: Indeed, they are both fs that lives in RAM so
-    there is no foundmentally differences. However, TwiFS is designed
+    there is no foundmental differences. However, TwiFS is designed
     to be a 'virtual FIlesystem for KERnel space' (FIKER), so other
     kernel sub-modules can just create node and attach their own
     implementation of read/write, without brothering to create a
     to be a 'virtual FIlesystem for KERnel space' (FIKER), so other
     kernel sub-modules can just create node and attach their own
     implementation of read/write, without brothering to create a
     'mountibility' for other fs.
 */
 
     'mountibility' for other fs.
 */
 
-volatile static inode_t ino = 0;
+static volatile inode_t ino = 0;
 
 extern const struct v_inode_ops ramfs_inode_ops;
 extern const struct v_file_ops ramfs_file_ops;
 
 
 extern const struct v_inode_ops ramfs_inode_ops;
 extern const struct v_file_ops ramfs_file_ops;
 
+static int
+__ramfs_mknod(struct v_dnode* dnode, struct v_inode** nod_out, u32_t flags)
+{
+    struct v_inode* inode = vfs_i_alloc(dnode->super_block);
+
+    if (!inode) {
+        return ENOMEM;
+    }
+
+    struct ram_inode* rinode = valloc(sizeof(struct ram_inode));
+
+    if (!rinode) {
+        vfs_i_free(inode);
+        return ENOMEM;
+    }
+
+    rinode->flags = flags;
+    inode->data = rinode;
+
+    if (!(flags & RAMF_DIR)) {
+        inode->itype = VFS_IFFILE;
+    }
+
+    if ((flags & RAMF_SYMLINK)) {
+        inode->itype |= VFS_IFSYMLINK;
+    }
+
+    if (nod_out) {
+        *nod_out = inode;
+    }
+
+    vfs_i_addhash(inode);
+    vfs_assign_inode(dnode, inode);
+
+    return 0;
+}
+
 int
 ramfs_readdir(struct v_file* file, struct dir_context* dctx)
 {
 int
 ramfs_readdir(struct v_file* file, struct dir_context* dctx)
 {
@@ -65,33 +104,21 @@ ramfs_readdir(struct v_file* file, struct dir_context* dctx)
 int
 ramfs_mkdir(struct v_inode* this, struct v_dnode* dnode)
 {
 int
 ramfs_mkdir(struct v_inode* this, struct v_dnode* dnode)
 {
-    struct v_inode* inode = vfs_i_alloc(dnode->super_block);
-    inode->itype = VFS_IFDIR;
-
-    vfs_i_addhash(inode);
-    vfs_assign_inode(dnode, inode);
-
-    return 0;
+    return __ramfs_mknod(dnode, NULL, RAMF_DIR);
 }
 
 int
 ramfs_create(struct v_inode* this, struct v_dnode* dnode)
 {
 }
 
 int
 ramfs_create(struct v_inode* this, struct v_dnode* dnode)
 {
-    struct v_inode* inode = vfs_i_alloc(dnode->super_block);
-    inode->itype = VFS_IFFILE;
-
-    vfs_i_addhash(inode);
-    vfs_assign_inode(dnode, inode);
-
-    return 0;
+    return __ramfs_mknod(dnode, NULL, RAMF_FILE);
 }
 
 void
 ramfs_inode_init(struct v_superblock* vsb, struct v_inode* inode)
 {
     inode->id = ino++;
 }
 
 void
 ramfs_inode_init(struct v_superblock* vsb, struct v_inode* inode)
 {
     inode->id = ino++;
-    inode->ops = &ramfs_inode_ops;
-    inode->default_fops = &ramfs_file_ops;
+    inode->ops = (struct v_inode_ops*)&ramfs_inode_ops;
+    inode->default_fops = (struct v_file_ops*)&ramfs_file_ops;
 }
 
 int
 }
 
 int
@@ -99,13 +126,7 @@ ramfs_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
 {
     vsb->ops.init_inode = ramfs_inode_init;
 
 {
     vsb->ops.init_inode = ramfs_inode_init;
 
-    struct v_inode* inode = vfs_i_alloc(vsb);
-    inode->itype = VFS_IFDIR;
-
-    vfs_i_addhash(inode);
-    vfs_assign_inode(mount_point, inode);
-
-    return 0;
+    return __ramfs_mknod(mount_point, NULL, RAMF_DIR);
 }
 
 int
 }
 
 int
@@ -117,12 +138,69 @@ ramfs_unmount(struct v_superblock* vsb)
 void
 ramfs_init()
 {
 void
 ramfs_init()
 {
-    struct filesystem* ramfs = fsm_new_fs("ramfs", 5);
+    struct filesystem* ramfs = fsm_new_fs("ramfs", -1);
     ramfs->mount = ramfs_mount;
     ramfs->unmount = ramfs_unmount;
 
     fsm_register(ramfs);
 }
     ramfs->mount = ramfs_mount;
     ramfs->unmount = ramfs_unmount;
 
     fsm_register(ramfs);
 }
+EXPORT_FILE_SYSTEM(ramfs, ramfs_init);
+
+int
+ramfs_mksymlink(struct v_inode* this, const char* target)
+{
+    struct ram_inode* rinode = RAM_INODE(this->data);
+
+    assert(!(rinode->flags & RAMF_SYMLINK));
+
+    size_t len = strlen(target);
+    char* symlink = valloc(len);
+
+    if (!symlink) {
+        return ENOMEM;
+    }
+
+    memcpy(symlink, target, len);
+
+    this->itype |= VFS_IFSYMLINK;
+    rinode->flags |= RAMF_SYMLINK;
+    rinode->symlink = symlink;
+
+    return 0;
+}
+
+int
+ramfs_read_symlink(struct v_inode* this, const char** path_out)
+{
+    struct ram_inode* rinode = RAM_INODE(this->data);
+
+    if (!(rinode->flags & RAMF_SYMLINK)) {
+        return EINVAL;
+    }
+
+    *path_out = rinode->symlink;
+
+    return 0;
+}
+
+int
+ramfs_unlink(struct v_inode* this)
+{
+    struct ram_inode* rinode = RAM_INODE(this->data);
+
+    if ((rinode->flags & RAMF_SYMLINK)) {
+        rinode->flags &= ~RAMF_SYMLINK;
+        this->itype &= ~VFS_IFSYMLINK;
+
+        vfree(rinode->symlink);
+
+        return 0;
+    }
+
+    // TODO
+
+    return 0;
+}
 
 const struct v_inode_ops ramfs_inode_ops = { .mkdir = ramfs_mkdir,
                                              .rmdir = default_inode_rmdir,
 
 const struct v_inode_ops ramfs_inode_ops = { .mkdir = ramfs_mkdir,
                                              .rmdir = default_inode_rmdir,
@@ -130,10 +208,16 @@ const struct v_inode_ops ramfs_inode_ops = { .mkdir = ramfs_mkdir,
                                                default_inode_dirlookup,
                                              .create = ramfs_create,
                                              .open = default_inode_open,
                                                default_inode_dirlookup,
                                              .create = ramfs_create,
                                              .open = default_inode_open,
+                                             .unlink = ramfs_unlink,
+                                             .set_symlink = ramfs_mksymlink,
+                                             .read_symlink = ramfs_read_symlink,
                                              .rename = default_inode_rename };
 
 const struct v_file_ops ramfs_file_ops = { .readdir = ramfs_readdir,
                                            .close = default_file_close,
                                            .read = default_file_read,
                                              .rename = default_inode_rename };
 
 const struct v_file_ops ramfs_file_ops = { .readdir = ramfs_readdir,
                                            .close = default_file_close,
                                            .read = default_file_read,
+                                           .read_page = default_file_read_page,
                                            .write = default_file_write,
                                            .write = default_file_write,
+                                           .write_page =
+                                             default_file_write_page,
                                            .seek = default_file_seek };
\ No newline at end of file
                                            .seek = default_file_seek };
\ No newline at end of file