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