refactor: synchronize the vfs objects
[lunaix-os.git] / lunaix-os / includes / lunaix / fs.h
1 #ifndef __LUNAIX_VFS_H
2 #define __LUNAIX_VFS_H
3
4 #include <hal/ahci/hba.h>
5 #include <lunaix/block.h>
6 #include <lunaix/clock.h>
7 #include <lunaix/ds/btrie.h>
8 #include <lunaix/ds/hashtable.h>
9 #include <lunaix/ds/hstr.h>
10 #include <lunaix/ds/llist.h>
11 #include <lunaix/ds/lru.h>
12 #include <lunaix/ds/mutex.h>
13 #include <lunaix/status.h>
14 #include <stdatomic.h>
15
16 #define VFS_NAME_MAXLEN 128
17 #define VFS_MAX_FD 32
18
19 #define VFS_IFDIR 0x1
20 #define VFS_IFFILE 0x2
21 #define VFS_IFSEQDEV 0x4
22 #define VFS_IFVOLDEV 0x8
23 #define VFS_IFSYMLINK 0x16
24
25 #define VFS_WALK_MKPARENT 0x1
26 #define VFS_WALK_FSRELATIVE 0x2
27 #define VFS_WALK_PARENT 0x4
28 #define VFS_WALK_NOFOLLOW 0x4
29
30 #define FSTYPE_ROFS 0x1
31
32 #define VFS_VALID_CHAR(chr)                                                    \
33     (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') ||       \
34      ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' ||         \
35      (chr) == '-')
36
37 extern struct hstr vfs_ddot;
38 extern struct hstr vfs_dot;
39
40 struct v_dnode;
41 struct v_inode;
42 struct v_superblock;
43 struct v_file;
44 struct v_fd;
45 struct pcache;
46
47 struct filesystem
48 {
49     struct hlist_node fs_list;
50     struct hstr fs_name;
51     uint32_t types;
52     int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
53     int (*unmount)(struct v_superblock* vsb);
54 };
55
56 struct v_superblock
57 {
58     struct llist_header sb_list;
59     int fs_id;
60     bdev_t dev;
61     struct v_dnode* root;
62     struct filesystem* fs;
63     uint32_t iobuf_size;
64     struct
65     {
66         uint32_t (*read_capacity)(struct v_superblock* vsb);
67         uint32_t (*read_usage)(struct v_superblock* vsb);
68     } ops;
69 };
70
71 struct dir_context
72 {
73     int index;
74     void* cb_data;
75     void (*read_complete_callback)(struct dir_context* dctx,
76                                    const char* name,
77                                    const int len,
78                                    const int dtype);
79 };
80
81 struct v_file_ops
82 {
83     int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
84     int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
85     int (*readdir)(struct v_inode* inode, struct dir_context* dctx);
86     int (*seek)(struct v_inode* inode, size_t offset);
87     int (*rename)(struct v_inode* inode, char* new_name);
88     int (*close)(struct v_file* file);
89     int (*sync)(struct v_inode* inode);
90 };
91
92 struct v_file
93 {
94     struct v_inode* inode;
95     struct v_dnode* dnode;
96     struct llist_header* f_list;
97     uint32_t f_pos;
98     atomic_ulong ref_count;
99     struct v_file_ops ops;
100 };
101
102 struct v_fd
103 {
104     struct v_file* file;
105     int flags;
106 };
107
108 struct v_inode
109 {
110     mutex_t lock;
111     uint32_t itype;
112     time_t ctime;
113     time_t mtime;
114     time_t atime;
115     lba_t lb_addr;
116     uint32_t open_count;
117     uint32_t link_count;
118     uint32_t lb_usage;
119     uint32_t fsize;
120     struct pcache* pg_cache;
121     void* data; // 允许底层FS绑定他的一些专有数据
122     struct
123     {
124         int (*create)(struct v_inode* this, struct v_dnode* dnode);
125         int (*open)(struct v_inode* this, struct v_file* file);
126         int (*sync)(struct v_inode* this);
127         int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
128         int (*rmdir)(struct v_inode* this);
129         int (*unlink)(struct v_inode* this);
130         int (*link)(struct v_inode* this, struct v_dnode* new_name);
131         int (*read_symlink)(struct v_inode* this, const char** path_out);
132         int (*symlink)(struct v_inode* this, const char* target);
133         int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
134     } ops;
135     struct v_file_ops default_fops;
136 };
137
138 struct v_dnode
139 {
140     mutex_t lock; // sync the path walking
141     struct hstr name;
142     struct v_inode* inode;
143     struct v_dnode* parent;
144     struct hlist_node hash_list;
145     struct llist_header children;
146     struct llist_header siblings;
147     struct v_superblock* super_block;
148     atomic_ulong ref_count;
149     struct
150     {
151         void (*destruct)(struct v_dnode* dnode);
152     } ops;
153 };
154
155 struct v_fdtable
156 {
157     struct v_fd* fds[VFS_MAX_FD];
158 };
159
160 struct pcache_pg
161 {
162     struct llist_header pg_list;
163     struct llist_header dirty_list;
164     struct lru_node lru;
165     void* pg;
166     uint32_t flags;
167     uint32_t fpos;
168 };
169
170 struct pcache
171 {
172     struct v_inode* master;
173     struct btrie tree;
174     struct llist_header pages;
175     struct llist_header dirty;
176     uint32_t n_dirty;
177     uint32_t n_pages;
178 };
179
180 /* --- file system manager --- */
181 void
182 fsm_init();
183
184 void
185 fsm_register(struct filesystem* fs);
186
187 struct filesystem*
188 fsm_get(const char* fs_name);
189
190 void
191 vfs_init();
192
193 struct v_dnode*
194 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
195
196 void
197 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
198
199 int
200 vfs_walk(struct v_dnode* start,
201          const char* path,
202          struct v_dnode** dentry,
203          struct hstr* component,
204          int walk_options);
205
206 int
207 vfs_mount(const char* target, const char* fs_name, bdev_t device);
208
209 int
210 vfs_unmount(const char* target);
211
212 int
213 vfs_mount_at(const char* fs_name, bdev_t device, struct v_dnode* mnt_point);
214
215 int
216 vfs_unmount_at(struct v_dnode* mnt_point);
217
218 int
219 vfs_mkdir(const char* path, struct v_dnode** dentry);
220
221 int
222 vfs_open(struct v_dnode* dnode, struct v_file** file);
223
224 int
225 vfs_close(struct v_file* file);
226
227 int
228 vfs_fsync(struct v_file* file);
229
230 struct v_superblock*
231 vfs_sb_alloc();
232
233 void
234 vfs_sb_free(struct v_superblock* sb);
235
236 struct v_dnode*
237 vfs_d_alloc();
238
239 void
240 vfs_d_free(struct v_dnode* dnode);
241
242 struct v_inode*
243 vfs_i_alloc();
244
245 void
246 vfs_i_free(struct v_inode* inode);
247
248 int
249 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
250
251 void
252 pcache_init(struct pcache* pcache);
253
254 void
255 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
256
257 struct pcache_pg*
258 pcache_new_page(struct pcache* pcache, uint32_t index);
259
260 void
261 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
262
263 struct pcache_pg*
264 pcache_get_page(struct pcache* pcache,
265                 uint32_t index,
266                 uint32_t* offset,
267                 struct pcache_pg** page);
268
269 int
270 pcache_write(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
271
272 int
273 pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos);
274
275 void
276 pcache_release(struct pcache* pcache);
277
278 int
279 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
280
281 void
282 pcache_commit_all(struct v_inode* inode);
283
284 void
285 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
286 #endif /* __LUNAIX_VFS_H */