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;
98 struct hbucket* i_cache;
102 u32_t (*read_capacity)(struct v_superblock* vsb);
103 u32_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);
123 // for operatiosn {write|read}_page, following are true:
124 // + `len` always equals to PG_SIZE
125 // + `fpos` always PG_SIZE aligned.
126 // These additional operations allow underlying fs to use more specialized
127 // and optimized code.
129 int (*write_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
130 int (*read_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
132 int (*readdir)(struct v_file* file, struct dir_context* dctx);
133 int (*seek)(struct v_inode* inode, size_t offset); // optional
134 int (*close)(struct v_file* file);
135 int (*sync)(struct v_file* file);
140 int (*create)(struct v_inode* this, struct v_dnode* dnode);
141 int (*open)(struct v_inode* this, struct v_file* file);
142 int (*sync)(struct v_inode* this);
143 int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
144 int (*rmdir)(struct v_inode* this, struct v_dnode* dir);
145 int (*unlink)(struct v_inode* this);
146 int (*link)(struct v_inode* this, struct v_dnode* new_name);
147 int (*read_symlink)(struct v_inode* this, const char** path_out);
148 int (*set_symlink)(struct v_inode* this, const char* target);
149 int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
150 int (*rename)(struct v_inode* from_inode,
151 struct v_dnode* from_dnode,
152 struct v_dnode* to_dnode);
153 int (*getxattr)(struct v_inode* this,
154 struct v_xattr_entry* entry); // optional
155 int (*setxattr)(struct v_inode* this,
156 struct v_xattr_entry* entry); // optional
157 int (*delxattr)(struct v_inode* this,
158 struct v_xattr_entry* entry); // optional
163 struct llist_header entries;
171 struct v_inode* inode;
172 struct v_dnode* dnode;
173 struct llist_header* f_list;
175 atomic_ulong ref_count;
176 struct v_file_ops* ops; // for caching
185 // [v_inode::aka_nodes]
186 // how do we invalidate corresponding v_dnodes given the v_inode?
188 Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow
189 info of every process being accessible via file system. Each process's
190 creation will result a creation of a directory under the root of task fs
191 with it's pid as name. But that dir must delete when process is killed, and
192 such deletion does not mediated by vfs itself, so there is a need of cache
194 And this is also the case of all ramfs where argumentation to file tree is
195 performed by third party.
211 void* data; // 允许底层FS绑定他的一些专有数据
212 struct llist_header aka_dnodes;
213 struct llist_header xattrs;
214 struct v_superblock* sb;
215 struct hlist_node hash_list;
217 struct pcache* pg_cache;
218 struct v_inode_ops* ops;
219 struct v_file_ops* default_fops;
221 void (*destruct)(struct v_inode* inode);
227 struct llist_header list;
228 struct llist_header submnts;
229 struct llist_header sibmnts;
230 struct v_mount* parent;
231 struct v_dnode* mnt_point;
232 struct v_superblock* super_block;
239 mutex_t lock; // sync the path walking
242 struct v_inode* inode;
243 struct v_dnode* parent;
244 struct hlist_node hash_list;
245 struct llist_header aka_list;
246 struct llist_header children;
247 struct llist_header siblings;
248 struct v_superblock* super_block;
250 atomic_ulong ref_count;
257 struct v_fd* fds[VFS_MAX_FD];
262 struct v_inode* master;
264 struct llist_header pages;
265 struct llist_header dirty;
272 struct llist_header pg_list;
273 struct llist_header dirty_list;
275 struct pcache* holder;
289 fsm_new_fs(char* name, size_t name_len);
292 fsm_register(struct filesystem* fs);
295 fsm_get(const char* fs_name);
301 vfs_export_attributes();
304 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
307 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
310 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
313 vfs_dcache_remove(struct v_dnode* dnode);
316 vfs_walk(struct v_dnode* start,
318 struct v_dnode** dentry,
319 struct hstr* component,
323 vfs_walk_proc(const char* path,
324 struct v_dnode** dentry,
325 struct hstr* component,
329 vfs_mount(const char* target,
331 struct device* device,
335 vfs_unmount(const char* target);
338 vfs_mount_at(const char* fs_name,
339 struct device* device,
340 struct v_dnode* mnt_point,
344 vfs_unmount_at(struct v_dnode* mnt_point);
347 vfs_mkdir(const char* path, struct v_dnode** dentry);
350 vfs_open(struct v_dnode* dnode, struct v_file** file);
353 vfs_pclose(struct v_file* file, pid_t pid);
356 vfs_close(struct v_file* file);
359 vfs_free_fd(struct v_fd* fd);
362 vfs_fsync(struct v_file* file);
365 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
371 vfs_sb_free(struct v_superblock* sb);
377 vfs_d_free(struct v_dnode* dnode);
380 vfs_i_find(struct v_superblock* sb, u32_t i_id);
383 vfs_i_addhash(struct v_inode* inode);
386 vfs_i_alloc(struct v_superblock* sb);
389 vfs_i_free(struct v_inode* inode);
392 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
395 vfs_getfd(int fd, struct v_fd** fd_s);
398 vfs_get_dtype(int itype);
401 vfs_ref_dnode(struct v_dnode* dnode);
404 vfs_unref_dnode(struct v_dnode* dnode);
407 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
410 pcache_init(struct pcache* pcache);
413 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
416 pcache_new_page(struct pcache* pcache, u32_t index);
419 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
422 pcache_get_page(struct pcache* pcache,
425 struct pcache_pg** page);
428 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
431 pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
434 pcache_release(struct pcache* pcache);
437 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
440 pcache_commit_all(struct v_inode* inode);
443 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
451 mnt_mkbusy(struct v_mount* mnt);
459 mnt_chillax(struct v_mount* mnt);
462 vfs_mount_root(const char* fs_name, struct device* device);
465 vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point);
468 vfs_check_writable(struct v_dnode* dnode);
471 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
474 default_file_write(struct v_inode* inode,
480 default_file_readdir(struct v_file* file, struct dir_context* dctx);
483 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
486 default_inode_rename(struct v_inode* from_inode,
487 struct v_dnode* from_dnode,
488 struct v_dnode* to_dnode);
491 default_file_close(struct v_file* file);
494 default_file_seek(struct v_inode* inode, size_t offset);
497 default_inode_open(struct v_inode* this, struct v_file* file);
500 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
503 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
505 struct v_xattr_entry*
506 xattr_new(struct hstr* name);
508 struct v_xattr_entry*
509 xattr_getcache(struct v_inode* inode, struct hstr* name);
512 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
514 #endif /* __LUNAIX_VFS_H */