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/llist.h>
10 #include <lunaix/ds/lru.h>
11 #include <lunaix/ds/mutex.h>
12 #include <lunaix/status.h>
13 #include <stdatomic.h>
15 #define VFS_NAME_MAXLEN 128
19 #define VFS_IFFILE 0x2
20 #define VFS_IFSEQDEV 0x4
21 #define VFS_IFVOLDEV 0x8
22 #define VFS_IFSYMLINK 0x10
24 // Walk, mkdir if component encountered is non-exists.
25 #define VFS_WALK_MKPARENT 0x1
27 // Walk, relative to current FS.
28 #define VFS_WALK_FSRELATIVE 0x2
31 Terminate the walk on the immediate parent,
32 name of child (last component) is returned through `component`
34 #define VFS_WALK_PARENT 0x4
36 // Do not follow the symbolic link
37 #define VFS_WALK_NOFOLLOW 0x8
39 #define VFS_HASHTABLE_BITS 10
40 #define VFS_HASHTABLE_SIZE (1 << VFS_HASHTABLE_BITS)
41 #define VFS_HASH_MASK (VFS_HASHTABLE_SIZE - 1)
42 #define VFS_HASHBITS (32 - VFS_HASHTABLE_BITS)
44 #define VFS_PATH_DELIM '/'
46 #define FSTYPE_ROFS 0x1
48 #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD)
50 #define VFS_VALID_CHAR(chr) \
51 (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') || \
52 ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' || \
53 (chr) == '-' || (chr) == ':')
55 #define unlock_inode(inode) mutex_unlock(&inode->lock)
56 #define lock_inode(inode) \
58 mutex_lock(&inode->lock); \
59 lru_use_one(inode_lru, &inode->lru); \
62 #define unlock_dnode(dnode) mutex_unlock(&dnode->lock)
63 #define lock_dnode(dnode) \
65 mutex_lock(&dnode->lock); \
66 lru_use_one(dnode_lru, &dnode->lru); \
69 typedef u32_t inode_t;
81 extern struct v_file_ops default_file_ops;
82 extern struct v_inode_ops default_inode_ops;
84 extern struct hstr vfs_ddot;
85 extern struct hstr vfs_dot;
86 extern struct v_dnode* vfs_sysroot;
90 struct hlist_node fs_list;
94 int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
95 int (*unmount)(struct v_superblock* vsb);
100 struct llist_header sb_list;
102 struct v_dnode* root;
103 struct filesystem* fs;
104 struct hbucket* i_cache;
108 u32_t (*read_capacity)(struct v_superblock* vsb);
109 u32_t (*read_usage)(struct v_superblock* vsb);
110 void (*init_inode)(struct v_superblock* vsb, struct v_inode* inode);
118 void (*read_complete_callback)(struct dir_context* dctx,
126 int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
127 int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
129 // for operatiosn {write|read}_page, following are true:
130 // + `len` always equals to PG_SIZE
131 // + `fpos` always PG_SIZE aligned.
132 // These additional operations allow underlying fs to use more specialized
133 // and optimized code.
135 int (*write_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
136 int (*read_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
138 int (*readdir)(struct v_file* file, struct dir_context* dctx);
139 int (*seek)(struct v_inode* inode, size_t offset); // optional
140 int (*close)(struct v_file* file);
141 int (*sync)(struct v_file* file);
146 int (*create)(struct v_inode* this, struct v_dnode* dnode);
147 int (*open)(struct v_inode* this, struct v_file* file);
148 int (*sync)(struct v_inode* this);
149 int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
150 int (*rmdir)(struct v_inode* this, struct v_dnode* dir);
151 int (*unlink)(struct v_inode* this);
152 int (*link)(struct v_inode* this, struct v_dnode* new_name);
153 int (*read_symlink)(struct v_inode* this, const char** path_out);
154 int (*set_symlink)(struct v_inode* this, const char* target);
155 int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
156 int (*rename)(struct v_inode* from_inode,
157 struct v_dnode* from_dnode,
158 struct v_dnode* to_dnode);
159 int (*getxattr)(struct v_inode* this,
160 struct v_xattr_entry* entry); // optional
161 int (*setxattr)(struct v_inode* this,
162 struct v_xattr_entry* entry); // optional
163 int (*delxattr)(struct v_inode* this,
164 struct v_xattr_entry* entry); // optional
169 struct llist_header entries;
177 struct v_inode* inode;
178 struct v_dnode* dnode;
179 struct llist_header* f_list;
181 atomic_ulong ref_count;
182 struct v_file_ops* ops; // for caching
191 // [v_inode::aka_nodes]
192 // how do we invalidate corresponding v_dnodes given the v_inode?
194 Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow
195 info of every process being accessible via file system. Each process's
196 creation will result a creation of a directory under the root of task fs
197 with it's pid as name. But that dir must delete when process is killed, and
198 such deletion does not mediated by vfs itself, so there is a need of cache
200 And this is also the case of all ramfs where argumentation to file tree is
201 performed by third party.
217 void* data; // 允许底层FS绑定他的一些专有数据
218 struct llist_header aka_dnodes;
219 struct llist_header xattrs;
220 struct v_superblock* sb;
221 struct hlist_node hash_list;
223 struct pcache* pg_cache;
224 struct v_inode_ops* ops;
225 struct v_file_ops* default_fops;
227 void (*destruct)(struct v_inode* inode);
233 struct llist_header list;
234 struct llist_header submnts;
235 struct llist_header sibmnts;
236 struct v_mount* parent;
237 struct v_dnode* mnt_point;
238 struct v_superblock* super_block;
245 mutex_t lock; // sync the path walking
248 struct v_inode* inode;
249 struct v_dnode* parent;
250 struct hlist_node hash_list;
251 struct llist_header aka_list;
252 struct llist_header children;
253 struct llist_header siblings;
254 struct v_superblock* super_block;
256 atomic_ulong ref_count;
263 struct v_fd* fds[VFS_MAX_FD];
268 struct v_inode* master;
270 struct llist_header pages;
271 struct llist_header dirty;
278 struct llist_header pg_list;
279 struct llist_header dirty_list;
281 struct pcache* holder;
295 fsm_new_fs(char* name, size_t name_len);
298 fsm_register(struct filesystem* fs);
301 fsm_get(const char* fs_name);
307 vfs_export_attributes();
310 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
313 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
316 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
319 vfs_dcache_remove(struct v_dnode* dnode);
322 vfs_walk(struct v_dnode* start,
324 struct v_dnode** dentry,
325 struct hstr* component,
329 vfs_walk_proc(const char* path,
330 struct v_dnode** dentry,
331 struct hstr* component,
335 vfs_mount(const char* target,
337 struct device* device,
341 vfs_unmount(const char* target);
344 vfs_mount_at(const char* fs_name,
345 struct device* device,
346 struct v_dnode* mnt_point,
350 vfs_unmount_at(struct v_dnode* mnt_point);
353 vfs_mkdir(const char* path, struct v_dnode** dentry);
356 vfs_open(struct v_dnode* dnode, struct v_file** file);
359 vfs_pclose(struct v_file* file, pid_t pid);
362 vfs_close(struct v_file* file);
365 vfs_free_fd(struct v_fd* fd);
368 vfs_fsync(struct v_file* file);
371 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
377 vfs_sb_free(struct v_superblock* sb);
383 vfs_d_free(struct v_dnode* dnode);
386 vfs_i_find(struct v_superblock* sb, u32_t i_id);
389 vfs_i_addhash(struct v_inode* inode);
392 vfs_i_alloc(struct v_superblock* sb);
395 vfs_i_free(struct v_inode* inode);
398 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
401 vfs_getfd(int fd, struct v_fd** fd_s);
404 vfs_get_dtype(int itype);
407 vfs_ref_dnode(struct v_dnode* dnode);
410 vfs_ref_file(struct v_file* file);
413 vfs_unref_dnode(struct v_dnode* dnode);
416 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
419 pcache_init(struct pcache* pcache);
422 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
425 pcache_new_page(struct pcache* pcache, u32_t index);
428 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
431 pcache_get_page(struct pcache* pcache,
434 struct pcache_pg** page);
437 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
440 pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
443 pcache_release(struct pcache* pcache);
446 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
449 pcache_commit_all(struct v_inode* inode);
452 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
460 mnt_mkbusy(struct v_mount* mnt);
468 mnt_chillax(struct v_mount* mnt);
471 vfs_mount_root(const char* fs_name, struct device* device);
474 vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point);
477 vfs_check_writable(struct v_dnode* dnode);
480 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
483 default_file_write(struct v_inode* inode,
489 default_file_readdir(struct v_file* file, struct dir_context* dctx);
492 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
495 default_inode_rename(struct v_inode* from_inode,
496 struct v_dnode* from_dnode,
497 struct v_dnode* to_dnode);
500 default_file_close(struct v_file* file);
503 default_file_seek(struct v_inode* inode, size_t offset);
506 default_inode_open(struct v_inode* this, struct v_file* file);
509 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
512 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
514 struct v_xattr_entry*
515 xattr_new(struct hstr* name);
517 struct v_xattr_entry*
518 xattr_getcache(struct v_inode* inode, struct hstr* name);
521 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
523 #endif /* __LUNAIX_VFS_H */