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 u32_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 u32_t (*read_capacity)(struct v_superblock* vsb);
104 u32_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);
124 // for operatiosn {write|read}_page, following are true:
125 // + `len` always equals to PG_SIZE
126 // + `fpos` always PG_SIZE aligned.
127 // These additional operations allow underlying fs to use more specialized
128 // and optimized code.
130 int (*write_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
131 int (*read_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
133 int (*readdir)(struct v_file* file, struct dir_context* dctx);
134 int (*seek)(struct v_inode* inode, size_t offset); // optional
135 int (*close)(struct v_file* file);
136 int (*sync)(struct v_file* file);
141 int (*create)(struct v_inode* this, struct v_dnode* dnode);
142 int (*open)(struct v_inode* this, struct v_file* file);
143 int (*sync)(struct v_inode* this);
144 int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
145 int (*rmdir)(struct v_inode* this, struct v_dnode* dir);
146 int (*unlink)(struct v_inode* this);
147 int (*link)(struct v_inode* this, struct v_dnode* new_name);
148 int (*read_symlink)(struct v_inode* this, const char** path_out);
149 int (*set_symlink)(struct v_inode* this, const char* target);
150 int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
151 int (*rename)(struct v_inode* from_inode,
152 struct v_dnode* from_dnode,
153 struct v_dnode* to_dnode);
154 int (*getxattr)(struct v_inode* this,
155 struct v_xattr_entry* entry); // optional
156 int (*setxattr)(struct v_inode* this,
157 struct v_xattr_entry* entry); // optional
158 int (*delxattr)(struct v_inode* this,
159 struct v_xattr_entry* entry); // optional
164 struct llist_header entries;
172 struct v_inode* inode;
173 struct v_dnode* dnode;
174 struct llist_header* f_list;
176 atomic_ulong ref_count;
177 struct v_file_ops* ops; // for caching
186 // [v_inode::aka_nodes]
187 // how do we invalidate corresponding v_dnodes given the v_inode?
189 Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow
190 info of every process being accessible via file system. Each process's
191 creation will result a creation of a directory under the root of task fs
192 with it's pid as name. But that dir must delete when process is killed, and
193 such deletion does not mediated by vfs itself, so there is a need of cache
195 And this is also the case of all ramfs where argumentation to file tree is
196 performed by third party.
212 void* data; // 允许底层FS绑定他的一些专有数据
213 struct llist_header aka_dnodes;
214 struct llist_header xattrs;
215 struct v_superblock* sb;
216 struct hlist_node hash_list;
218 struct pcache* pg_cache;
219 struct v_inode_ops* ops;
220 struct v_file_ops* default_fops;
222 void (*destruct)(struct v_inode* inode);
228 struct llist_header list;
229 struct llist_header submnts;
230 struct llist_header sibmnts;
231 struct v_mount* parent;
232 struct v_dnode* mnt_point;
233 struct v_superblock* super_block;
240 mutex_t lock; // sync the path walking
243 struct v_inode* inode;
244 struct v_dnode* parent;
245 struct hlist_node hash_list;
246 struct llist_header aka_list;
247 struct llist_header children;
248 struct llist_header siblings;
249 struct v_superblock* super_block;
251 atomic_ulong ref_count;
258 struct v_fd* fds[VFS_MAX_FD];
263 struct v_inode* master;
265 struct llist_header pages;
266 struct llist_header dirty;
273 struct llist_header pg_list;
274 struct llist_header dirty_list;
276 struct pcache* holder;
290 fsm_new_fs(char* name, size_t name_len);
293 fsm_register(struct filesystem* fs);
296 fsm_get(const char* fs_name);
302 vfs_export_attributes();
305 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
308 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
311 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
314 vfs_dcache_remove(struct v_dnode* dnode);
317 vfs_walk(struct v_dnode* start,
319 struct v_dnode** dentry,
320 struct hstr* component,
324 vfs_walk_proc(const char* path,
325 struct v_dnode** dentry,
326 struct hstr* component,
330 vfs_mount(const char* target,
332 struct device* device,
336 vfs_unmount(const char* target);
339 vfs_mount_at(const char* fs_name,
340 struct device* device,
341 struct v_dnode* mnt_point,
345 vfs_unmount_at(struct v_dnode* mnt_point);
348 vfs_mkdir(const char* path, struct v_dnode** dentry);
351 vfs_open(struct v_dnode* dnode, struct v_file** file);
354 vfs_pclose(struct v_file* file, pid_t pid);
357 vfs_close(struct v_file* file);
360 vfs_free_fd(struct v_fd* fd);
363 vfs_fsync(struct v_file* file);
366 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
372 vfs_sb_free(struct v_superblock* sb);
378 vfs_d_free(struct v_dnode* dnode);
381 vfs_i_find(struct v_superblock* sb, u32_t i_id);
384 vfs_i_addhash(struct v_inode* inode);
387 vfs_i_alloc(struct v_superblock* sb);
390 vfs_i_free(struct v_inode* inode);
393 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
396 vfs_getfd(int fd, struct v_fd** fd_s);
399 vfs_get_dtype(int itype);
402 vfs_ref_dnode(struct v_dnode* dnode);
405 vfs_unref_dnode(struct v_dnode* dnode);
408 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
411 pcache_init(struct pcache* pcache);
414 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
417 pcache_new_page(struct pcache* pcache, u32_t index);
420 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
423 pcache_get_page(struct pcache* pcache,
426 struct pcache_pg** page);
429 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
432 pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
435 pcache_release(struct pcache* pcache);
438 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
441 pcache_commit_all(struct v_inode* inode);
444 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
452 mnt_mkbusy(struct v_mount* mnt);
460 mnt_chillax(struct v_mount* mnt);
463 vfs_mount_root(const char* fs_name, struct device* device);
466 vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point);
469 vfs_check_writable(struct v_dnode* dnode);
472 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
475 default_file_write(struct v_inode* inode,
481 default_file_readdir(struct v_file* file, struct dir_context* dctx);
484 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
487 default_inode_rename(struct v_inode* from_inode,
488 struct v_dnode* from_dnode,
489 struct v_dnode* to_dnode);
492 default_file_close(struct v_file* file);
495 default_file_seek(struct v_inode* inode, size_t offset);
498 default_inode_open(struct v_inode* this, struct v_file* file);
501 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
504 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
506 struct v_xattr_entry*
507 xattr_new(struct hstr* name);
509 struct v_xattr_entry*
510 xattr_getcache(struct v_inode* inode, struct hstr* name);
513 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
515 #endif /* __LUNAIX_VFS_H */