2019-06-22 11:11:12 -05:00
|
|
|
#include <tasking.h>
|
2019-06-22 16:11:44 -05:00
|
|
|
#include <ipc/vfs.h>
|
2019-06-27 17:00:23 -05:00
|
|
|
#include <mailboxes.h>
|
2019-06-29 09:04:34 -05:00
|
|
|
#include <stdlib.h>
|
2019-07-01 15:30:00 -05:00
|
|
|
#include <string.h>
|
2019-08-25 13:53:44 -05:00
|
|
|
#include <dbg.h>
|
2019-06-22 11:11:12 -05:00
|
|
|
|
2019-06-29 09:55:02 -05:00
|
|
|
#define PROC_FD_LIMIT 1024
|
|
|
|
|
2019-06-29 09:27:41 -05:00
|
|
|
typedef struct _vfs_mapping_struct {
|
|
|
|
char* mntpnt;
|
|
|
|
uint32_t type;
|
|
|
|
struct _vfs_mapping_struct* next;
|
|
|
|
} vfs_mapping;
|
|
|
|
|
2019-06-29 09:55:02 -05:00
|
|
|
typedef struct {
|
2019-07-20 11:03:27 -05:00
|
|
|
vfs_mapping* mntpnt;
|
2019-06-29 09:55:02 -05:00
|
|
|
char* path;
|
2019-07-20 11:03:27 -05:00
|
|
|
char* mode;
|
2019-06-29 09:55:02 -05:00
|
|
|
uint32_t pos;
|
|
|
|
char error;
|
2019-08-31 16:46:52 -05:00
|
|
|
void* fs_data;
|
2019-06-29 09:55:02 -05:00
|
|
|
} vfs_file;
|
|
|
|
|
2019-06-29 09:27:41 -05:00
|
|
|
static const char** drv_names;
|
|
|
|
static uint32_t* drvs;
|
|
|
|
static uint32_t max_drvs;
|
2019-08-25 13:53:44 -05:00
|
|
|
static uint32_t num_drvs;
|
2019-06-29 09:27:41 -05:00
|
|
|
static vfs_mapping* head_mapping;
|
|
|
|
static vfs_mapping* tail_mapping;
|
2019-07-20 11:03:27 -05:00
|
|
|
vfs_file* fd_tables[32768];
|
2019-06-29 09:55:02 -05:00
|
|
|
uint16_t open_fds[32768];
|
2019-07-27 11:11:28 -05:00
|
|
|
uint32_t box;
|
|
|
|
vfs_message* get_message(Message* msg) {
|
2019-06-29 09:14:59 -05:00
|
|
|
msg->msg=malloc(sizeof(vfs_message));
|
|
|
|
mailbox_get_msg(box,msg,sizeof(vfs_message));
|
2019-07-01 15:13:47 -05:00
|
|
|
while (msg->from==0 && msg->size==0) {
|
|
|
|
yield();
|
2019-07-31 17:45:14 -05:00
|
|
|
mailbox_get_msg(box,msg,sizeof(vfs_message));
|
2019-07-01 15:13:47 -05:00
|
|
|
}
|
2019-06-29 09:14:59 -05:00
|
|
|
vfs_message* vfs_msg=(vfs_message*)msg->msg;
|
|
|
|
return vfs_msg;
|
|
|
|
}
|
|
|
|
|
2019-06-29 09:27:41 -05:00
|
|
|
static int vfsstrcmp(const char* s1,const char* s2) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; s1[i] == s2[i]; i++) {
|
|
|
|
if (s1[i] == '\0') return 0;
|
|
|
|
}
|
|
|
|
if (s1[i] == '\0') return 0;
|
|
|
|
return s1[i] - s2[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_vfs() {
|
|
|
|
drv_names=malloc(sizeof(const char**)*32);
|
2019-08-05 14:25:46 -05:00
|
|
|
drvs=malloc(sizeof(uint32_t)*32);
|
2019-06-29 09:27:41 -05:00
|
|
|
max_drvs=32;
|
2019-08-25 13:53:44 -05:00
|
|
|
num_drvs=0;
|
2019-08-03 15:50:23 -05:00
|
|
|
head_mapping=NULL;
|
2019-06-29 09:27:41 -05:00
|
|
|
tail_mapping=NULL;
|
|
|
|
}
|
|
|
|
|
2019-08-03 15:50:23 -05:00
|
|
|
uint32_t register_fs_intern(uint32_t drv,const char* type) {
|
2019-08-25 13:53:44 -05:00
|
|
|
if (num_drvs==max_drvs) {
|
2019-06-29 09:27:41 -05:00
|
|
|
drvs=realloc(drvs,sizeof(uint32_t)*(max_drvs+32));
|
|
|
|
drv_names=realloc(drv_names,sizeof(char*)*(max_drvs+32));
|
|
|
|
max_drvs+=32;
|
|
|
|
}
|
2019-08-25 13:53:44 -05:00
|
|
|
drvs[num_drvs]=drv;
|
|
|
|
drv_names[num_drvs]=type;
|
|
|
|
num_drvs++;
|
|
|
|
return num_drvs-1;
|
2019-06-29 09:27:41 -05:00
|
|
|
}
|
|
|
|
|
2019-07-31 17:45:14 -05:00
|
|
|
void vfs_fopen(vfs_message* vfs_msg,uint32_t from) {
|
2019-07-01 15:13:47 -05:00
|
|
|
vfs_mapping* mnt=head_mapping;
|
|
|
|
vfs_mapping* mntpnt=NULL;
|
|
|
|
uint32_t mntpnt_len=0;
|
|
|
|
for (;mnt!=NULL;mnt=mnt->next) {
|
|
|
|
char* root=mnt->mntpnt;
|
|
|
|
if (strlen(root)>mntpnt_len) {
|
|
|
|
if (vfsstrcmp(root,vfs_msg->path)==0) {
|
|
|
|
mntpnt=mnt;
|
|
|
|
mntpnt_len=strlen(root);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-07-31 17:45:14 -05:00
|
|
|
if (mntpnt) { // was if (mntpnt)
|
2019-07-01 15:13:47 -05:00
|
|
|
Message msg;
|
|
|
|
char* path_buf=malloc(sizeof(char)*4096);
|
|
|
|
strcpy(path_buf,&(vfs_msg->path[0]));
|
|
|
|
memset(&(vfs_msg->path[0]),0,sizeof(char)*4096);
|
2019-07-01 15:30:00 -05:00
|
|
|
for (size_t i=0;i<strlen(path_buf)+1-mntpnt_len;i++) {
|
2019-07-01 15:13:47 -05:00
|
|
|
vfs_msg->path[i]=path_buf[i+mntpnt_len];
|
|
|
|
}
|
|
|
|
free(path_buf);
|
2019-07-27 11:11:28 -05:00
|
|
|
msg.from=box;
|
2019-07-01 15:13:47 -05:00
|
|
|
msg.to=drvs[mntpnt->type];
|
|
|
|
msg.size=sizeof(vfs_message);
|
|
|
|
msg.msg=vfs_msg;
|
|
|
|
mailbox_send_msg(&msg);
|
|
|
|
yield();
|
2019-07-31 17:45:14 -05:00
|
|
|
vfs_message* resp_msg=get_message(&msg);
|
|
|
|
if (resp_msg->flags!=0) {
|
|
|
|
return;
|
2019-07-01 15:13:47 -05:00
|
|
|
}
|
|
|
|
if (fd_tables[from]==NULL) {
|
|
|
|
fd_tables[from]=malloc(PROC_FD_LIMIT*sizeof(vfs_file));
|
2019-07-31 19:46:01 -05:00
|
|
|
open_fds[from]=0;
|
2019-07-01 15:13:47 -05:00
|
|
|
} else {
|
|
|
|
if (open_fds[from]==PROC_FD_LIMIT) {
|
2019-08-28 20:12:15 -05:00
|
|
|
vfs_msg->flags=2;
|
2019-07-01 15:13:47 -05:00
|
|
|
}
|
2019-06-29 09:55:02 -05:00
|
|
|
}
|
2019-07-01 15:13:47 -05:00
|
|
|
uint16_t fd=open_fds[from];
|
|
|
|
open_fds[from]++;
|
2019-07-20 11:03:27 -05:00
|
|
|
fd_tables[from][fd].mntpnt=mntpnt;
|
|
|
|
fd_tables[from][fd].path=malloc(sizeof(char)*(strlen(&vfs_msg->path[0])+1));
|
|
|
|
strcpy(fd_tables[from][fd].path,&vfs_msg->path[0]);
|
|
|
|
fd_tables[from][fd].mode=malloc(sizeof(char)*(strlen(&vfs_msg->mode[0])+1));
|
|
|
|
strcpy(fd_tables[from][fd].mode,&vfs_msg->mode[0]);
|
|
|
|
fd_tables[from][fd].pos=0;
|
|
|
|
fd_tables[from][fd].error=0;
|
2019-08-31 16:46:52 -05:00
|
|
|
fd_tables[from][fd].fs_data=resp_msg->fs_data;
|
2019-07-01 15:13:47 -05:00
|
|
|
vfs_msg->fd=fd;
|
2019-07-31 17:45:14 -05:00
|
|
|
vfs_msg->flags=0;
|
|
|
|
return;
|
2019-06-29 09:55:02 -05:00
|
|
|
}
|
2019-08-28 20:12:15 -05:00
|
|
|
vfs_msg->flags=2;
|
2019-06-29 09:55:02 -05:00
|
|
|
}
|
|
|
|
|
2019-08-28 20:32:14 -05:00
|
|
|
void vfs_puts(vfs_message* vfs_msg,uint32_t from) {
|
|
|
|
char* data=malloc(sizeof(char)*vfs_msg->data);
|
|
|
|
Message msg;
|
|
|
|
msg.msg=data;
|
|
|
|
mailbox_get_msg(box,&msg,vfs_msg->data);
|
|
|
|
while (msg.from==0 && msg.size==0) {
|
|
|
|
yield();
|
|
|
|
mailbox_get_msg(box,&msg,sizeof(vfs_message));
|
|
|
|
}
|
|
|
|
if (msg.from==0) {
|
|
|
|
vfs_msg->flags=2;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint32_t fd=vfs_msg->fd;
|
|
|
|
vfs_file file_info=fd_tables[from][fd];
|
|
|
|
strcpy(&vfs_msg->path[0],file_info.path);
|
|
|
|
strcpy(&vfs_msg->mode[0],file_info.mode);
|
|
|
|
vfs_msg->pos=file_info.pos;
|
2019-08-31 16:46:52 -05:00
|
|
|
vfs_msg->fs_data=fd_tables[from][fd].fs_data;
|
2019-08-28 20:32:14 -05:00
|
|
|
msg.from=box;
|
|
|
|
msg.to=drvs[file_info.mntpnt->type];
|
|
|
|
msg.size=sizeof(vfs_message);
|
|
|
|
msg.msg=vfs_msg;
|
|
|
|
mailbox_send_msg(&msg);
|
|
|
|
msg.size=vfs_msg->data;
|
|
|
|
msg.msg=data;
|
|
|
|
mailbox_send_msg(&msg);
|
|
|
|
free(data);
|
|
|
|
yield();
|
2019-08-31 10:39:30 -05:00
|
|
|
vfs_message* resp=get_message(&msg);
|
|
|
|
if (resp->flags!=0) {
|
|
|
|
vfs_msg->flags=resp->flags;
|
2019-08-28 20:32:14 -05:00
|
|
|
return;
|
|
|
|
}
|
2019-09-01 10:06:33 -05:00
|
|
|
fd_tables[from][fd].pos+=vfs_msg->data;
|
2019-08-28 20:32:14 -05:00
|
|
|
vfs_msg->flags=0;
|
|
|
|
}
|
|
|
|
|
2019-09-01 10:06:33 -05:00
|
|
|
char* vfs_gets(vfs_message* vfs_msg,uint32_t from) {
|
|
|
|
uint32_t fd=vfs_msg->fd;
|
|
|
|
vfs_file file_info=fd_tables[from][fd];
|
|
|
|
strcpy(&vfs_msg->path[0],file_info.path);
|
|
|
|
strcpy(&vfs_msg->mode[0],file_info.mode);
|
|
|
|
vfs_msg->pos=file_info.pos;
|
|
|
|
vfs_msg->fs_data=fd_tables[from][fd].fs_data;
|
|
|
|
Message msg;
|
|
|
|
msg.from=box;
|
|
|
|
msg.to=drvs[file_info.mntpnt->type];
|
|
|
|
msg.size=sizeof(vfs_message);
|
|
|
|
msg.msg=vfs_msg;
|
|
|
|
mailbox_send_msg(&msg);
|
|
|
|
yield();
|
|
|
|
vfs_message* resp=get_message(&msg);
|
|
|
|
if (resp->flags!=0) {
|
|
|
|
vfs_msg->flags=resp->flags;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
char* data=malloc(sizeof(char)*resp->data);
|
|
|
|
msg.msg=data;
|
|
|
|
mailbox_get_msg(box,&msg,resp->data);
|
|
|
|
while (msg.from==0 && msg.size==0) {
|
|
|
|
yield();
|
|
|
|
mailbox_get_msg(box,&msg,sizeof(vfs_message));
|
|
|
|
}
|
|
|
|
if (msg.from==0) {
|
|
|
|
vfs_msg->flags=2;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (resp->data>vfs_msg->data) {
|
|
|
|
vfs_msg->flags=2;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
vfs_msg->data=resp->data;
|
|
|
|
fd_tables[from][fd].pos+=vfs_msg->data;
|
|
|
|
vfs_msg->flags=0;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2019-08-28 20:32:14 -05:00
|
|
|
|
2019-08-03 15:50:23 -05:00
|
|
|
void vfs_register_fs(vfs_message* vfs_msg, uint32_t from) {
|
2019-08-05 14:26:20 -05:00
|
|
|
char* name=malloc(sizeof(char)*(strlen(vfs_msg->mode)+1));
|
2019-08-03 15:50:23 -05:00
|
|
|
name[0]='\0';
|
2019-08-05 14:26:20 -05:00
|
|
|
strcpy(name,&vfs_msg->mode[0]);
|
2019-08-25 13:53:44 -05:00
|
|
|
register_fs_intern(vfs_msg->fd,name);
|
2019-08-03 15:50:23 -05:00
|
|
|
vfs_msg->flags=0;
|
|
|
|
}
|
|
|
|
|
2019-08-25 13:53:44 -05:00
|
|
|
void vfs_mount(vfs_message* vfs_msg, uint32_t from) {
|
|
|
|
char* path=malloc(sizeof(char)*(strlen(vfs_msg->path)+1));
|
|
|
|
path[0]='\0';
|
|
|
|
strcpy(path,&vfs_msg->path[0]);
|
|
|
|
char* type=malloc(sizeof(char)*(strlen(vfs_msg->mode)+1));
|
|
|
|
type[0]='\0';
|
|
|
|
strcpy(type,&vfs_msg->mode[0]);
|
|
|
|
char* disk_file=malloc(sizeof(char)*(vfs_msg->data));
|
|
|
|
Message msg;
|
|
|
|
msg.msg=disk_file;
|
|
|
|
mailbox_get_msg(box,&msg,vfs_msg->data);
|
|
|
|
while (msg.from==0 && msg.size==0) {
|
|
|
|
yield();
|
|
|
|
mailbox_get_msg(box,&msg,sizeof(vfs_message));
|
|
|
|
}
|
|
|
|
if (msg.from==0) {
|
2019-08-28 20:12:15 -05:00
|
|
|
vfs_msg->flags=2;
|
2019-08-25 13:53:44 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
char found=0;
|
|
|
|
uint32_t i;
|
|
|
|
for (i=0;i<num_drvs;i++) {
|
|
|
|
if (strcmp(type,drv_names[i])==0) {
|
|
|
|
found=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
2019-08-28 20:12:15 -05:00
|
|
|
vfs_msg->flags=2;
|
2019-08-25 13:53:44 -05:00
|
|
|
return;
|
|
|
|
}
|
2019-08-31 10:37:49 -05:00
|
|
|
msg.from=box;
|
|
|
|
msg.to=drvs[i];
|
|
|
|
msg.size=sizeof(vfs_message);
|
|
|
|
msg.msg=vfs_msg;
|
|
|
|
mailbox_send_msg(&msg);
|
|
|
|
msg.size=vfs_msg->data;
|
|
|
|
msg.msg=disk_file;
|
|
|
|
mailbox_send_msg(&msg);
|
|
|
|
yield();
|
|
|
|
msg.size=sizeof(vfs_message);
|
|
|
|
vfs_message* resp=get_message(&msg);
|
|
|
|
if (resp->flags!=0) {
|
|
|
|
vfs_msg->flags=resp->flags;
|
|
|
|
return;
|
|
|
|
}
|
2019-08-25 13:53:44 -05:00
|
|
|
if (head_mapping==NULL) {
|
|
|
|
vfs_mapping* mapping=malloc(sizeof(vfs_mapping));
|
|
|
|
mapping->mntpnt=malloc(sizeof(char)*(strlen(path)+1));
|
|
|
|
strcpy(mapping->mntpnt,path);
|
2019-08-28 20:29:55 -05:00
|
|
|
mapping->type=i;
|
2019-08-25 13:53:44 -05:00
|
|
|
mapping->next=NULL;
|
|
|
|
head_mapping=mapping;
|
|
|
|
tail_mapping=mapping;
|
|
|
|
} else {
|
|
|
|
vfs_mapping* mapping=malloc(sizeof(vfs_mapping));
|
|
|
|
mapping->mntpnt=malloc(sizeof(char)*(strlen(path)+1));
|
|
|
|
strcpy(mapping->mntpnt,path);
|
2019-08-28 20:29:55 -05:00
|
|
|
mapping->type=i;
|
2019-08-25 13:53:44 -05:00
|
|
|
mapping->next=NULL;
|
|
|
|
tail_mapping->next=mapping;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-24 11:52:13 -05:00
|
|
|
int main() {
|
2019-06-29 09:27:41 -05:00
|
|
|
init_vfs();
|
2019-07-27 11:11:28 -05:00
|
|
|
box=mailbox_new(16);
|
2019-06-27 17:00:23 -05:00
|
|
|
yield();
|
2019-06-29 09:55:02 -05:00
|
|
|
while (1) {
|
|
|
|
Message msg;
|
2019-07-27 11:11:28 -05:00
|
|
|
vfs_message* vfs_msg=get_message(&msg);
|
2019-07-31 17:45:14 -05:00
|
|
|
uint32_t sender=msg.from;
|
2019-09-01 10:06:33 -05:00
|
|
|
char* gets_data;
|
2019-06-29 09:55:02 -05:00
|
|
|
switch (vfs_msg->type) {
|
|
|
|
case VFS_OPEN:
|
2019-07-31 17:45:14 -05:00
|
|
|
vfs_fopen(vfs_msg,msg.from);
|
2019-06-29 09:55:02 -05:00
|
|
|
break;
|
2019-08-28 20:32:14 -05:00
|
|
|
case VFS_PUTS:
|
|
|
|
vfs_puts(vfs_msg,msg.from);
|
|
|
|
break;
|
2019-09-01 10:06:33 -05:00
|
|
|
case VFS_GETS:
|
|
|
|
gets_data=vfs_gets(vfs_msg,msg.from);
|
|
|
|
break;
|
2019-06-29 09:55:02 -05:00
|
|
|
case VFS_MOUNT:
|
2019-08-25 13:53:44 -05:00
|
|
|
vfs_mount(vfs_msg,msg.from);
|
2019-06-29 09:55:02 -05:00
|
|
|
break;
|
2019-08-03 15:50:23 -05:00
|
|
|
case VFS_REGISTER_FS:
|
|
|
|
vfs_register_fs(vfs_msg,msg.from);
|
|
|
|
break;
|
2019-06-29 09:55:02 -05:00
|
|
|
default:
|
2019-08-28 20:12:15 -05:00
|
|
|
vfs_msg->flags=1;
|
2019-06-29 09:55:02 -05:00
|
|
|
break;
|
|
|
|
}
|
2019-07-31 17:45:14 -05:00
|
|
|
msg.from=box;
|
|
|
|
msg.to=sender;
|
2019-06-29 09:55:02 -05:00
|
|
|
mailbox_send_msg(&msg);
|
2019-09-01 10:06:33 -05:00
|
|
|
if (vfs_msg->type==VFS_GETS && gets_data!=NULL) {
|
|
|
|
msg.size=vfs_msg->data;
|
|
|
|
msg.msg=gets_data;
|
|
|
|
mailbox_send_msg(&msg);
|
|
|
|
}
|
2019-06-29 09:55:02 -05:00
|
|
|
yield();
|
2019-06-29 09:21:08 -05:00
|
|
|
}
|
2019-05-24 11:52:13 -05:00
|
|
|
for (;;);
|
|
|
|
}
|