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>
18 #include <usr/lunaix/fstypes.h>
20 #define VFS_NAME_MAXLEN 128
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
30 // Walk, mkdir if component encountered is non-exists.
31 #define VFS_WALK_MKPARENT 0x1
33 // Walk, relative to current FS.
34 #define VFS_WALK_FSRELATIVE 0x2
37 Terminate the walk on the immediate parent,
38 name of child (last component) is returned through `component`
40 #define VFS_WALK_PARENT 0x4
42 // Do not follow the symbolic link
43 #define VFS_WALK_NOFOLLOW 0x8
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)
50 #define VFS_PATH_DELIM '/'
52 #define FSTYPE_ROFS 0b00000001
53 #define FSTYPE_PSEUDO 0x00000010
55 #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD)
57 #define EXPORT_FILE_SYSTEM(fs_id, init_fn) \
58 export_ldga_el(fs, fs_id, ptr_t, init_fn)
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) == ':')
65 #define unlock_inode(inode) mutex_unlock(&inode->lock)
66 #define lock_inode(inode) \
68 mutex_lock(&inode->lock); \
69 lru_use_one(inode_lru, &inode->lru); \
72 #define unlock_dnode(dnode) mutex_unlock(&dnode->lock)
73 #define lock_dnode(dnode) \
75 mutex_lock(&dnode->lock); \
76 lru_use_one(dnode_lru, &dnode->lru); \
79 #define assert_fs(cond) assert_p(cond, "FS")
80 #define fail_fs(msg) fail_p(msg, "FS")
82 typedef u32_t inode_t;
94 extern struct v_file_ops default_file_ops;
95 extern struct v_inode_ops default_inode_ops;
97 extern struct hstr vfs_ddot;
98 extern struct hstr vfs_dot;
99 extern struct v_dnode* vfs_sysroot;
101 typedef int (*mntops_mnt)(struct v_superblock* vsb, struct v_dnode* mount_point);
102 typedef int (*mntops_umnt)(struct v_superblock* vsb);
106 struct llist_header fs_flat;
107 struct hlist_node fs_list;
117 struct filesystem* fs;
122 struct llist_header sb_list;
124 struct v_dnode* root;
125 struct filesystem* fs;
126 struct blkbuf_cache* blks;
127 struct hbucket* i_cache;
128 struct hbucket* d_cache;
131 unsigned int ref_count;
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);
145 void (*read_complete_callback)(struct dir_context* dctx,
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);
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.
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);
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);
173 int (*create)(struct v_inode* this, struct v_dnode* dnode,
176 int (*open)(struct v_inode* this, struct v_file* file);
177 int (*sync)(struct v_inode* this);
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);
184 int (*read_symlink)(struct v_inode* this, const char** path_out);
185 int (*set_symlink)(struct v_inode* this, const char* target);
187 int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
189 int (*rename)(struct v_inode* from_inode,
190 struct v_dnode* from_dnode,
191 struct v_dnode* to_dnode);
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
203 struct llist_header entries;
211 struct v_inode* inode;
212 struct v_dnode* dnode;
213 struct llist_header* f_list;
215 unsigned long ref_count;
217 struct v_file_ops* ops; // for caching
226 // [v_inode::aka_nodes]
227 // how do we invalidate corresponding v_dnodes given the v_inode?
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
235 And this is also the case of all ramfs where argumentation to file tree is
236 performed by third party.
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;
263 struct pcache* pg_cache;
264 struct v_inode_ops* ops;
265 struct v_file_ops* default_fops;
267 void (*destruct)(struct v_inode* inode);
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;
285 mutex_t lock; // sync the path walking
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;
295 struct v_superblock* super_block;
298 unsigned long ref_count;
302 void (*destruct)(struct v_dnode* dnode);
307 struct v_fd* fds[VFS_MAX_FD];
312 struct v_inode* master;
314 struct llist_header dirty;
321 struct llist_header dirty_list;
335 check_itype_any(struct v_inode* inode, unsigned int type_mask)
337 return !!(inode->itype & type_mask) || !type_mask;
347 fsm_new_fs(char* name, size_t name_len);
350 fsm_register(struct filesystem* fs);
353 fsm_get(const char* fs_name);
356 fsm_itbegin(struct fs_iter* iterator);
359 fsm_itnext(struct fs_iter* iterator);
362 fsm_itend(struct fs_iter* iterator)
371 vfs_export_attributes();
374 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
377 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
380 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
383 vfs_dcache_remove(struct v_dnode* dnode);
386 vfs_walk(struct v_dnode* start,
388 struct v_dnode** dentry,
389 struct hstr* component,
393 vfs_walk_proc(const char* path,
394 struct v_dnode** dentry,
395 struct hstr* component,
399 vfs_walkat(int fd, const char* path, int at_opts,
400 struct v_dnode** dnode_out);
403 vfs_mount(const char* target,
405 struct device* device,
409 vfs_unmount(const char* target);
412 vfs_mount_at(const char* fs_name,
413 struct device* device,
414 struct v_dnode* mnt_point,
418 vfs_unmount_at(struct v_dnode* mnt_point);
421 vfs_mkdir(const char* path, struct v_dnode** dentry);
424 vfs_open(struct v_dnode* dnode, struct v_file** file);
427 vfs_pclose(struct v_file* file, pid_t pid);
430 vfs_close(struct v_file* file);
433 vfs_free_fd(struct v_fd* fd);
436 vfs_fsync(struct v_file* file);
439 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
445 vfs_sb_unref(struct v_superblock* sb);
448 vfs_sb_ref(struct v_superblock* sb);
450 #define vfs_assign_sb(sb_accessor, sb) \
452 if (likely(sb_accessor)) { \
453 vfs_sb_unref(sb_accessor); \
455 vfs_sb_ref(((sb_accessor) = (sb))); \
459 vfs_i_assign_sb(struct v_inode* inode, struct v_superblock* sb)
461 vfs_assign_sb(inode->sb, sb);
465 vfs_d_assign_sb(struct v_dnode* dnode, struct v_superblock* sb)
467 vfs_assign_sb(dnode->super_block, sb);
471 vfs_d_assign_vmnt(struct v_dnode* dnode, struct v_mount* vmnt)
474 assert_msg(dnode->mnt->mnt_point != dnode,
475 "vmnt must be detached first");
481 vfs_d_assign_sb(dnode, vmnt->super_block);
485 vfs_vmnt_assign_sb(struct v_mount* vmnt, struct v_superblock* sb)
487 vfs_assign_sb(vmnt->super_block, sb);
491 vfs_d_alloc(struct v_dnode* parent, struct hstr* name);
494 vfs_d_free(struct v_dnode* dnode);
497 vfs_i_find(struct v_superblock* sb, u32_t i_id);
500 vfs_i_addhash(struct v_inode* inode);
503 vfs_i_alloc(struct v_superblock* sb);
506 vfs_i_free(struct v_inode* inode);
509 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
512 vfs_getfd(int fd, struct v_fd** fd_s);
515 vfs_get_dtype(int itype);
518 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
521 pcache_init(struct pcache* pcache);
524 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
527 pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
530 pcache_release(struct pcache* pcache);
533 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
536 pcache_commit_all(struct v_inode* inode);
539 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
547 mnt_mkbusy(struct v_mount* mnt);
555 mnt_chillax(struct v_mount* mnt);
558 vfs_mount_root(const char* fs_name, struct device* device);
561 mnt_check_busy(struct v_mount* mnt)
563 return mnt->busy_counter > 1;
567 vfs_ref_dnode(struct v_dnode* dnode)
571 if (likely(dnode->mnt)) {
572 mnt_mkbusy(dnode->mnt);
577 vfs_unref_dnode(struct v_dnode* dnode)
581 if (likely(dnode->mnt)) {
582 mnt_chillax(dnode->mnt);
587 vfs_ref_file(struct v_file* file)
593 vfs_unref_file(struct v_file* file)
599 vfs_check_duped_file(struct v_file* file)
601 return file->ref_count > 1;
605 vfs_check_writable(struct v_dnode* dnode);
608 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
611 default_file_write(struct v_inode* inode,
617 default_file_read_page(struct v_inode* inode, void* buffer, size_t fpos);
620 default_file_write_page(struct v_inode* inode, void* buffer, size_t fpos);
623 default_file_readdir(struct v_file* file, struct dir_context* dctx);
626 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
629 default_inode_rename(struct v_inode* from_inode,
630 struct v_dnode* from_dnode,
631 struct v_dnode* to_dnode);
634 default_file_close(struct v_file* file);
637 default_file_seek(struct v_file* file, size_t offset);
640 default_inode_open(struct v_inode* this, struct v_file* file);
643 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
646 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
648 struct v_xattr_entry*
649 xattr_new(struct hstr* name);
651 struct v_xattr_entry*
652 xattr_getcache(struct v_inode* inode, struct hstr* name);
655 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
658 /* --- misc stuff --- */
660 #define check_itype(to_check, itype) \
661 (((to_check) & (itype)) == (itype))
664 * @brief Check if node represent a regular file (nothing but a file)
671 check_regfile_node(struct v_inode* inode)
673 return inode->itype == VFS_IFFILE;
677 * @brief Check if node represent a file.
678 * This is basically everything within file system (dir, dev, etc.)
685 check_file_node(struct v_inode* inode)
687 return check_itype(inode->itype, VFS_IFFILE);
691 check_directory_node(struct v_inode* inode)
693 return check_itype(inode->itype, VFS_IFDIR);
697 check_device_node(struct v_inode* inode)
699 return check_itype(inode->itype, VFS_IFDEV);
703 check_seqdev_node(struct v_inode* inode)
705 return check_device_node(inode);
709 check_voldev_node(struct v_inode* inode)
711 return check_itype(inode->itype, VFS_IFVOLDEV);
715 check_symlink_node(struct v_inode* inode)
717 return check_itype(inode->itype, VFS_IFSYMLINK);
721 check_allow_ops(struct v_inode* inode, unsigned int perm)
723 return fsacl_allow_ops(perm, inode->acl, inode->uid, inode->gid);
727 check_allow_read(struct v_inode* inode)
729 return check_allow_ops(inode, FSACL_aR);
733 check_allow_write(struct v_inode* inode)
735 return check_allow_ops(inode, FSACL_aW);
739 check_allow_execute(struct v_inode* inode)
741 return check_allow_ops(inode, FSACL_aX);
744 #endif /* __LUNAIX_VFS_H */