feat: better rtc framework which aims to remove single rtc restrictions.
[lunaix-os.git] / lunaix-os / kernel / fs / mount.c
index 38258ee68d831a6a52114b4a3d42ae2819406545..12e1d4b94c273acc87df26203f8ea96c2b611711 100644 (file)
@@ -2,9 +2,14 @@
 #include <lunaix/fs.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/process.h>
+#include <lunaix/spike.h>
+#include <lunaix/syscall_utils.h>
+#include <lunaix/syslog.h>
 #include <lunaix/types.h>
 
-static struct llist_header all_mnts = { .next = &all_mnts, .prev = &all_mnts };
+LOG_MODULE("fs")
+
+struct llist_header all_mnts = { .next = &all_mnts, .prev = &all_mnts };
 
 struct v_mount*
 vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point)
@@ -18,12 +23,12 @@ vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point)
     llist_append(&all_mnts, &mnt->list);
     mutex_init(&mnt->lock);
 
-    mnt_mkbusy(parent);
     mnt->parent = parent;
     mnt->mnt_point = mnt_point;
     mnt->super_block = mnt_point->super_block;
 
     if (parent) {
+        mnt_mkbusy(parent);
         mutex_lock(&mnt->parent->lock);
         llist_append(&parent->submnts, &mnt->sibmnts);
         mutex_unlock(&mnt->parent->lock);
@@ -68,30 +73,23 @@ __vfs_do_unmount(struct v_mount* mnt)
 void
 mnt_mkbusy(struct v_mount* mnt)
 {
-    while (mnt) {
-        mutex_lock(&mnt->lock);
-        mnt->busy_counter++;
-        mutex_unlock(&mnt->lock);
-
-        mnt = mnt->parent;
-    }
+    mutex_lock(&mnt->lock);
+    mnt->busy_counter++;
+    mutex_unlock(&mnt->lock);
 }
 
 void
 mnt_chillax(struct v_mount* mnt)
 {
-    while (mnt) {
-        mutex_lock(&mnt->lock);
-        mnt->busy_counter--;
-        mutex_unlock(&mnt->lock);
-
-        mnt = mnt->parent;
-    }
+    mutex_lock(&mnt->lock);
+    mnt->busy_counter--;
+    mutex_unlock(&mnt->lock);
 }
 
 int
 vfs_mount_root(const char* fs_name, struct device* device)
 {
+    extern struct v_dnode* vfs_sysroot;
     int errno = 0;
     if (vfs_sysroot->mnt && (errno = vfs_unmount_at(vfs_sysroot))) {
         return errno;
@@ -135,6 +133,10 @@ vfs_mount_at(const char* fs_name,
              struct v_dnode* mnt_point,
              int options)
 {
+    if (device && device->dev_type != DEV_IFVOL) {
+        return ENOTBLK;
+    }
+
     if (mnt_point->inode && !(mnt_point->inode->itype & VFS_IFDIR)) {
         return ENOTDIR;
     }
@@ -144,11 +146,20 @@ vfs_mount_at(const char* fs_name,
         return ENODEV;
     }
 
+    if (fs->types == FSTYPE_ROFS) {
+        options |= MNT_RO;
+    }
+
+    char* dev_name = "sys";
     struct v_mount* parent_mnt = mnt_point->mnt;
     struct v_superblock *sb = vfs_sb_alloc(), *old_sb = mnt_point->super_block;
     sb->dev = device;
     mnt_point->super_block = sb;
 
+    if (device) {
+        dev_name = device->name_val;
+    }
+
     int errno = 0;
     if (!(errno = fs->mount(sb, mnt_point))) {
         sb->fs = fs;
@@ -159,6 +170,8 @@ vfs_mount_at(const char* fs_name,
             goto cleanup;
         }
 
+        kprintf("mount: dev=%s, fs=%s, mode=%d\n", dev_name, fs_name, options);
+
         mnt_point->mnt->flags = options;
     } else {
         goto cleanup;
@@ -167,6 +180,11 @@ vfs_mount_at(const char* fs_name,
     return errno;
 
 cleanup:
+    kprintf(KERROR "mount: dev=%s, fs=%s, mode=%d, err=%d\n",
+            dev_name,
+            fs_name,
+            options,
+            errno);
     mnt_point->super_block = old_sb;
     vfs_sb_free(sb);
     return errno;