feat: page caching layer for vfs
[lunaix-os.git] / lunaix-os / includes / lunaix / fs.h
1 #ifndef __LUNAIX_VFS_H
2 #define __LUNAIX_VFS_H
3
4 #include <hal/ahci/hba.h>
5 #include <lunaix/block.h>
6 #include <lunaix/ds/btrie.h>
7 #include <lunaix/ds/hashtable.h>
8 #include <lunaix/ds/hstr.h>
9 #include <lunaix/ds/llist.h>
10 #include <lunaix/status.h>
11
12 #define VFS_NAME_MAXLEN 128
13 #define VFS_MAX_FD 32
14
15 #define VFS_INODE_TYPE_DIR 0x1
16 #define VFS_INODE_TYPE_FILE 0x2
17 #define VFS_INODE_TYPE_DEVICE 0x4
18 #define VFS_INODE_TYPE_SYMLINK 0x8
19
20 #define VFS_WALK_MKPARENT 0x1
21 #define VFS_WALK_FSRELATIVE 0x2
22 #define VFS_WALK_PARENT 0x4
23 #define VFS_WALK_NOFOLLOW 0x4
24
25 #define FSTYPE_ROFS 0x1
26
27 #define VFS_VALID_CHAR(chr)                                                    \
28     ('A' <= (chr) && (chr) <= 'Z' || 'a' <= (chr) && (chr) <= 'z' ||           \
29      '0' <= (chr) && (chr) <= '9' || (chr) == '.' || (chr) == '_' ||           \
30      (chr) == '-')
31
32 extern struct hstr vfs_ddot;
33 extern struct hstr vfs_dot;
34
35 struct v_dnode;
36 struct pcache;
37
38 struct filesystem
39 {
40     struct hlist_node fs_list;
41     struct hstr fs_name;
42     uint32_t types;
43     int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
44     int (*unmount)(struct v_superblock* vsb);
45 };
46
47 struct v_superblock
48 {
49     struct llist_header sb_list;
50     int fs_id;
51     bdev_t dev;
52     struct v_dnode* root;
53     struct filesystem* fs;
54     uint32_t iobuf_size;
55     struct
56     {
57         uint32_t (*read_capacity)(struct v_superblock* vsb);
58         uint32_t (*read_usage)(struct v_superblock* vsb);
59     } ops;
60 };
61
62 struct dir_context
63 {
64     int index;
65     void* cb_data;
66     void (*read_complete_callback)(struct dir_context* dctx,
67                                    const char* name,
68                                    const int len,
69                                    const int dtype);
70 };
71
72 struct v_file_ops
73 {
74     int (*write)(struct v_file* file, void* buffer, size_t len, size_t fpos);
75     int (*read)(struct v_file* file, void* buffer, size_t len, size_t fpos);
76     int (*readdir)(struct v_file* file, struct dir_context* dctx);
77     int (*seek)(struct v_file* file, size_t offset);
78     int (*rename)(struct v_file* file, char* new_name);
79     int (*close)(struct v_file* file);
80     int (*sync)(struct v_file* file);
81 };
82
83 struct v_file
84 {
85     struct v_inode* inode;
86     struct v_dnode* dnode;
87     struct llist_header* f_list;
88     uint32_t f_pos;
89     uint32_t ref_count;
90     void* data; // 允许底层FS绑定他的一些专有数据
91     struct v_file_ops ops;
92 };
93
94 struct v_fd
95 {
96     struct v_file* file;
97     int flags;
98 };
99
100 struct v_inode
101 {
102     uint32_t itype;
103     uint32_t ctime;
104     uint32_t mtime;
105     uint64_t lb_addr;
106     uint32_t open_count;
107     uint32_t link_count;
108     uint32_t lb_usage;
109     uint32_t fsize;
110     struct pcache* pg_cache;
111     void* data; // 允许底层FS绑定他的一些专有数据
112     struct
113     {
114         int (*create)(struct v_inode* this);
115         int (*open)(struct v_inode* this, struct v_file* file);
116         int (*sync)(struct v_inode* this);
117         int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
118         int (*rmdir)(struct v_inode* this);
119         int (*unlink)(struct v_inode* this);
120         int (*link)(struct v_inode* this, struct v_dnode* new_name);
121         int (*read_symlink)(struct v_inode* this, const char** path_out);
122         int (*symlink)(struct v_inode* this, const char* target);
123         int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
124     } ops;
125 };
126
127 struct v_dnode
128 {
129     struct hstr name;
130     struct v_inode* inode;
131     struct v_dnode* parent;
132     struct hlist_node hash_list;
133     struct llist_header children;
134     struct llist_header siblings;
135     struct v_superblock* super_block;
136     struct
137     {
138         void (*destruct)(struct v_dnode* dnode);
139     } ops;
140 };
141
142 struct v_fdtable
143 {
144     struct v_fd* fds[VFS_MAX_FD];
145 };
146
147 struct pcache_pg
148 {
149     struct llist_header pg_list;
150     struct llist_header dirty_list;
151     void* pg;
152     uint32_t flags;
153     uint32_t fpos;
154 };
155
156 struct pcache
157 {
158     struct btrie tree;
159     struct llist_header pages;
160     struct llist_header dirty;
161     uint32_t n_dirty;
162     uint32_t n_pages;
163 };
164
165 /* --- file system manager --- */
166 void
167 fsm_init();
168
169 void
170 fsm_register(struct filesystem* fs);
171
172 struct filesystem*
173 fsm_get(const char* fs_name);
174
175 void
176 vfs_init();
177
178 struct v_dnode*
179 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
180
181 void
182 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
183
184 int
185 vfs_walk(struct v_dnode* start,
186          const char* path,
187          struct v_dnode** dentry,
188          struct hstr* component,
189          int walk_options);
190
191 int
192 vfs_mount(const char* target, const char* fs_name, bdev_t device);
193
194 int
195 vfs_unmount(const char* target);
196
197 int
198 vfs_mount_at(const char* fs_name, bdev_t device, struct v_dnode* mnt_point);
199
200 int
201 vfs_unmount_at(struct v_dnode* mnt_point);
202
203 int
204 vfs_mkdir(const char* path, struct v_dnode** dentry);
205
206 int
207 vfs_open(struct v_dnode* dnode, struct v_file** file);
208
209 int
210 vfs_close(struct v_file* file);
211
212 int
213 vfs_fsync(struct v_file* file);
214
215 struct v_superblock*
216 vfs_sb_alloc();
217
218 void
219 vfs_sb_free(struct v_superblock* sb);
220
221 struct v_dnode*
222 vfs_d_alloc();
223
224 void
225 vfs_d_free(struct v_dnode* dnode);
226
227 struct v_inode*
228 vfs_i_alloc();
229
230 void
231 vfs_i_free(struct v_inode* inode);
232
233 void
234 pcache_init(struct pcache* pcache);
235
236 void
237 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
238
239 struct pcache_pg*
240 pcache_new_page(struct pcache* pcache, uint32_t index);
241
242 void
243 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
244
245 struct pcache_pg*
246 pcache_get_page(struct pcache* pcache,
247                 uint32_t index,
248                 uint32_t* offset,
249                 struct pcache_pg** page);
250
251 int
252 pcache_write(struct v_file* file, void* data, uint32_t len);
253
254 int
255 pcache_read(struct v_file* file, void* data, uint32_t len);
256
257 void
258 pcache_release(struct pcache* pcache);
259
260 int
261 pcache_commit(struct v_file* file, struct pcache_pg* page);
262
263 void
264 pcache_invalidate(struct v_file* file, struct pcache_pg* page);
265
266 void
267 pcache_commit_all(struct v_file* file);
268 #endif /* __LUNAIX_VFS_H */