diff options
| author | Miguel <m.i@gmx.at> | 2018-09-16 23:46:30 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-16 23:46:30 +0200 |
| commit | 06e6e427c76bdb88a7f72dd04411d95a4bda3270 (patch) | |
| tree | 5c2bae3ca5292bf3db58c33ef3d7f4f3947593c3 /fs | |
| parent | 740ae2e69995df37c44fe61f57642ee642982ca2 (diff) | |
starting to create sysfs
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ext2.c | 25 | ||||
| -rw-r--r-- | fs/ext2.h | 3 | ||||
| -rw-r--r-- | fs/fd.h | 5 | ||||
| -rw-r--r-- | fs/mount.c | 96 | ||||
| -rw-r--r-- | fs/mount.h | 53 |
5 files changed, 180 insertions, 2 deletions
@@ -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); +} @@ -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); @@ -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 |
