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;
102 uint32_t (*read_capacity)(struct v_superblock* vsb);
103 uint32_t (*read_usage)(struct v_superblock* vsb);
104 void (*init_inode)(struct v_superblock* vsb, struct v_inode* inode);
112 void (*read_complete_callback)(struct dir_context* dctx,
120 int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
121 int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
122 int (*readdir)(struct v_file* file, struct dir_context* dctx);
123 int (*seek)(struct v_inode* inode, size_t offset); // optional
124 int (*close)(struct v_file* file);
125 int (*sync)(struct v_file* file);
130 int (*create)(struct v_inode* this, struct v_dnode* dnode);
131 int (*open)(struct v_inode* this, struct v_file* file);
132 int (*sync)(struct v_inode* this);
133 int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
134 int (*rmdir)(struct v_inode* this, struct v_dnode* dir);
135 int (*unlink)(struct v_inode* this);
136 int (*link)(struct v_inode* this, struct v_dnode* new_name);
137 int (*read_symlink)(struct v_inode* this, const char** path_out);
138 int (*set_symlink)(struct v_inode* this, const char* target);
139 int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
140 int (*rename)(struct v_inode* from_inode,
141 struct v_dnode* from_dnode,
142 struct v_dnode* to_dnode);
143 int (*getxattr)(struct v_inode* this,
144 struct v_xattr_entry* entry); // optional
145 int (*setxattr)(struct v_inode* this,
146 struct v_xattr_entry* entry); // optional
147 int (*delxattr)(struct v_inode* this,
148 struct v_xattr_entry* entry); // optional
153 struct llist_header entries;
161 struct v_inode* inode;
162 struct v_dnode* dnode;
163 struct llist_header* f_list;
165 atomic_ulong ref_count;
166 struct v_file_ops* ops; // for caching
175 // FIXME how do we invalidate corresponding v_dnodes given the v_inode?
177 Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow
178 info of every process being accessible via file system. Each process's
179 creation will result a creation of a directory under the root of task fs
180 with it's pid as name. But that dir must delete when process is killed, and
181 such deletion does not mediated by vfs itself, so there is a need of cache
183 And this is also the case of all ramfs where argumentation to file tree is
184 performed by third party.
200 void* data; // 允许底层FS绑定他的一些专有数据
201 struct llist_header aka_dnodes;
202 struct llist_header xattrs;
203 struct v_superblock* sb;
204 struct hlist_node hash_list;
206 struct pcache* pg_cache;
207 struct v_inode_ops* ops;
208 struct v_file_ops* default_fops;
214 struct llist_header list;
215 struct llist_header submnts;
216 struct llist_header sibmnts;
217 struct v_mount* parent;
218 struct v_dnode* mnt_point;
219 struct v_superblock* super_block;
220 uint32_t busy_counter;
226 mutex_t lock; // sync the path walking
229 struct v_inode* inode;
230 struct v_dnode* parent;
231 struct hlist_node hash_list;
232 struct llist_header aka_list;
233 struct llist_header children;
234 struct llist_header siblings;
235 struct v_superblock* super_block;
237 atomic_ulong ref_count;
244 struct v_fd* fds[VFS_MAX_FD];
249 struct v_inode* master;
251 struct llist_header pages;
252 struct llist_header dirty;
259 struct llist_header pg_list;
260 struct llist_header dirty_list;
262 struct pcache* holder;
275 fsm_new_fs(char* name, size_t name_len);
278 fsm_register(struct filesystem* fs);
281 fsm_get(const char* fs_name);
287 vfs_export_attributes();
290 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
293 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
296 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
299 vfs_dcache_remove(struct v_dnode* dnode);
302 vfs_walk(struct v_dnode* start,
304 struct v_dnode** dentry,
305 struct hstr* component,
309 vfs_walk_proc(const char* path,
310 struct v_dnode** dentry,
311 struct hstr* component,
315 vfs_mount(const char* target,
317 struct device* device,
321 vfs_unmount(const char* target);
324 vfs_mount_at(const char* fs_name,
325 struct device* device,
326 struct v_dnode* mnt_point,
330 vfs_unmount_at(struct v_dnode* mnt_point);
333 vfs_mkdir(const char* path, struct v_dnode** dentry);
336 vfs_open(struct v_dnode* dnode, struct v_file** file);
339 vfs_pclose(struct v_file* file, pid_t pid);
342 vfs_close(struct v_file* file);
345 vfs_free_fd(struct v_fd* fd);
348 vfs_fsync(struct v_file* file);
351 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
357 vfs_sb_free(struct v_superblock* sb);
363 vfs_d_free(struct v_dnode* dnode);
366 vfs_i_find(struct v_superblock* sb, uint32_t i_id);
369 vfs_i_addhash(struct v_inode* inode);
372 vfs_i_alloc(struct v_superblock* sb);
375 vfs_i_free(struct v_inode* inode);
378 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
381 vfs_getfd(int fd, struct v_fd** fd_s);
384 vfs_get_dtype(int itype);
387 vfs_ref_dnode(struct v_dnode* dnode);
390 vfs_unref_dnode(struct v_dnode* dnode);
393 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
396 pcache_init(struct pcache* pcache);
399 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
402 pcache_new_page(struct pcache* pcache, uint32_t index);
405 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
408 pcache_get_page(struct pcache* pcache,
411 struct pcache_pg** page);
414 pcache_write(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
417 pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
420 pcache_release(struct pcache* pcache);
423 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
426 pcache_commit_all(struct v_inode* inode);
429 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
437 mnt_mkbusy(struct v_mount* mnt);
445 mnt_chillax(struct v_mount* mnt);
448 vfs_mount_root(const char* fs_name, struct device* device);
451 vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point);
454 vfs_check_writable(struct v_dnode* dnode);
457 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
460 default_file_write(struct v_inode* inode,
466 default_file_readdir(struct v_file* file, struct dir_context* dctx);
469 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
472 default_inode_rename(struct v_inode* from_inode,
473 struct v_dnode* from_dnode,
474 struct v_dnode* to_dnode);
477 default_file_close(struct v_file* file);
480 default_file_seek(struct v_inode* inode, size_t offset);
483 default_inode_open(struct v_inode* this, struct v_file* file);
486 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
489 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
491 struct v_xattr_entry*
492 xattr_new(struct hstr* name);
494 struct v_xattr_entry*
495 xattr_getcache(struct v_inode* inode, struct hstr* name);
498 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
500 #endif /* __LUNAIX_VFS_H */