6feb2aa0447769b7f5d68fda278936774036d8a8
[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/ldga.h>
10 #include <lunaix/ds/llist.h>
11 #include <lunaix/ds/lru.h>
12 #include <lunaix/ds/mutex.h>
13 #include <lunaix/status.h>
14 #include <lunaix/spike.h>
15 #include <lunaix/bcache.h>
16
17 #include <usr/lunaix/fstypes.h>
18
19 #define VFS_NAME_MAXLEN 128
20 #define VFS_MAX_FD 32
21
22 #define VFS_IFFILE       F_FILE
23 #define VFS_IFDIR       (F_FILE | F_DIR    )
24 #define VFS_IFDEV       (F_FILE | F_DEV    )
25 #define VFS_IFSYMLINK   (F_FILE | F_SYMLINK)
26 #define VFS_IFVOLDEV    (F_FILE | F_SVDEV  )
27 #define VFS_IFSEQDEV    VFS_IFDEV
28
29 // Walk, mkdir if component encountered is non-exists.
30 #define VFS_WALK_MKPARENT 0x1
31
32 // Walk, relative to current FS.
33 #define VFS_WALK_FSRELATIVE 0x2
34
35 /*
36     Terminate the walk on the immediate parent,
37     name of child (last component) is returned through `component`
38 */
39 #define VFS_WALK_PARENT 0x4
40
41 // Do not follow the symbolic link
42 #define VFS_WALK_NOFOLLOW 0x8
43
44 #define VFS_HASHTABLE_BITS 10
45 #define VFS_HASHTABLE_SIZE (1 << VFS_HASHTABLE_BITS)
46 #define VFS_HASH_MASK (VFS_HASHTABLE_SIZE - 1)
47 #define VFS_HASHBITS (32 - VFS_HASHTABLE_BITS)
48
49 #define VFS_PATH_DELIM '/'
50
51 #define FSTYPE_ROFS     0b00000001
52 #define FSTYPE_PSEUDO   0x00000010
53
54 #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD)
55
56 #define EXPORT_FILE_SYSTEM(fs_id, init_fn)                                     \
57     export_ldga_el(fs, fs_id, ptr_t, init_fn)
58
59 #define VFS_VALID_CHAR(chr)                                                    \
60     (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') ||       \
61      ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' ||         \
62      (chr) == '-' || (chr) == ':')
63
64 #define unlock_inode(inode) mutex_unlock(&inode->lock)
65 #define lock_inode(inode)                                                      \
66     ({                                                                         \
67         mutex_lock(&inode->lock);                                              \
68         lru_use_one(inode_lru, &inode->lru);                                   \
69     })
70
71 #define unlock_dnode(dnode) mutex_unlock(&dnode->lock)
72 #define lock_dnode(dnode)                                                      \
73     ({                                                                         \
74         mutex_lock(&dnode->lock);                                              \
75         lru_use_one(dnode_lru, &dnode->lru);                                   \
76     })
77
78 #define assert_fs(cond) assert_p(cond, "FS")
79 #define fail_fs(msg) fail_p(msg, "FS")
80
81 typedef u32_t inode_t;
82
83 struct v_dnode;
84 struct v_inode;
85 struct v_superblock;
86 struct v_file;
87 struct v_file_ops;
88 struct v_inode_ops;
89 struct v_fd;
90 struct pcache;
91 struct v_xattr_entry;
92
93 extern struct v_file_ops default_file_ops;
94 extern struct v_inode_ops default_inode_ops;
95
96 extern struct hstr vfs_ddot;
97 extern struct hstr vfs_dot;
98 extern struct v_dnode* vfs_sysroot;
99
100 typedef int (*mntops_mnt)(struct v_superblock* vsb, struct v_dnode* mount_point);
101 typedef int (*mntops_umnt)(struct v_superblock* vsb);
102
103 struct filesystem
104 {
105     struct llist_header fs_flat;
106     struct hlist_node fs_list;
107     struct hstr fs_name;
108     u32_t types;
109     int fs_id;
110     mntops_mnt mount;
111     mntops_umnt unmount;
112 };
113
114 struct fs_iter
115 {
116     struct filesystem* fs;
117 };
118
119 struct v_superblock
120 {
121     struct llist_header sb_list;
122     struct device* dev;
123     struct v_dnode* root;
124     struct filesystem* fs;
125     struct blkbuf_cache* blks;
126     struct hbucket* i_cache;
127     struct hbucket* d_cache;
128     
129     void* data;
130     unsigned int ref_count;
131     size_t blksize;
132     struct
133     {
134         size_t (*read_capacity)(struct v_superblock* vsb);
135         size_t (*read_usage)(struct v_superblock* vsb);
136         void (*init_inode)(struct v_superblock* vsb, struct v_inode* inode);
137         void (*release)(struct v_superblock* vsb);
138     } ops;
139 };
140
141 struct dir_context
142 {
143     void* cb_data;
144     void (*read_complete_callback)(struct dir_context* dctx,
145                                    const char* name,
146                                    const int len,
147                                    const int dtype);
148 };
149
150 struct v_file_ops
151 {
152     int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
153     int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
154
155     // for operatiosn {write|read}_page, following are true:
156     //  + `len` always equals to PG_SIZE
157     //  + `fpos` always PG_SIZE aligned.
158     // These additional operations allow underlying fs to use more specialized
159     // and optimized code.
160
161     int (*write_page)(struct v_inode* inode, void* pg, size_t fpos);
162     int (*read_page)(struct v_inode* inode, void* pg, size_t fpos);
163
164     int (*readdir)(struct v_file* file, struct dir_context* dctx);
165     int (*seek)(struct v_file* file, size_t offset);
166     int (*close)(struct v_file* file);
167     int (*sync)(struct v_file* file);
168 };
169
170 struct v_inode_ops
171 {
172     int (*create)(struct v_inode* this, struct v_dnode* dnode, 
173                   unsigned int itype);
174     
175     int (*open)(struct v_inode* this, struct v_file* file);
176     int (*sync)(struct v_inode* this);
177
178     int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
179     int (*rmdir)(struct v_inode* this, struct v_dnode* dnode);
180     int (*unlink)(struct v_inode* this, struct v_dnode* name);
181     int (*link)(struct v_inode* this, struct v_dnode* new_name);
182
183     int (*read_symlink)(struct v_inode* this, const char** path_out);
184     int (*set_symlink)(struct v_inode* this, const char* target);
185     
186     int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
187
188     int (*rename)(struct v_inode* from_inode,
189                   struct v_dnode* from_dnode,
190                   struct v_dnode* to_dnode);
191
192     int (*getxattr)(struct v_inode* this,
193                     struct v_xattr_entry* entry); // optional
194     int (*setxattr)(struct v_inode* this,
195                     struct v_xattr_entry* entry); // optional
196     int (*delxattr)(struct v_inode* this,
197                     struct v_xattr_entry* entry); // optional
198 };
199
200 struct v_xattr_entry
201 {
202     struct llist_header entries;
203     struct hstr name;
204     const void* value;
205     size_t len;
206 };
207
208 struct v_file
209 {
210     struct v_inode* inode;
211     struct v_dnode* dnode;
212     struct llist_header* f_list;
213     u32_t f_pos;
214     unsigned long ref_count;
215     void* data;
216     struct v_file_ops* ops; // for caching
217 };
218
219 struct v_fd
220 {
221     struct v_file* file;
222     int flags;
223 };
224
225 //  [v_inode::aka_nodes]
226 //  how do we invalidate corresponding v_dnodes given the v_inode?
227 /*
228     Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow
229     info of every process being accessible via file system. Each process's
230     creation will result a creation of a directory under the root of task fs
231     with it's pid as name. But that dir must delete when process is killed, and
232     such deletion does not mediated by vfs itself, so there is a need of cache
233     syncing.
234     And this is also the case of all ramfs where argumentation to file tree is
235     performed by third party.
236 */
237
238 struct v_inode
239 {
240     inode_t id;
241     mutex_t lock;
242     u32_t itype;
243     time_t ctime;
244     time_t mtime;
245     time_t atime;
246     lba_t lb_addr;
247     u32_t open_count;
248     u32_t link_count;
249     u32_t lb_usage;
250     u32_t fsize;
251     void* data; // 允许底层FS绑定他的一些专有数据
252     struct llist_header aka_dnodes;
253     struct llist_header xattrs;
254     struct v_superblock* sb;
255     struct hlist_node hash_list;
256     struct lru_node lru;
257     struct pcache* pg_cache;
258     struct v_inode_ops* ops;
259     struct v_file_ops* default_fops;
260
261     void (*destruct)(struct v_inode* inode);
262 };
263
264 struct v_mount
265 {
266     mutex_t lock;
267     struct llist_header list;
268     struct llist_header submnts;
269     struct llist_header sibmnts;
270     struct v_mount* parent;
271     struct v_dnode* mnt_point;
272     struct v_superblock* super_block;
273     u32_t busy_counter;
274     int flags;
275 };
276
277 struct v_dnode
278 {
279     mutex_t lock; // sync the path walking
280     struct lru_node lru;
281     struct hstr name;
282     struct v_inode* inode;
283     struct v_dnode* parent;
284     struct hlist_node hash_list;
285     struct llist_header aka_list;
286     struct llist_header children;
287     struct llist_header siblings;
288     
289     struct v_superblock* super_block;
290     struct v_mount* mnt;
291     
292     unsigned long ref_count;
293
294     void* data;
295
296     void (*destruct)(struct v_dnode* dnode);
297 };
298
299 struct v_fdtable
300 {
301     struct v_fd* fds[VFS_MAX_FD];
302 };
303
304 struct pcache
305 {
306     struct v_inode* master;
307     struct bcache cache;
308     struct llist_header dirty;
309     u32_t n_dirty;
310     u32_t n_pages;
311 };
312
313 struct pcache_pg
314 {
315     struct llist_header dirty_list;
316
317     union {
318         struct {
319             bool dirty:1;
320         };
321         u32_t flags;
322     };
323
324     void* data;
325     unsigned int index;
326 };
327
328 static inline bool
329 check_itype_any(struct v_inode* inode, unsigned int type_mask)
330 {
331     return !!(inode->itype & type_mask) || !type_mask;
332 }
333
334 void
335 fsm_init();
336
337 void
338 fsm_register_all();
339
340 struct filesystem*
341 fsm_new_fs(char* name, size_t name_len);
342
343 void
344 fsm_register(struct filesystem* fs);
345
346 struct filesystem*
347 fsm_get(const char* fs_name);
348
349 void
350 fsm_itbegin(struct fs_iter* iterator);
351
352 bool
353 fsm_itnext(struct fs_iter* iterator);
354
355 static inline void
356 fsm_itend(struct fs_iter* iterator)
357 {
358     iterator->fs = NULL;
359 }
360
361 void
362 vfs_init();
363
364 void
365 vfs_export_attributes();
366
367 struct v_dnode*
368 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
369
370 void
371 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
372
373 void
374 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
375
376 void
377 vfs_dcache_remove(struct v_dnode* dnode);
378
379 int
380 vfs_walk(struct v_dnode* start,
381          const char* path,
382          struct v_dnode** dentry,
383          struct hstr* component,
384          int walk_options);
385
386 int
387 vfs_walk_proc(const char* path,
388               struct v_dnode** dentry,
389               struct hstr* component,
390               int options);
391
392 int
393 vfs_mount(const char* target,
394           const char* fs_name,
395           struct device* device,
396           int options);
397
398 int
399 vfs_unmount(const char* target);
400
401 int
402 vfs_mount_at(const char* fs_name,
403              struct device* device,
404              struct v_dnode* mnt_point,
405              int options);
406
407 int
408 vfs_unmount_at(struct v_dnode* mnt_point);
409
410 int
411 vfs_mkdir(const char* path, struct v_dnode** dentry);
412
413 int
414 vfs_open(struct v_dnode* dnode, struct v_file** file);
415
416 int
417 vfs_pclose(struct v_file* file, pid_t pid);
418
419 int
420 vfs_close(struct v_file* file);
421
422 void
423 vfs_free_fd(struct v_fd* fd);
424
425 int
426 vfs_fsync(struct v_file* file);
427
428 void
429 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
430
431 struct v_superblock*
432 vfs_sb_alloc();
433
434 void
435 vfs_sb_unref(struct v_superblock* sb);
436
437 void
438 vfs_sb_ref(struct v_superblock* sb);
439
440 #define vfs_assign_sb(sb_accessor, sb)      \
441     ({                                      \
442         if (likely(sb_accessor)) {          \
443             vfs_sb_unref(sb_accessor);       \
444         }                                   \
445         vfs_sb_ref(((sb_accessor) = (sb))); \
446     })
447
448 static inline void
449 vfs_i_assign_sb(struct v_inode* inode, struct v_superblock* sb)
450 {
451     vfs_assign_sb(inode->sb, sb);
452 }
453
454 static inline void
455 vfs_d_assign_sb(struct v_dnode* dnode, struct v_superblock* sb)
456 {
457     vfs_assign_sb(dnode->super_block, sb);
458 }
459
460 static inline void
461 vfs_d_assign_vmnt(struct v_dnode* dnode, struct v_mount* vmnt)
462 {
463     if (dnode->mnt) {
464         assert_msg(dnode->mnt->mnt_point != dnode, 
465                     "vmnt must be detached first");
466     }
467
468     dnode->mnt = vmnt;
469
470     if (likely(vmnt))
471         vfs_d_assign_sb(dnode, vmnt->super_block);
472 }
473
474 static inline void
475 vfs_vmnt_assign_sb(struct v_mount* vmnt, struct v_superblock* sb)
476 {
477     vfs_assign_sb(vmnt->super_block, sb);
478 }
479
480 struct v_dnode*
481 vfs_d_alloc(struct v_dnode* parent, struct hstr* name);
482
483 void
484 vfs_d_free(struct v_dnode* dnode);
485
486 struct v_inode*
487 vfs_i_find(struct v_superblock* sb, u32_t i_id);
488
489 void
490 vfs_i_addhash(struct v_inode* inode);
491
492 struct v_inode*
493 vfs_i_alloc(struct v_superblock* sb);
494
495 void
496 vfs_i_free(struct v_inode* inode);
497
498 int
499 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
500
501 int
502 vfs_getfd(int fd, struct v_fd** fd_s);
503
504 int
505 vfs_get_dtype(int itype);
506
507 int
508 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
509
510 void
511 pcache_init(struct pcache* pcache);
512
513 int
514 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
515
516 int
517 pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
518
519 void
520 pcache_release(struct pcache* pcache);
521
522 int
523 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
524
525 void
526 pcache_commit_all(struct v_inode* inode);
527
528 void
529 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
530
531 /**
532  * @brief 将挂载点标记为繁忙
533  *
534  * @param mnt
535  */
536 void
537 mnt_mkbusy(struct v_mount* mnt);
538
539 /**
540  * @brief 将挂载点标记为清闲
541  *
542  * @param mnt
543  */
544 void
545 mnt_chillax(struct v_mount* mnt);
546
547 int
548 vfs_mount_root(const char* fs_name, struct device* device);
549
550 static inline bool
551 mnt_check_busy(struct v_mount* mnt)
552 {
553     return mnt->busy_counter > 1;
554 }
555
556 static inline void
557 vfs_ref_dnode(struct v_dnode* dnode)
558 {
559     dnode->ref_count++;
560     
561     if (likely(dnode->mnt)) {
562         mnt_mkbusy(dnode->mnt);
563     }
564 }
565
566 static inline void
567 vfs_unref_dnode(struct v_dnode* dnode)
568 {
569     dnode->ref_count--;
570
571     if (likely(dnode->mnt)) {
572         mnt_chillax(dnode->mnt);
573     }
574 }
575
576 static inline void
577 vfs_ref_file(struct v_file* file)
578 {
579     file->ref_count++;
580 }
581
582 static inline void
583 vfs_unref_file(struct v_file* file)
584 {
585     file->ref_count--;
586 }
587
588 static inline bool
589 vfs_check_duped_file(struct v_file* file)
590 {
591     return file->ref_count > 1;
592 }
593
594 int
595 vfs_check_writable(struct v_dnode* dnode);
596
597 int
598 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
599
600 int
601 default_file_write(struct v_inode* inode,
602                    void* buffer,
603                    size_t len,
604                    size_t fpos);
605
606 int
607 default_file_read_page(struct v_inode* inode, void* buffer, size_t fpos);
608
609 int
610 default_file_write_page(struct v_inode* inode, void* buffer, size_t fpos);
611
612 int
613 default_file_readdir(struct v_file* file, struct dir_context* dctx);
614
615 int
616 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
617
618 int
619 default_inode_rename(struct v_inode* from_inode,
620                      struct v_dnode* from_dnode,
621                      struct v_dnode* to_dnode);
622
623 int
624 default_file_close(struct v_file* file);
625
626 int
627 default_file_seek(struct v_file* file, size_t offset);
628
629 int
630 default_inode_open(struct v_inode* this, struct v_file* file);
631
632 int
633 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
634
635 int
636 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
637
638 struct v_xattr_entry*
639 xattr_new(struct hstr* name);
640
641 struct v_xattr_entry*
642 xattr_getcache(struct v_inode* inode, struct hstr* name);
643
644 void
645 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
646
647
648 /* --- misc stuff --- */
649
650 #define check_itype(to_check, itype)    \
651     (((to_check) & (itype)) == (itype))
652
653 /**
654  * @brief Check if node represent a regular file (nothing but a file)
655  * 
656  * @param inode 
657  * @return true 
658  * @return false 
659  */
660 static inline bool
661 check_regfile_node(struct v_inode* inode)
662 {
663     return inode->itype == VFS_IFFILE;
664 }
665
666 /**
667  * @brief Check if node represent a file.
668  *        This is basically everything within file system (dir, dev, etc.)
669  * 
670  * @param inode 
671  * @return true 
672  * @return false 
673  */
674 static inline bool
675 check_file_node(struct v_inode* inode)
676 {
677     return check_itype(inode->itype, VFS_IFFILE);
678 }
679
680 static inline bool
681 check_directory_node(struct v_inode* inode)
682 {
683     return check_itype(inode->itype, VFS_IFDIR);
684 }
685
686 static inline bool
687 check_device_node(struct v_inode* inode)
688 {
689     return check_itype(inode->itype, VFS_IFDEV);
690 }
691
692 static inline bool
693 check_seqdev_node(struct v_inode* inode)
694 {
695     return check_device_node(inode);
696 }
697
698 static inline bool
699 check_voldev_node(struct v_inode* inode)
700 {
701     return check_itype(inode->itype, VFS_IFVOLDEV);
702 }
703
704 static inline bool
705 check_symlink_node(struct v_inode* inode)
706 {
707     return check_itype(inode->itype, VFS_IFSYMLINK);
708 }
709
710 #endif /* __LUNAIX_VFS_H */