blob: 9c0ca9a56fc9f09f860d6948dc0d341bd89b8a24 [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{
swissChilia664e722021-07-27 17:47:55 -07009 if (node->mount)
10 node = node->mount;
11
swissChili8efa4922021-03-02 16:34:49 -080012 if (!node || !node->vtable || !node->vtable->read)
13 return 0;
14
15 return node->vtable->read(node, offset, size, buffer);
16}
17
18uint fs_write(struct fs_node *node, size_t offset, size_t size, uchar *buffer)
19{
swissChilia664e722021-07-27 17:47:55 -070020 if (node->mount)
21 node = node->mount;
22
swissChili8efa4922021-03-02 16:34:49 -080023 if (!node || !node->vtable || !node->vtable->write)
24 return 0;
25
26 return node->vtable->write(node, offset, size, buffer);
27}
28
29void fs_open(struct fs_node *node)
30{
swissChilia664e722021-07-27 17:47:55 -070031 if (node->mount)
32 node = node->mount;
33
swissChili8efa4922021-03-02 16:34:49 -080034 if (!node || !node->vtable || !node->vtable->open)
35 return;
36
37 node->vtable->open(node);
38}
39
40void fs_close(struct fs_node *node)
41{
swissChilia664e722021-07-27 17:47:55 -070042 if (node->mount)
43 node = node->mount;
44
swissChili8efa4922021-03-02 16:34:49 -080045 if (!node || !node->vtable || !node->vtable->close)
46 return;
47
48 node->vtable->close(node);
49}
50
swissChilib7fe8992021-03-10 16:25:47 -080051bool fs_readdir(struct fs_node *node, uint index, struct fs_dirent *out)
swissChili8efa4922021-03-02 16:34:49 -080052{
swissChilia664e722021-07-27 17:47:55 -070053 if (node->mount)
54 node = node->mount;
55
swissChilif5448622021-03-08 20:17:36 -080056 if (!node || !node->vtable || !node->vtable->readdir ||
57 (node->flags & 7) != FS_DIRECTORY)
swissChilib7fe8992021-03-10 16:25:47 -080058 return false;
swissChili8efa4922021-03-02 16:34:49 -080059
swissChilif5448622021-03-08 20:17:36 -080060 return node->vtable->readdir(node, index, out);
swissChili8efa4922021-03-02 16:34:49 -080061}
62
swissChili480f1762021-07-26 22:17:34 -070063struct fs_node *fs_finddir(struct fs_node *node, char *name, uint name_len)
swissChili8efa4922021-03-02 16:34:49 -080064{
swissChilia664e722021-07-27 17:47:55 -070065 if (node->mount)
66 node = node->mount;
67
swissChilif5448622021-03-08 20:17:36 -080068 if (!node || !node->vtable || !node->vtable->finddir ||
69 (node->flags & 7) != FS_DIRECTORY)
swissChilib7fe8992021-03-10 16:25:47 -080070 return NULL;
swissChili8efa4922021-03-02 16:34:49 -080071
swissChili480f1762021-07-26 22:17:34 -070072 return node->vtable->finddir(node, name, name_len);
swissChili8efa4922021-03-02 16:34:49 -080073}
swissChili6c0519e2021-03-07 19:40:23 -080074
swissChilib7fe8992021-03-10 16:25:47 -080075bool root_readdir(struct fs_node *node, uint index, struct fs_dirent *out)
swissChili6c0519e2021-03-07 19:40:23 -080076{
swissChilif5448622021-03-08 20:17:36 -080077 if (node == &root && index == 0)
78 {
79 // devfs
80 memcpy(out->name, "dev", 4);
81 out->inode = -1;
swissChili6c0519e2021-03-07 19:40:23 -080082
swissChilib7fe8992021-03-10 16:25:47 -080083 return true;
swissChilif5448622021-03-08 20:17:36 -080084 }
85 else
swissChilib7fe8992021-03-10 16:25:47 -080086 return false;
swissChilif5448622021-03-08 20:17:36 -080087}
88
swissChili480f1762021-07-26 22:17:34 -070089struct fs_node *root_finddir(struct fs_node *node, char *name, uint name_len)
swissChilif5448622021-03-08 20:17:36 -080090{
swissChili480f1762021-07-26 22:17:34 -070091 if (!strncmp(name, "dev", name_len))
swissChilif5448622021-03-08 20:17:36 -080092 {
swissChilib7fe8992021-03-10 16:25:47 -080093 return &dev;
swissChilif5448622021-03-08 20:17:36 -080094 }
swissChilib7fe8992021-03-10 16:25:47 -080095 else return NULL;
swissChilif5448622021-03-08 20:17:36 -080096}
97
swissChilib7fe8992021-03-10 16:25:47 -080098bool dev_readdir(struct fs_node *node, uint index, struct fs_dirent *out)
swissChilif5448622021-03-08 20:17:36 -080099{
100 if (node == &dev && index == 0)
101 {
102 // initrd
103 memcpy(out->name, "dirent", 7);
104 out->inode = -1;
swissChilib7fe8992021-03-10 16:25:47 -0800105 return true;
swissChilif5448622021-03-08 20:17:36 -0800106 }
107 else
swissChilib7fe8992021-03-10 16:25:47 -0800108 return false;
swissChilif5448622021-03-08 20:17:36 -0800109}
110
swissChili480f1762021-07-26 22:17:34 -0700111struct fs_node *dev_finddir(struct fs_node *node, char *name, uint name_len)
swissChilif5448622021-03-08 20:17:36 -0800112{
113 if (node != &dev)
swissChilib7fe8992021-03-10 16:25:47 -0800114 return NULL;
swissChilif5448622021-03-08 20:17:36 -0800115
swissChili480f1762021-07-26 22:17:34 -0700116 if (!strncmp(name, "initrd", MIN(name_len, FS_MAX_NAME_LEN)))
swissChilif5448622021-03-08 20:17:36 -0800117 {
swissChilib7fe8992021-03-10 16:25:47 -0800118 return &initrd;
swissChilif5448622021-03-08 20:17:36 -0800119 }
120
swissChilib7fe8992021-03-10 16:25:47 -0800121 return NULL;
swissChili6c0519e2021-03-07 19:40:23 -0800122}
123
swissChilia664e722021-07-27 17:47:55 -0700124static struct fs_vtable root_vt =
125{
126 NULL,
127};
128
swissChili6c0519e2021-03-07 19:40:23 -0800129void init_vfs()
130{
swissChilia664e722021-07-27 17:47:55 -0700131 root.mount = NULL;
132 root.inode = 0; // fake inode
swissChilif5448622021-03-08 20:17:36 -0800133 root.flags = FS_DIRECTORY;
swissChilia664e722021-07-27 17:47:55 -0700134 root.mask = ~0;
135 root.gid = root.uid = 0;
136 root.size = 0;
137 root.vtable = &root_vt;
swissChilif5448622021-03-08 20:17:36 -0800138}
139
140uint fs_mount(struct fs_node *target, struct fs_node *source)
141{
142 if (target->flags ^ FS_DIRECTORY)
143 return 1; // target is not a directory
144
145 if (target->flags & FS_MOUNT)
146 return 2; // already mounted
147
148 if (source->flags ^ FS_DIRECTORY)
149 return 3; // source is not a directory
150
151 target->flags |= FS_MOUNT;
152 target->mount = source;
153
154 return 0;
swissChili6c0519e2021-03-07 19:40:23 -0800155}