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/process.h>
13 #include <lunaix/status.h>
14 #include <stdatomic.h>
16 #define VFS_NAME_MAXLEN 128
20 #define VFS_IFFILE 0x2
21 #define VFS_IFSEQDEV 0x4
22 #define VFS_IFVOLDEV 0x8
23 #define VFS_IFSYMLINK 0x16
25 #define VFS_WALK_MKPARENT 0x1
26 #define VFS_WALK_FSRELATIVE 0x2
27 #define VFS_WALK_PARENT 0x4
28 #define VFS_WALK_NOFOLLOW 0x8
30 #define VFS_HASHTABLE_BITS 10
31 #define VFS_HASHTABLE_SIZE (1 << VFS_HASHTABLE_BITS)
32 #define VFS_HASH_MASK (VFS_HASHTABLE_SIZE - 1)
33 #define VFS_HASHBITS (32 - VFS_HASHTABLE_BITS)
35 #define VFS_PATH_DELIM '/'
37 #define FSTYPE_ROFS 0x1
39 #define DO_STATUS(errno) SYSCALL_ESTATUS(__current->k_status = errno)
40 #define DO_STATUS_OR_RETURN(errno) ({ errno < 0 ? DO_STATUS(errno) : errno; })
42 #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD)
44 #define VFS_VALID_CHAR(chr) \
45 (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') || \
46 ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' || \
47 (chr) == '-' || (chr) == ':')
49 #define unlock_inode(inode) mutex_unlock(&inode->lock)
50 #define lock_inode(inode) \
52 mutex_lock(&inode->lock); \
53 lru_use_one(inode_lru, &inode->lru); \
56 #define unlock_dnode(dnode) mutex_unlock(&dnode->lock)
57 #define lock_dnode(dnode) \
59 mutex_lock(&dnode->lock); \
60 lru_use_one(dnode_lru, &dnode->lru); \
63 typedef uint32_t inode_t;
75 extern struct v_file_ops default_file_ops;
76 extern struct v_inode_ops default_inode_ops;
78 extern struct hstr vfs_ddot;
79 extern struct hstr vfs_dot;
80 extern struct v_dnode* vfs_sysroot;
84 struct hlist_node fs_list;
88 int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
89 int (*unmount)(struct v_superblock* vsb);
94 struct llist_header sb_list;
97 struct filesystem* fs;
99 struct hbucket* i_cache;
103 uint32_t (*read_capacity)(struct v_superblock* vsb);
104 uint32_t (*read_usage)(struct v_superblock* vsb);
105 void (*init_inode)(struct v_superblock* vsb, struct v_inode* inode);
113 void (*read_complete_callback)(struct dir_context* dctx,
121 int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
122 int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
123 int (*readdir)(struct v_file* file, struct dir_context* dctx);
124 int (*seek)(struct v_inode* inode, size_t offset); // optional
125 int (*close)(struct v_file* file);
126 int (*sync)(struct v_file* file);
131 int (*create)(struct v_inode* this, struct v_dnode* dnode);
132 int (*open)(struct v_inode* this, struct v_file* file);
133 int (*sync)(struct v_inode* this);
134 int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
135 int (*rmdir)(struct v_inode* this, struct v_dnode* dir);
136 int (*unlink)(struct v_inode* this);
137 int (*link)(struct v_inode* this, struct v_dnode* new_name);
138 int (*read_symlink)(struct v_inode* this, const char** path_out);
139 int (*set_symlink)(struct v_inode* this, const char* target);
140 int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
141 int (*rename)(struct v_inode* from_inode,
142 struct v_dnode* from_dnode,
143 struct v_dnode* to_dnode);
144 int (*getxattr)(struct v_inode* this,
145 struct v_xattr_entry* entry); // optional
146 int (*setxattr)(struct v_inode* this,
147 struct v_xattr_entry* entry); // optional
148 int (*delxattr)(struct v_inode* this,
149 struct v_xattr_entry* entry); // optional
154 struct llist_header entries;
162 struct v_inode* inode;
163 struct v_dnode* dnode;
164 struct llist_header* f_list;
166 atomic_ulong ref_count;
167 struct v_file_ops* ops; // for caching
176 // [v_inode::aka_nodes]
177 // how do we invalidate corresponding v_dnodes given the v_inode?
179 Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow
180 info of every process being accessible via file system. Each process's
181 creation will result a creation of a directory under the root of task fs
182 with it's pid as name. But that dir must delete when process is killed, and
183 such deletion does not mediated by vfs itself, so there is a need of cache
185 And this is also the case of all ramfs where argumentation to file tree is
186 performed by third party.
202 void* data; // 允许底层FS绑定他的一些专有数据
203 struct llist_header aka_dnodes;
204 struct llist_header xattrs;
205 struct v_superblock* sb;
206 struct hlist_node hash_list;
208 struct pcache* pg_cache;
209 struct v_inode_ops* ops;
210 struct v_file_ops* default_fops;
216 struct llist_header list;
217 struct llist_header submnts;
218 struct llist_header sibmnts;
219 struct v_mount* parent;
220 struct v_dnode* mnt_point;
221 struct v_superblock* super_block;
222 uint32_t busy_counter;
228 mutex_t lock; // sync the path walking
231 struct v_inode* inode;
232 struct v_dnode* parent;
233 struct hlist_node hash_list;
234 struct llist_header aka_list;
235 struct llist_header children;
236 struct llist_header siblings;
237 struct v_superblock* super_block;
239 atomic_ulong ref_count;
246 struct v_fd* fds[VFS_MAX_FD];
251 struct v_inode* master;
253 struct llist_header pages;
254 struct llist_header dirty;
261 struct llist_header pg_list;
262 struct llist_header dirty_list;
264 struct pcache* holder;
277 fsm_new_fs(char* name, size_t name_len);
280 fsm_register(struct filesystem* fs);
283 fsm_get(const char* fs_name);
289 vfs_export_attributes();
292 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
295 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
298 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
301 vfs_dcache_remove(struct v_dnode* dnode);
304 vfs_walk(struct v_dnode* start,
306 struct v_dnode** dentry,
307 struct hstr* component,
311 vfs_walk_proc(const char* path,
312 struct v_dnode** dentry,
313 struct hstr* component,
317 vfs_mount(const char* target,
319 struct device* device,
323 vfs_unmount(const char* target);
326 vfs_mount_at(const char* fs_name,
327 struct device* device,
328 struct v_dnode* mnt_point,
332 vfs_unmount_at(struct v_dnode* mnt_point);
335 vfs_mkdir(const char* path, struct v_dnode** dentry);
338 vfs_open(struct v_dnode* dnode, struct v_file** file);
341 vfs_pclose(struct v_file* file, pid_t pid);
344 vfs_close(struct v_file* file);
347 vfs_free_fd(struct v_fd* fd);
350 vfs_fsync(struct v_file* file);
353 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
359 vfs_sb_free(struct v_superblock* sb);
365 vfs_d_free(struct v_dnode* dnode);
368 vfs_i_find(struct v_superblock* sb, uint32_t i_id);
371 vfs_i_addhash(struct v_inode* inode);
374 vfs_i_alloc(struct v_superblock* sb);
377 vfs_i_free(struct v_inode* inode);
380 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
383 vfs_getfd(int fd, struct v_fd** fd_s);
386 vfs_get_dtype(int itype);
389 vfs_ref_dnode(struct v_dnode* dnode);
392 vfs_unref_dnode(struct v_dnode* dnode);
395 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
398 pcache_init(struct pcache* pcache);
401 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
404 pcache_new_page(struct pcache* pcache, uint32_t index);
407 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
410 pcache_get_page(struct pcache* pcache,
413 struct pcache_pg** page);
416 pcache_write(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
419 pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
422 pcache_release(struct pcache* pcache);
425 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
428 pcache_commit_all(struct v_inode* inode);
431 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
439 mnt_mkbusy(struct v_mount* mnt);
447 mnt_chillax(struct v_mount* mnt);
450 vfs_mount_root(const char* fs_name, struct device* device);
453 vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point);
456 vfs_check_writable(struct v_dnode* dnode);
459 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
462 default_file_write(struct v_inode* inode,
468 default_file_readdir(struct v_file* file, struct dir_context* dctx);
471 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
474 default_inode_rename(struct v_inode* from_inode,
475 struct v_dnode* from_dnode,
476 struct v_dnode* to_dnode);
479 default_file_close(struct v_file* file);
482 default_file_seek(struct v_inode* inode, size_t offset);
485 default_inode_open(struct v_inode* this, struct v_file* file);
488 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
491 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
493 struct v_xattr_entry*
494 xattr_new(struct hstr* name);
496 struct v_xattr_entry*
497 xattr_getcache(struct v_inode* inode, struct hstr* name);
500 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
502 #endif /* __LUNAIX_VFS_H */