summaryrefslogtreecommitdiff
path: root/fs/mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/mount.c')
-rw-r--r--fs/mount.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/fs/mount.c b/fs/mount.c
new file mode 100644
index 0000000..a7cd949
--- /dev/null
+++ b/fs/mount.c
@@ -0,0 +1,96 @@
+#include <stddef.h>
+
+#include "kernel.h"
+#include "mount.h"
+
+#include "log.h"
+
+#include "lib/string/string.h"
+// temporary
+#include "fd.h"
+
+static mount mounts[MAX_MOUNTS];
+static uint32_t mounts_count=0;
+
+char *mount_type_to_str(uint32_t t)
+{
+ switch(t)
+ {
+ case MOUNT_TYPE_EXT2: return "EXT2";
+ case MOUNT_TYPE_PIPES: return "PIPES";
+ case MOUNT_TYPE_SYS: return "SYS";
+ }
+ return "UNKNOWN";
+}
+
+void mount_add(mount mnt)
+{
+ if(mounts_count==MAX_MOUNTS)kpanic("maxium number of mounts exceeded. increase MAX_MOUNTS in kernel.h and recomplie kernel.");
+ mounts[mounts_count++]=mnt;
+ klog("mounted %s",mnt.path);
+}
+
+void mount_dump()
+{
+ for(int i=0;i<mounts_count;i++)
+ {
+ mount *m=&mounts[i];
+ klog("%s mounted at: %s ",mount_type_to_str(m->type),m->path);
+ }
+}
+
+static uint32_t check_match(char *p1, char *p2)
+{
+ uint32_t c=0;
+ while(1)
+ {
+ if(*p1==0||*p2==0||*p1!=*p2)return c;
+ c++;
+ p1++;
+ p2++;
+ }
+}
+
+/**
+ * Find the mountpoint correspoding with the given path and return in _mnt_ parameter.
+ * The return value points to the input path with chopped of prefix indicating the mount itself.
+ * returns 0 if mount not found.
+ */
+static char* get_mount_for_path(char *path,mount *mnt)
+{
+ if(path[0]!='/')kpanic("this works only for absolute paths!");
+
+ uint32_t best=0;
+ uint32_t best_len=0;
+
+ for(int i=0;i<mounts_count;i++)
+ {
+ mount *m=&mounts[i];
+ uint32_t len=check_match(path,m->path);
+
+ if(len>best_len&&len==strlen(m->path))
+ {
+ best=i;
+ best_len=len;
+ }
+
+ }
+ if(best_len==0)return 0;
+ *mnt=mounts[best];
+ return path+best_len-1;
+}
+
+fd mount_file_open(char *path)
+{
+ mount m;
+ char *p=get_mount_for_path(path,&m);
+ klog("%s in %s",p,m.path);
+ return m.mount_file_open(&m,p);
+}
+
+int mount_read_dir (char *path, fs_dirent *dirs, uint32_t *pos)
+{
+ mount m;
+ char *p=get_mount_for_path(path,&m);
+ return m.mount_read_dir(&m,p,dirs,pos);
+}