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