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 0x16
24 #define VFS_WALK_MKPARENT 0x1
25 #define VFS_WALK_FSRELATIVE 0x2
26 #define VFS_WALK_PARENT 0x4
27 #define VFS_WALK_NOFOLLOW 0x8
29 #define VFS_HASHTABLE_BITS 10
30 #define VFS_HASHTABLE_SIZE (1 << VFS_HASHTABLE_BITS)
31 #define VFS_HASH_MASK (VFS_HASHTABLE_SIZE - 1)
32 #define VFS_HASHBITS (32 - VFS_HASHTABLE_BITS)
34 #define VFS_PATH_DELIM '/'
36 #define FSTYPE_ROFS 0x1
38 #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD)
40 #define VFS_VALID_CHAR(chr) \
41 (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') || \
42 ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' || \
43 (chr) == '-' || (chr) == ':')
45 #define unlock_inode(inode) mutex_unlock(&inode->lock)
46 #define lock_inode(inode) \
48 mutex_lock(&inode->lock); \
49 lru_use_one(inode_lru, &inode->lru); \
52 #define unlock_dnode(dnode) mutex_unlock(&dnode->lock)
53 #define lock_dnode(dnode) \
55 mutex_lock(&dnode->lock); \
56 lru_use_one(dnode_lru, &dnode->lru); \
59 typedef u32_t inode_t;
71 extern struct v_file_ops default_file_ops;
72 extern struct v_inode_ops default_inode_ops;
74 extern struct hstr vfs_ddot;
75 extern struct hstr vfs_dot;
76 extern struct v_dnode* vfs_sysroot;
80 struct hlist_node fs_list;
84 int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
85 int (*unmount)(struct v_superblock* vsb);
90 struct llist_header sb_list;
93 struct filesystem* fs;
94 struct hbucket* i_cache;
98 u32_t (*read_capacity)(struct v_superblock* vsb);
99 u32_t (*read_usage)(struct v_superblock* vsb);
100 void (*init_inode)(struct v_superblock* vsb, struct v_inode* inode);
108 void (*read_complete_callback)(struct dir_context* dctx,
116 int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
117 int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
119 // for operatiosn {write|read}_page, following are true:
120 // + `len` always equals to PG_SIZE
121 // + `fpos` always PG_SIZE aligned.
122 // These additional operations allow underlying fs to use more specialized
123 // and optimized code.
125 int (*write_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
126 int (*read_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
128 int (*readdir)(struct v_file* file, struct dir_context* dctx);
129 int (*seek)(struct v_inode* inode, size_t offset); // optional
130 int (*close)(struct v_file* file);
131 int (*sync)(struct v_file* file);
136 int (*create)(struct v_inode* this, struct v_dnode* dnode);
137 int (*open)(struct v_inode* this, struct v_file* file);
138 int (*sync)(struct v_inode* this);
139 int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
140 int (*rmdir)(struct v_inode* this, struct v_dnode* dir);
141 int (*unlink)(struct v_inode* this);
142 int (*link)(struct v_inode* this, struct v_dnode* new_name);
143 int (*read_symlink)(struct v_inode* this, const char** path_out);
144 int (*set_symlink)(struct v_inode* this, const char* target);
145 int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
146 int (*rename)(struct v_inode* from_inode,
147 struct v_dnode* from_dnode,
148 struct v_dnode* to_dnode);
149 int (*getxattr)(struct v_inode* this,
150 struct v_xattr_entry* entry); // optional
151 int (*setxattr)(struct v_inode* this,
152 struct v_xattr_entry* entry); // optional
153 int (*delxattr)(struct v_inode* this,
154 struct v_xattr_entry* entry); // optional
159 struct llist_header entries;
167 struct v_inode* inode;
168 struct v_dnode* dnode;
169 struct llist_header* f_list;
171 atomic_ulong ref_count;
172 struct v_file_ops* ops; // for caching
181 // [v_inode::aka_nodes]
182 // how do we invalidate corresponding v_dnodes given the v_inode?
184 Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow
185 info of every process being accessible via file system. Each process's
186 creation will result a creation of a directory under the root of task fs
187 with it's pid as name. But that dir must delete when process is killed, and
188 such deletion does not mediated by vfs itself, so there is a need of cache
190 And this is also the case of all ramfs where argumentation to file tree is
191 performed by third party.
207 void* data; // 允许底层FS绑定他的一些专有数据
208 struct llist_header aka_dnodes;
209 struct llist_header xattrs;
210 struct v_superblock* sb;
211 struct hlist_node hash_list;
213 struct pcache* pg_cache;
214 struct v_inode_ops* ops;
215 struct v_file_ops* default_fops;
217 void (*destruct)(struct v_inode* inode);
223 struct llist_header list;
224 struct llist_header submnts;
225 struct llist_header sibmnts;
226 struct v_mount* parent;
227 struct v_dnode* mnt_point;
228 struct v_superblock* super_block;
235 mutex_t lock; // sync the path walking
238 struct v_inode* inode;
239 struct v_dnode* parent;
240 struct hlist_node hash_list;
241 struct llist_header aka_list;
242 struct llist_header children;
243 struct llist_header siblings;
244 struct v_superblock* super_block;
246 atomic_ulong ref_count;
253 struct v_fd* fds[VFS_MAX_FD];
258 struct v_inode* master;
260 struct llist_header pages;
261 struct llist_header dirty;
268 struct llist_header pg_list;
269 struct llist_header dirty_list;
271 struct pcache* holder;
285 fsm_new_fs(char* name, size_t name_len);
288 fsm_register(struct filesystem* fs);
291 fsm_get(const char* fs_name);
297 vfs_export_attributes();
300 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
303 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
306 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
309 vfs_dcache_remove(struct v_dnode* dnode);
312 vfs_walk(struct v_dnode* start,
314 struct v_dnode** dentry,
315 struct hstr* component,
319 vfs_walk_proc(const char* path,
320 struct v_dnode** dentry,
321 struct hstr* component,
325 vfs_mount(const char* target,
327 struct device* device,
331 vfs_unmount(const char* target);
334 vfs_mount_at(const char* fs_name,
335 struct device* device,
336 struct v_dnode* mnt_point,
340 vfs_unmount_at(struct v_dnode* mnt_point);
343 vfs_mkdir(const char* path, struct v_dnode** dentry);
346 vfs_open(struct v_dnode* dnode, struct v_file** file);
349 vfs_pclose(struct v_file* file, pid_t pid);
352 vfs_close(struct v_file* file);
355 vfs_free_fd(struct v_fd* fd);
358 vfs_fsync(struct v_file* file);
361 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
367 vfs_sb_free(struct v_superblock* sb);
373 vfs_d_free(struct v_dnode* dnode);
376 vfs_i_find(struct v_superblock* sb, u32_t i_id);
379 vfs_i_addhash(struct v_inode* inode);
382 vfs_i_alloc(struct v_superblock* sb);
385 vfs_i_free(struct v_inode* inode);
388 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
391 vfs_getfd(int fd, struct v_fd** fd_s);
394 vfs_get_dtype(int itype);
397 vfs_ref_dnode(struct v_dnode* dnode);
400 vfs_ref_file(struct v_file* file);
403 vfs_unref_dnode(struct v_dnode* dnode);
406 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
409 pcache_init(struct pcache* pcache);
412 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
415 pcache_new_page(struct pcache* pcache, u32_t index);
418 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
421 pcache_get_page(struct pcache* pcache,
424 struct pcache_pg** page);
427 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
430 pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
433 pcache_release(struct pcache* pcache);
436 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
439 pcache_commit_all(struct v_inode* inode);
442 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
450 mnt_mkbusy(struct v_mount* mnt);
458 mnt_chillax(struct v_mount* mnt);
461 vfs_mount_root(const char* fs_name, struct device* device);
464 vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point);
467 vfs_check_writable(struct v_dnode* dnode);
470 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
473 default_file_write(struct v_inode* inode,
479 default_file_readdir(struct v_file* file, struct dir_context* dctx);
482 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
485 default_inode_rename(struct v_inode* from_inode,
486 struct v_dnode* from_dnode,
487 struct v_dnode* to_dnode);
490 default_file_close(struct v_file* file);
493 default_file_seek(struct v_inode* inode, size_t offset);
496 default_inode_open(struct v_inode* this, struct v_file* file);
499 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
502 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
504 struct v_xattr_entry*
505 xattr_new(struct hstr* name);
507 struct v_xattr_entry*
508 xattr_getcache(struct v_inode* inode, struct hstr* name);
511 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
513 #endif /* __LUNAIX_VFS_H */