blob: e3c06a015e55a525f9e4c83753ca8059b7852efc [file] [log] [blame]
swissChili8efa4922021-03-02 16:34:49 -08001#include "vfs.h"
swissChilif5448622021-03-08 20:17:36 -08002#include "io.h"
swissChili8efa4922021-03-02 16:34:49 -08003
swissChili6c0519e2021-03-07 19:40:23 -08004struct fs_node root, dev, initrd;
swissChilif5448622021-03-08 20:17:36 -08005struct fs_vtable root_v, dev_v;
swissChili6c0519e2021-03-07 19:40:23 -08006
swissChili8efa4922021-03-02 16:34:49 -08007uint fs_read(struct fs_node *node, size_t offset, size_t size, uchar *buffer)
8{
9 if (!node || !node->vtable || !node->vtable->read)
10 return 0;
11
12 return node->vtable->read(node, offset, size, buffer);
13}
14
15uint fs_write(struct fs_node *node, size_t offset, size_t size, uchar *buffer)
16{
17 if (!node || !node->vtable || !node->vtable->write)
18 return 0;
19
20 return node->vtable->write(node, offset, size, buffer);
21}
22
23void fs_open(struct fs_node *node)
24{
25 if (!node || !node->vtable || !node->vtable->open)
26 return;
27
28 node->vtable->open(node);
29}
30
31void fs_close(struct fs_node *node)
32{
33 if (!node || !node->vtable || !node->vtable->close)
34 return;
35
36 node->vtable->close(node);
37}
38
swissChilib7fe8992021-03-10 16:25:47 -080039bool fs_readdir(struct fs_node *node, uint index, struct fs_dirent *out)
swissChili8efa4922021-03-02 16:34:49 -080040{
swissChilif5448622021-03-08 20:17:36 -080041 if (!node || !node->vtable || !node->vtable->readdir ||
42 (node->flags & 7) != FS_DIRECTORY)
swissChilib7fe8992021-03-10 16:25:47 -080043 return false;
swissChili8efa4922021-03-02 16:34:49 -080044
swissChilif5448622021-03-08 20:17:36 -080045 return node->vtable->readdir(node, index, out);
swissChili8efa4922021-03-02 16:34:49 -080046}
47
swissChili480f1762021-07-26 22:17:34 -070048struct fs_node *fs_finddir(struct fs_node *node, char *name, uint name_len)
swissChili8efa4922021-03-02 16:34:49 -080049{
swissChilif5448622021-03-08 20:17:36 -080050 if (!node || !node->vtable || !node->vtable->finddir ||
51 (node->flags & 7) != FS_DIRECTORY)
swissChilib7fe8992021-03-10 16:25:47 -080052 return NULL;
swissChili8efa4922021-03-02 16:34:49 -080053
swissChili480f1762021-07-26 22:17:34 -070054 return node->vtable->finddir(node, name, name_len);
swissChili8efa4922021-03-02 16:34:49 -080055}
swissChili6c0519e2021-03-07 19:40:23 -080056
swissChilib7fe8992021-03-10 16:25:47 -080057bool root_readdir(struct fs_node *node, uint index, struct fs_dirent *out)
swissChili6c0519e2021-03-07 19:40:23 -080058{
swissChilif5448622021-03-08 20:17:36 -080059 if (node == &root && index == 0)
60 {
61 // devfs
62 memcpy(out->name, "dev", 4);
63 out->inode = -1;
swissChili6c0519e2021-03-07 19:40:23 -080064
swissChilib7fe8992021-03-10 16:25:47 -080065 return true;
swissChilif5448622021-03-08 20:17:36 -080066 }
67 else
swissChilib7fe8992021-03-10 16:25:47 -080068 return false;
swissChilif5448622021-03-08 20:17:36 -080069}
70
swissChili480f1762021-07-26 22:17:34 -070071struct fs_node *root_finddir(struct fs_node *node, char *name, uint name_len)
swissChilif5448622021-03-08 20:17:36 -080072{
swissChili480f1762021-07-26 22:17:34 -070073 if (!strncmp(name, "dev", name_len))
swissChilif5448622021-03-08 20:17:36 -080074 {
swissChilib7fe8992021-03-10 16:25:47 -080075 return &dev;
swissChilif5448622021-03-08 20:17:36 -080076 }
swissChilib7fe8992021-03-10 16:25:47 -080077 else return NULL;
swissChilif5448622021-03-08 20:17:36 -080078}
79
swissChilib7fe8992021-03-10 16:25:47 -080080bool dev_readdir(struct fs_node *node, uint index, struct fs_dirent *out)
swissChilif5448622021-03-08 20:17:36 -080081{
82 if (node == &dev && index == 0)
83 {
84 // initrd
85 memcpy(out->name, "dirent", 7);
86 out->inode = -1;
swissChilib7fe8992021-03-10 16:25:47 -080087 return true;
swissChilif5448622021-03-08 20:17:36 -080088 }
89 else
swissChilib7fe8992021-03-10 16:25:47 -080090 return false;
swissChilif5448622021-03-08 20:17:36 -080091}
92
swissChili480f1762021-07-26 22:17:34 -070093struct fs_node *dev_finddir(struct fs_node *node, char *name, uint name_len)
swissChilif5448622021-03-08 20:17:36 -080094{
95 if (node != &dev)
swissChilib7fe8992021-03-10 16:25:47 -080096 return NULL;
swissChilif5448622021-03-08 20:17:36 -080097
swissChili480f1762021-07-26 22:17:34 -070098 if (!strncmp(name, "initrd", MIN(name_len, FS_MAX_NAME_LEN)))
swissChilif5448622021-03-08 20:17:36 -080099 {
swissChilib7fe8992021-03-10 16:25:47 -0800100 return &initrd;
swissChilif5448622021-03-08 20:17:36 -0800101 }
102
swissChilib7fe8992021-03-10 16:25:47 -0800103 return NULL;
swissChili6c0519e2021-03-07 19:40:23 -0800104}
105
106void init_vfs()
107{
swissChilif5448622021-03-08 20:17:36 -0800108 memset(&root_v, 0, sizeof(root_v));
109 memset(&dev_v, 0, sizeof(root_v));
110 memset(&root, 0, sizeof(root));
111 memset(&dev, 0, sizeof(dev));
112
113 root.flags = FS_DIRECTORY;
114 root.vtable = &root_v;
115 dev.flags = FS_DIRECTORY;
116 dev.vtable = &dev_v;
117 initrd.flags = FS_DIRECTORY;
118
119 root_v.readdir = root_readdir;
120 root_v.finddir = root_finddir;
swissChilib7fe8992021-03-10 16:25:47 -0800121
122 dev_v.readdir = dev_readdir;
123 dev_v.finddir = dev_finddir;
swissChilif5448622021-03-08 20:17:36 -0800124}
125
126uint fs_mount(struct fs_node *target, struct fs_node *source)
127{
128 if (target->flags ^ FS_DIRECTORY)
129 return 1; // target is not a directory
130
131 if (target->flags & FS_MOUNT)
132 return 2; // already mounted
133
134 if (source->flags ^ FS_DIRECTORY)
135 return 3; // source is not a directory
136
137 target->flags |= FS_MOUNT;
138 target->mount = source;
139
140 return 0;
swissChili6c0519e2021-03-07 19:40:23 -0800141}