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>
17 #include <usr/lunaix/fstypes.h>
19 #define VFS_NAME_MAXLEN 128
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
29 // Walk, mkdir if component encountered is non-exists.
30 #define VFS_WALK_MKPARENT 0x1
32 // Walk, relative to current FS.
33 #define VFS_WALK_FSRELATIVE 0x2
36 Terminate the walk on the immediate parent,
37 name of child (last component) is returned through `component`
39 #define VFS_WALK_PARENT 0x4
41 // Do not follow the symbolic link
42 #define VFS_WALK_NOFOLLOW 0x8
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)
49 #define VFS_PATH_DELIM '/'
51 #define FSTYPE_ROFS 0b00000001
52 #define FSTYPE_PSEUDO 0x00000010
54 #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD)
56 #define EXPORT_FILE_SYSTEM(fs_id, init_fn) \
57 export_ldga_el(fs, fs_id, ptr_t, init_fn)
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) == ':')
64 #define unlock_inode(inode) mutex_unlock(&inode->lock)
65 #define lock_inode(inode) \
67 mutex_lock(&inode->lock); \
68 lru_use_one(inode_lru, &inode->lru); \
71 #define unlock_dnode(dnode) mutex_unlock(&dnode->lock)
72 #define lock_dnode(dnode) \
74 mutex_lock(&dnode->lock); \
75 lru_use_one(dnode_lru, &dnode->lru); \
78 #define assert_fs(cond) assert_p(cond, "FS")
79 #define fail_fs(msg) fail_p(msg, "FS")
81 typedef u32_t inode_t;
93 extern struct v_file_ops default_file_ops;
94 extern struct v_inode_ops default_inode_ops;
96 extern struct hstr vfs_ddot;
97 extern struct hstr vfs_dot;
98 extern struct v_dnode* vfs_sysroot;
100 typedef int (*mntops_mnt)(struct v_superblock* vsb, struct v_dnode* mount_point);
101 typedef int (*mntops_umnt)(struct v_superblock* vsb);
105 struct llist_header fs_flat;
106 struct hlist_node fs_list;
116 struct filesystem* fs;
121 struct llist_header sb_list;
123 struct v_dnode* root;
124 struct filesystem* fs;
125 struct blkbuf_cache* blks;
126 struct hbucket* i_cache;
127 struct hbucket* d_cache;
130 unsigned int ref_count;
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);
144 void (*read_complete_callback)(struct dir_context* dctx,
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);
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.
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);
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);
172 int (*create)(struct v_inode* this, struct v_dnode* dnode,
175 int (*open)(struct v_inode* this, struct v_file* file);
176 int (*sync)(struct v_inode* this);
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);
183 int (*read_symlink)(struct v_inode* this, const char** path_out);
184 int (*set_symlink)(struct v_inode* this, const char* target);
186 int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
188 int (*rename)(struct v_inode* from_inode,
189 struct v_dnode* from_dnode,
190 struct v_dnode* to_dnode);
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
202 struct llist_header entries;
210 struct v_inode* inode;
211 struct v_dnode* dnode;
212 struct llist_header* f_list;
214 unsigned long ref_count;
216 struct v_file_ops* ops; // for caching
225 // [v_inode::aka_nodes]
226 // how do we invalidate corresponding v_dnodes given the v_inode?
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
234 And this is also the case of all ramfs where argumentation to file tree is
235 performed by third party.
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;
257 struct pcache* pg_cache;
258 struct v_inode_ops* ops;
259 struct v_file_ops* default_fops;
261 void (*destruct)(struct v_inode* inode);
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;
279 mutex_t lock; // sync the path walking
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;
289 struct v_superblock* super_block;
292 unsigned long ref_count;
296 void (*destruct)(struct v_dnode* dnode);
301 struct v_fd* fds[VFS_MAX_FD];
306 struct v_inode* master;
308 struct llist_header dirty;
315 struct llist_header dirty_list;
329 check_itype_any(struct v_inode* inode, unsigned int type_mask)
331 return !!(inode->itype & type_mask) || !type_mask;
341 fsm_new_fs(char* name, size_t name_len);
344 fsm_register(struct filesystem* fs);
347 fsm_get(const char* fs_name);
350 fsm_itbegin(struct fs_iter* iterator);
353 fsm_itnext(struct fs_iter* iterator);
356 fsm_itend(struct fs_iter* iterator)
365 vfs_export_attributes();
368 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
371 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
374 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
377 vfs_dcache_remove(struct v_dnode* dnode);
380 vfs_walk(struct v_dnode* start,
382 struct v_dnode** dentry,
383 struct hstr* component,
387 vfs_walk_proc(const char* path,
388 struct v_dnode** dentry,
389 struct hstr* component,
393 vfs_mount(const char* target,
395 struct device* device,
399 vfs_unmount(const char* target);
402 vfs_mount_at(const char* fs_name,
403 struct device* device,
404 struct v_dnode* mnt_point,
408 vfs_unmount_at(struct v_dnode* mnt_point);
411 vfs_mkdir(const char* path, struct v_dnode** dentry);
414 vfs_open(struct v_dnode* dnode, struct v_file** file);
417 vfs_pclose(struct v_file* file, pid_t pid);
420 vfs_close(struct v_file* file);
423 vfs_free_fd(struct v_fd* fd);
426 vfs_fsync(struct v_file* file);
429 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
435 vfs_sb_unref(struct v_superblock* sb);
438 vfs_sb_ref(struct v_superblock* sb);
440 #define vfs_assign_sb(sb_accessor, sb) \
442 if (likely(sb_accessor)) { \
443 vfs_sb_unref(sb_accessor); \
445 vfs_sb_ref(((sb_accessor) = (sb))); \
449 vfs_i_assign_sb(struct v_inode* inode, struct v_superblock* sb)
451 vfs_assign_sb(inode->sb, sb);
455 vfs_d_assign_sb(struct v_dnode* dnode, struct v_superblock* sb)
457 vfs_assign_sb(dnode->super_block, sb);
461 vfs_d_assign_vmnt(struct v_dnode* dnode, struct v_mount* vmnt)
464 assert_msg(dnode->mnt->mnt_point != dnode,
465 "vmnt must be detached first");
471 vfs_d_assign_sb(dnode, vmnt->super_block);
475 vfs_vmnt_assign_sb(struct v_mount* vmnt, struct v_superblock* sb)
477 vfs_assign_sb(vmnt->super_block, sb);
481 vfs_d_alloc(struct v_dnode* parent, struct hstr* name);
484 vfs_d_free(struct v_dnode* dnode);
487 vfs_i_find(struct v_superblock* sb, u32_t i_id);
490 vfs_i_addhash(struct v_inode* inode);
493 vfs_i_alloc(struct v_superblock* sb);
496 vfs_i_free(struct v_inode* inode);
499 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
502 vfs_getfd(int fd, struct v_fd** fd_s);
505 vfs_get_dtype(int itype);
508 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
511 pcache_init(struct pcache* pcache);
514 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
517 pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
520 pcache_release(struct pcache* pcache);
523 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
526 pcache_commit_all(struct v_inode* inode);
529 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
537 mnt_mkbusy(struct v_mount* mnt);
545 mnt_chillax(struct v_mount* mnt);
548 vfs_mount_root(const char* fs_name, struct device* device);
551 mnt_check_busy(struct v_mount* mnt)
553 return mnt->busy_counter > 1;
557 vfs_ref_dnode(struct v_dnode* dnode)
561 if (likely(dnode->mnt)) {
562 mnt_mkbusy(dnode->mnt);
567 vfs_unref_dnode(struct v_dnode* dnode)
571 if (likely(dnode->mnt)) {
572 mnt_chillax(dnode->mnt);
577 vfs_ref_file(struct v_file* file)
583 vfs_unref_file(struct v_file* file)
589 vfs_check_duped_file(struct v_file* file)
591 return file->ref_count > 1;
595 vfs_check_writable(struct v_dnode* dnode);
598 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
601 default_file_write(struct v_inode* inode,
607 default_file_read_page(struct v_inode* inode, void* buffer, size_t fpos);
610 default_file_write_page(struct v_inode* inode, void* buffer, size_t fpos);
613 default_file_readdir(struct v_file* file, struct dir_context* dctx);
616 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
619 default_inode_rename(struct v_inode* from_inode,
620 struct v_dnode* from_dnode,
621 struct v_dnode* to_dnode);
624 default_file_close(struct v_file* file);
627 default_file_seek(struct v_file* file, size_t offset);
630 default_inode_open(struct v_inode* this, struct v_file* file);
633 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
636 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
638 struct v_xattr_entry*
639 xattr_new(struct hstr* name);
641 struct v_xattr_entry*
642 xattr_getcache(struct v_inode* inode, struct hstr* name);
645 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
648 /* --- misc stuff --- */
650 #define check_itype(to_check, itype) \
651 (((to_check) & (itype)) == (itype))
654 * @brief Check if node represent a regular file (nothing but a file)
661 check_regfile_node(struct v_inode* inode)
663 return inode->itype == VFS_IFFILE;
667 * @brief Check if node represent a file.
668 * This is basically everything within file system (dir, dev, etc.)
675 check_file_node(struct v_inode* inode)
677 return check_itype(inode->itype, VFS_IFFILE);
681 check_directory_node(struct v_inode* inode)
683 return check_itype(inode->itype, VFS_IFDIR);
687 check_device_node(struct v_inode* inode)
689 return check_itype(inode->itype, VFS_IFDEV);
693 check_seqdev_node(struct v_inode* inode)
695 return check_device_node(inode);
699 check_voldev_node(struct v_inode* inode)
701 return check_itype(inode->itype, VFS_IFVOLDEV);
705 check_symlink_node(struct v_inode* inode)
707 return check_itype(inode->itype, VFS_IFSYMLINK);
710 #endif /* __LUNAIX_VFS_H */