summaryrefslogtreecommitdiff
path: root/fs/mount.c
blob: 62cfe9f456cd38260271e2debe501265b8ef8a08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stddef.h>

#include "kernel.h"
#include "mount.h"

#include "log.h"

#include "lib/string/string.h"

#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 "SYSFS";
    }
    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 at %s",mount_type_to_str(mnt.type),mnt.path);
}

void mount_sysfs(ringbuffer *r, void (*f)(ringbuffer *r,char *fmt, ...))
{
    for(int i=0;i<mounts_count;i++)
    {
	mount *m=&mounts[i];
	f(r,"%s 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!");

    // start with root as default
    uint32_t best=0;
    uint32_t best_len=1;
    
    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;
	}
    }

    *mnt=mounts[best];
    return path+best_len-1;
}

fd mount_file_open(char *path)
{
    mount m;
    char *p=get_mount_for_path(path,&m);
    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);
}