summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-09-16 23:46:30 +0200
committerMiguel <m.i@gmx.at>2018-09-16 23:46:30 +0200
commit06e6e427c76bdb88a7f72dd04411d95a4bda3270 (patch)
tree5c2bae3ca5292bf3db58c33ef3d7f4f3947593c3 /fs
parent740ae2e69995df37c44fe61f57642ee642982ca2 (diff)
starting to create sysfs
Diffstat (limited to 'fs')
-rw-r--r--fs/ext2.c25
-rw-r--r--fs/ext2.h3
-rw-r--r--fs/fd.h5
-rw-r--r--fs/mount.c96
-rw-r--r--fs/mount.h53
5 files changed, 180 insertions, 2 deletions
diff --git a/fs/ext2.c b/fs/ext2.c
index 659edda..b518bd9 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -1,6 +1,7 @@
#include <stdbool.h>
#include <stdint.h>
+#include "mount.h"
#include "kernel.h"
#include "ext2.h"
@@ -303,3 +304,27 @@ int ext2_read_dir(uint32_t ext2_start_addr, int inode_nr, fs_dirent *dirs, uint3
}
return 0;
}
+
+/* mount interface */
+
+fd ext2_mount_file_open(mount *m,char *path)
+{
+ return fd_from_path(path);
+}
+
+int ext2_mount_read_dir(mount *m,char *path, fs_dirent *dirs, uint32_t *pos)
+{
+ uint32_t inode= ext2_filename_to_inode(VMEM_EXT2_RAMIMAGE,path);
+ return ext2_read_dir(m->data, inode, dirs, pos);
+}
+
+void ext2_mount(char *path)
+{
+ mount m;
+ m.type=MOUNT_TYPE_EXT2;
+ memcpy(m.path,path,strlen(path)+1);
+ m.mount_file_open=ext2_mount_file_open;
+ m.mount_read_dir=ext2_mount_read_dir;
+ m.data=VMEM_EXT2_RAMIMAGE;
+ mount_add(m);
+}
diff --git a/fs/ext2.h b/fs/ext2.h
index efa045f..3c53350 100644
--- a/fs/ext2.h
+++ b/fs/ext2.h
@@ -33,3 +33,6 @@ uint32_t ext2_filename_to_inode(uint32_t ext2_start_addr, char *path);
/** get address of first byte of given block for given inode number */
uint32_t ext2_inode_blockstart(uint32_t ext2_start_addr,uint32_t inode_nr,uint32_t block);
+
+/** mount */
+void ext2_mount(char *path);
diff --git a/fs/fd.h b/fs/fd.h
index 429387b..a51a0f3 100644
--- a/fs/fd.h
+++ b/fs/fd.h
@@ -26,7 +26,8 @@ typedef struct
enum FD_TYPE{
FD_TYPE_FIFO_BUFFERED=1,
- FD_TYPE_EXT2_FILE=2
+ FD_TYPE_EXT2_FILE=2,
+ FD_TYPE_EXT2_DIR=3
};
typedef struct fd_struct
@@ -47,5 +48,5 @@ bool fd_close(fd*);
fd fd_from_fifo(fifo* f);
fd fd_from_path(char *path);
-
+//fd fd_from_sysfs(void(*g)(void (*f)(char *fmt, ...)));
#endif
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);
+}
diff --git a/fs/mount.h b/fs/mount.h
new file mode 100644
index 0000000..4e61c28
--- /dev/null
+++ b/fs/mount.h
@@ -0,0 +1,53 @@
+/**
+ * @file
+ * Simple mount point manager
+ * ==========================
+ *
+ * Add up to MAX_MOUNTS (as defined in kernel.h) mounts and use
+ * mount_file_open() and mount_read_dir() to transparently
+ * be dispatch the underlying commands to them based on the supplied paths.
+ *
+ * Mount directories should exist on root direcotry '/'
+ */
+
+#ifndef MOUNT_H
+#define MOUNT_H
+
+#include <stdint.h>
+#include "interface/fs.h" // fs_dirent for read_dir
+#include "fd.h" // file descriptor returned by open
+
+/** the possible values for mount_struct.type */
+enum MOUNT_TYPE{
+ MOUNT_TYPE_EXT2 = 1,
+ MOUNT_TYPE_PIPES = 2,
+ MOUNT_TYPE_SYS = 3
+};
+
+/** struct telling all we need about a single mountpoint */
+typedef struct mount_struct
+{
+ uint32_t type; // MOUNT_TYPE
+
+ char path[256]; // where are we mounted (provide leading and trailing slash!)
+
+ fd (*mount_file_open)(struct mount_struct*, char *path);
+ int (*mount_read_dir) (struct mount_struct*, char *path, fs_dirent *dirs, uint32_t *pos);
+
+ void *data; //opaque data
+
+}mount;
+
+/** dumps mount info to klog */
+void mount_dump();
+
+/** adds a new mountpoints */
+void mount_add(mount mnt);
+
+/** dispatchers to according mount points */
+fd mount_file_open(char *path);
+
+/** TODO: should use fd number instead of PATH on each call*/
+int mount_read_dir (char *path, fs_dirent *dirs, uint32_t *pos);
+
+#endif