refactor: clean up the virtual memory mappings
[lunaix-os.git] / lunaix-os / includes / lunaix / fs.h
1 #ifndef __LUNAIX_VFS_H
2 #define __LUNAIX_VFS_H
3
4 #include <lunaix/clock.h>
5 #include <lunaix/device.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/ds/lru.h>
11 #include <lunaix/ds/mutex.h>
12 #include <lunaix/process.h>
13 #include <lunaix/status.h>
14 #include <stdatomic.h>
15
16 #define VFS_NAME_MAXLEN 128
17 #define VFS_MAX_FD 32
18
19 #define VFS_IFDIR 0x1
20 #define VFS_IFFILE 0x2
21 #define VFS_IFSEQDEV 0x4
22 #define VFS_IFVOLDEV 0x8
23 #define VFS_IFSYMLINK 0x16
24
25 #define VFS_WALK_MKPARENT 0x1
26 #define VFS_WALK_FSRELATIVE 0x2
27 #define VFS_WALK_PARENT 0x4
28 #define VFS_WALK_NOFOLLOW 0x8
29
30 #define VFS_HASHTABLE_BITS 10
31 #define VFS_HASHTABLE_SIZE (1 << VFS_HASHTABLE_BITS)
32 #define VFS_HASH_MASK (VFS_HASHTABLE_SIZE - 1)
33 #define VFS_HASHBITS (32 - VFS_HASHTABLE_BITS)
34
35 #define VFS_PATH_DELIM '/'
36
37 #define FSTYPE_ROFS 0x1
38
39 #define DO_STATUS(errno) SYSCALL_ESTATUS(__current->k_status = errno)
40 #define DO_STATUS_OR_RETURN(errno) ({ errno < 0 ? DO_STATUS(errno) : errno; })
41
42 #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD)
43
44 #define VFS_VALID_CHAR(chr)                                                    \
45     (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') ||       \
46      ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' ||         \
47      (chr) == '-' || (chr) == ':')
48
49 #define unlock_inode(inode) mutex_unlock(&inode->lock)
50 #define lock_inode(inode)                                                      \
51     ({                                                                         \
52         mutex_lock(&inode->lock);                                              \
53         lru_use_one(inode_lru, &inode->lru);                                   \
54     })
55
56 #define unlock_dnode(dnode) mutex_unlock(&dnode->lock)
57 #define lock_dnode(dnode)                                                      \
58     ({                                                                         \
59         mutex_lock(&dnode->lock);                                              \
60         lru_use_one(dnode_lru, &dnode->lru);                                   \
61     })
62
63 typedef uint32_t inode_t;
64
65 struct v_dnode;
66 struct v_inode;
67 struct v_superblock;
68 struct v_file;
69 struct v_file_ops;
70 struct v_inode_ops;
71 struct v_fd;
72 struct pcache;
73 struct v_xattr_entry;
74
75 extern struct v_file_ops default_file_ops;
76 extern struct v_inode_ops default_inode_ops;
77
78 extern struct hstr vfs_ddot;
79 extern struct hstr vfs_dot;
80 extern struct v_dnode* vfs_sysroot;
81
82 struct filesystem
83 {
84     struct hlist_node fs_list;
85     struct hstr fs_name;
86     uint32_t types;
87     int fs_id;
88     int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
89     int (*unmount)(struct v_superblock* vsb);
90 };
91
92 struct v_superblock
93 {
94     struct llist_header sb_list;
95     struct device* dev;
96     struct v_dnode* root;
97     struct filesystem* fs;
98     uint32_t iobuf_size;
99     struct hbucket* i_cache;
100     struct
101     {
102         uint32_t (*read_capacity)(struct v_superblock* vsb);
103         uint32_t (*read_usage)(struct v_superblock* vsb);
104         void (*init_inode)(struct v_superblock* vsb, struct v_inode* inode);
105     } ops;
106 };
107
108 struct dir_context
109 {
110     int index;
111     void* cb_data;
112     void (*read_complete_callback)(struct dir_context* dctx,
113                                    const char* name,
114                                    const int len,
115                                    const int dtype);
116 };
117
118 struct v_file_ops
119 {
120     int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
121     int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
122     int (*readdir)(struct v_file* file, struct dir_context* dctx);
123     int (*seek)(struct v_inode* inode, size_t offset); // optional
124     int (*close)(struct v_file* file);
125     int (*sync)(struct v_file* file);
126 };
127
128 struct v_inode_ops
129 {
130     int (*create)(struct v_inode* this, struct v_dnode* dnode);
131     int (*open)(struct v_inode* this, struct v_file* file);
132     int (*sync)(struct v_inode* this);
133     int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
134     int (*rmdir)(struct v_inode* this, struct v_dnode* dir);
135     int (*unlink)(struct v_inode* this);
136     int (*link)(struct v_inode* this, struct v_dnode* new_name);
137     int (*read_symlink)(struct v_inode* this, const char** path_out);
138     int (*set_symlink)(struct v_inode* this, const char* target);
139     int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
140     int (*rename)(struct v_inode* from_inode,
141                   struct v_dnode* from_dnode,
142                   struct v_dnode* to_dnode);
143     int (*getxattr)(struct v_inode* this,
144                     struct v_xattr_entry* entry); // optional
145     int (*setxattr)(struct v_inode* this,
146                     struct v_xattr_entry* entry); // optional
147     int (*delxattr)(struct v_inode* this,
148                     struct v_xattr_entry* entry); // optional
149 };
150
151 struct v_xattr_entry
152 {
153     struct llist_header entries;
154     struct hstr name;
155     const void* value;
156     size_t len;
157 };
158
159 struct v_file
160 {
161     struct v_inode* inode;
162     struct v_dnode* dnode;
163     struct llist_header* f_list;
164     uint32_t f_pos;
165     atomic_ulong ref_count;
166     struct v_file_ops* ops; // for caching
167 };
168
169 struct v_fd
170 {
171     struct v_file* file;
172     int flags;
173 };
174
175 struct v_inode
176 {
177     inode_t id;
178     mutex_t lock;
179     uint32_t itype;
180     time_t ctime;
181     time_t mtime;
182     time_t atime;
183     lba_t lb_addr;
184     uint32_t open_count;
185     uint32_t link_count;
186     uint32_t lb_usage;
187     uint32_t fsize;
188     struct llist_header xattrs;
189     struct v_superblock* sb;
190     struct hlist_node hash_list;
191     struct lru_node lru;
192     struct pcache* pg_cache;
193     void* data; // 允许底层FS绑定他的一些专有数据
194     struct v_inode_ops* ops;
195     struct v_file_ops* default_fops;
196 };
197
198 struct v_mount
199 {
200     mutex_t lock;
201     struct llist_header list;
202     struct llist_header submnts;
203     struct llist_header sibmnts;
204     struct v_mount* parent;
205     struct v_dnode* mnt_point;
206     struct v_superblock* super_block;
207     uint32_t busy_counter;
208     int flags;
209 };
210
211 struct v_dnode
212 {
213     mutex_t lock; // sync the path walking
214     struct lru_node lru;
215     struct hstr name;
216     struct v_inode* inode;
217     struct v_dnode* parent;
218     struct hlist_node hash_list;
219     struct llist_header children;
220     struct llist_header siblings;
221     struct v_superblock* super_block;
222     struct v_mount* mnt;
223     atomic_ulong ref_count;
224
225     void* data;
226 };
227
228 struct v_fdtable
229 {
230     struct v_fd* fds[VFS_MAX_FD];
231 };
232
233 struct pcache
234 {
235     struct v_inode* master;
236     struct btrie tree;
237     struct llist_header pages;
238     struct llist_header dirty;
239     uint32_t n_dirty;
240     uint32_t n_pages;
241 };
242
243 struct pcache_pg
244 {
245     struct llist_header pg_list;
246     struct llist_header dirty_list;
247     struct lru_node lru;
248     struct pcache* holder;
249     void* pg;
250     uint32_t flags;
251     uint32_t fpos;
252 };
253 /* --- file system manager --- */
254 void
255 fsm_init();
256
257 void
258 fsm_register_all();
259
260 struct filesystem*
261 fsm_new_fs(char* name, size_t name_len);
262
263 void
264 fsm_register(struct filesystem* fs);
265
266 struct filesystem*
267 fsm_get(const char* fs_name);
268
269 void
270 vfs_init();
271
272 struct v_dnode*
273 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
274
275 void
276 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
277
278 void
279 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
280
281 void
282 vfs_dcache_remove(struct v_dnode* dnode);
283
284 int
285 vfs_walk(struct v_dnode* start,
286          const char* path,
287          struct v_dnode** dentry,
288          struct hstr* component,
289          int walk_options);
290
291 int
292 vfs_walk_proc(const char* path,
293               struct v_dnode** dentry,
294               struct hstr* component,
295               int options);
296
297 int
298 vfs_mount(const char* target,
299           const char* fs_name,
300           struct device* device,
301           int options);
302
303 int
304 vfs_unmount(const char* target);
305
306 int
307 vfs_mount_at(const char* fs_name,
308              struct device* device,
309              struct v_dnode* mnt_point,
310              int options);
311
312 int
313 vfs_unmount_at(struct v_dnode* mnt_point);
314
315 int
316 vfs_mkdir(const char* path, struct v_dnode** dentry);
317
318 int
319 vfs_open(struct v_dnode* dnode, struct v_file** file);
320
321 int
322 vfs_close(struct v_file* file);
323
324 int
325 vfs_fsync(struct v_file* file);
326
327 void
328 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
329
330 struct v_superblock*
331 vfs_sb_alloc();
332
333 void
334 vfs_sb_free(struct v_superblock* sb);
335
336 struct v_dnode*
337 vfs_d_alloc();
338
339 void
340 vfs_d_free(struct v_dnode* dnode);
341
342 struct v_inode*
343 vfs_i_find(struct v_superblock* sb, uint32_t i_id);
344
345 void
346 vfs_i_addhash(struct v_inode* inode);
347
348 struct v_inode*
349 vfs_i_alloc(struct v_superblock* sb);
350
351 void
352 vfs_i_free(struct v_inode* inode);
353
354 int
355 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
356
357 int
358 vfs_getfd(int fd, struct v_fd** fd_s);
359
360 void
361 pcache_init(struct pcache* pcache);
362
363 void
364 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
365
366 struct pcache_pg*
367 pcache_new_page(struct pcache* pcache, uint32_t index);
368
369 void
370 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
371
372 int
373 pcache_get_page(struct pcache* pcache,
374                 uint32_t index,
375                 uint32_t* offset,
376                 struct pcache_pg** page);
377
378 int
379 pcache_write(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
380
381 int
382 pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
383
384 void
385 pcache_release(struct pcache* pcache);
386
387 int
388 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
389
390 void
391 pcache_commit_all(struct v_inode* inode);
392
393 void
394 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
395
396 /**
397  * @brief 将挂载点标记为繁忙
398  *
399  * @param mnt
400  */
401 void
402 mnt_mkbusy(struct v_mount* mnt);
403
404 /**
405  * @brief 将挂载点标记为清闲
406  *
407  * @param mnt
408  */
409 void
410 mnt_chillax(struct v_mount* mnt);
411
412 int
413 vfs_mount_root(const char* fs_name, struct device* device);
414
415 struct v_mount*
416 vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point);
417
418 int
419 vfs_check_writable(struct v_dnode* dnode);
420
421 int
422 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
423
424 int
425 default_file_write(struct v_inode* inode,
426                    void* buffer,
427                    size_t len,
428                    size_t fpos);
429
430 int
431 default_file_readdir(struct v_file* file, struct dir_context* dctx);
432
433 int
434 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
435
436 int
437 default_inode_rename(struct v_inode* from_inode,
438                      struct v_dnode* from_dnode,
439                      struct v_dnode* to_dnode);
440
441 int
442 default_file_close(struct v_file* file);
443
444 int
445 default_file_seek(struct v_inode* inode, size_t offset);
446
447 int
448 default_inode_open(struct v_inode* this, struct v_file* file);
449
450 int
451 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
452
453 int
454 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
455
456 struct v_xattr_entry*
457 xattr_new(struct hstr* name);
458
459 struct v_xattr_entry*
460 xattr_getcache(struct v_inode* inode, struct hstr* name);
461
462 void
463 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
464
465 #endif /* __LUNAIX_VFS_H */