properly update the pprev of next node when deleting hlist_node (close #30)
[lunaix-os.git] / lunaix-os / includes / lunaix / fs.h
1 #ifndef __LUNAIX_VFS_H
2 #define __LUNAIX_VFS_H
3
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/ldga.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
15 #include <stdatomic.h>
16
17 #include <usr/lunaix/fstypes.h>
18
19 #define VFS_NAME_MAXLEN 128
20 #define VFS_MAX_FD 32
21
22 #define VFS_IFDIR F_DIR
23 #define VFS_IFFILE F_FILE
24 #define VFS_IFDEV (F_DEV | F_FILE)
25 #define VFS_IFSEQDEV (F_SEQDEV | F_FILE)
26 #define VFS_IFVOLDEV (F_VOLDEV | F_FILE)
27 #define VFS_IFSYMLINK (F_SYMLINK | F_FILE)
28
29 #define VFS_DEVFILE(type) ((type) & F_DEV)
30 #define VFS_DEVTYPE(type) ((type) & ((F_SEQDEV | F_VOLDEV) ^ F_DEV))
31
32 // Walk, mkdir if component encountered is non-exists.
33 #define VFS_WALK_MKPARENT 0x1
34
35 // Walk, relative to current FS.
36 #define VFS_WALK_FSRELATIVE 0x2
37
38 /*
39     Terminate the walk on the immediate parent,
40     name of child (last component) is returned through `component`
41 */
42 #define VFS_WALK_PARENT 0x4
43
44 // Do not follow the symbolic link
45 #define VFS_WALK_NOFOLLOW 0x8
46
47 #define VFS_HASHTABLE_BITS 10
48 #define VFS_HASHTABLE_SIZE (1 << VFS_HASHTABLE_BITS)
49 #define VFS_HASH_MASK (VFS_HASHTABLE_SIZE - 1)
50 #define VFS_HASHBITS (32 - VFS_HASHTABLE_BITS)
51
52 #define VFS_PATH_DELIM '/'
53
54 #define FSTYPE_ROFS 0x1
55
56 #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD)
57
58 #define EXPORT_FILE_SYSTEM(fs_id, init_fn)                                     \
59     export_ldga_el(fs, fs_id, ptr_t, init_fn)
60
61 #define VFS_VALID_CHAR(chr)                                                    \
62     (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') ||       \
63      ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' ||         \
64      (chr) == '-' || (chr) == ':')
65
66 #define unlock_inode(inode) mutex_unlock(&inode->lock)
67 #define lock_inode(inode)                                                      \
68     ({                                                                         \
69         mutex_lock(&inode->lock);                                              \
70         lru_use_one(inode_lru, &inode->lru);                                   \
71     })
72
73 #define unlock_dnode(dnode) mutex_unlock(&dnode->lock)
74 #define lock_dnode(dnode)                                                      \
75     ({                                                                         \
76         mutex_lock(&dnode->lock);                                              \
77         lru_use_one(dnode_lru, &dnode->lru);                                   \
78     })
79
80 typedef u32_t inode_t;
81
82 struct v_dnode;
83 struct v_inode;
84 struct v_superblock;
85 struct v_file;
86 struct v_file_ops;
87 struct v_inode_ops;
88 struct v_fd;
89 struct pcache;
90 struct v_xattr_entry;
91
92 extern struct v_file_ops default_file_ops;
93 extern struct v_inode_ops default_inode_ops;
94
95 extern struct hstr vfs_ddot;
96 extern struct hstr vfs_dot;
97 extern struct v_dnode* vfs_sysroot;
98
99 struct filesystem
100 {
101     struct llist_header fs_flat;
102     struct hlist_node fs_list;
103     struct hstr fs_name;
104     u32_t types;
105     int fs_id;
106     int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
107     int (*unmount)(struct v_superblock* vsb);
108 };
109
110 struct v_superblock
111 {
112     struct llist_header sb_list;
113     struct device* dev;
114     struct v_dnode* root;
115     struct filesystem* fs;
116     struct hbucket* i_cache;
117     void* data;
118     size_t blksize;
119     struct
120     {
121         u32_t (*read_capacity)(struct v_superblock* vsb);
122         u32_t (*read_usage)(struct v_superblock* vsb);
123         void (*init_inode)(struct v_superblock* vsb, struct v_inode* inode);
124     } ops;
125 };
126
127 struct dir_context
128 {
129     int index;
130     void* cb_data;
131     void (*read_complete_callback)(struct dir_context* dctx,
132                                    const char* name,
133                                    const int len,
134                                    const int dtype);
135 };
136
137 struct v_file_ops
138 {
139     int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
140     int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
141
142     // for operatiosn {write|read}_page, following are true:
143     //  + `len` always equals to PG_SIZE
144     //  + `fpos` always PG_SIZE aligned.
145     // These additional operations allow underlying fs to use more specialized
146     // and optimized code.
147
148     int (*write_page)(struct v_inode* inode, void* pg, size_t fpos);
149     int (*read_page)(struct v_inode* inode, void* pg, size_t fpos);
150
151     int (*readdir)(struct v_file* file, struct dir_context* dctx);
152     int (*seek)(struct v_inode* inode, size_t offset); // optional
153     int (*close)(struct v_file* file);
154     int (*sync)(struct v_file* file);
155 };
156
157 struct v_inode_ops
158 {
159     int (*create)(struct v_inode* this, struct v_dnode* dnode);
160     int (*open)(struct v_inode* this, struct v_file* file);
161     int (*sync)(struct v_inode* this);
162     int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
163     int (*rmdir)(struct v_inode* this, struct v_dnode* dir);
164     int (*unlink)(struct v_inode* this);
165     int (*link)(struct v_inode* this, struct v_dnode* new_name);
166     int (*read_symlink)(struct v_inode* this, const char** path_out);
167     int (*set_symlink)(struct v_inode* this, const char* target);
168     int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
169     int (*rename)(struct v_inode* from_inode,
170                   struct v_dnode* from_dnode,
171                   struct v_dnode* to_dnode);
172     int (*getxattr)(struct v_inode* this,
173                     struct v_xattr_entry* entry); // optional
174     int (*setxattr)(struct v_inode* this,
175                     struct v_xattr_entry* entry); // optional
176     int (*delxattr)(struct v_inode* this,
177                     struct v_xattr_entry* entry); // optional
178 };
179
180 struct v_xattr_entry
181 {
182     struct llist_header entries;
183     struct hstr name;
184     const void* value;
185     size_t len;
186 };
187
188 struct v_file
189 {
190     struct v_inode* inode;
191     struct v_dnode* dnode;
192     struct llist_header* f_list;
193     u32_t f_pos;
194     atomic_ulong ref_count;
195     struct v_file_ops* ops; // for caching
196 };
197
198 struct v_fd
199 {
200     struct v_file* file;
201     int flags;
202 };
203
204 //  [v_inode::aka_nodes]
205 //  how do we invalidate corresponding v_dnodes given the v_inode?
206 /*
207     Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow
208     info of every process being accessible via file system. Each process's
209     creation will result a creation of a directory under the root of task fs
210     with it's pid as name. But that dir must delete when process is killed, and
211     such deletion does not mediated by vfs itself, so there is a need of cache
212     syncing.
213     And this is also the case of all ramfs where argumentation to file tree is
214     performed by third party.
215 */
216
217 struct v_inode
218 {
219     inode_t id;
220     mutex_t lock;
221     u32_t itype;
222     time_t ctime;
223     time_t mtime;
224     time_t atime;
225     lba_t lb_addr;
226     u32_t open_count;
227     u32_t link_count;
228     u32_t lb_usage;
229     u32_t fsize;
230     void* data; // 允许底层FS绑定他的一些专有数据
231     struct llist_header aka_dnodes;
232     struct llist_header xattrs;
233     struct v_superblock* sb;
234     struct hlist_node hash_list;
235     struct lru_node lru;
236     struct pcache* pg_cache;
237     struct v_inode_ops* ops;
238     struct v_file_ops* default_fops;
239
240     void (*destruct)(struct v_inode* inode);
241 };
242
243 struct v_mount
244 {
245     mutex_t lock;
246     struct llist_header list;
247     struct llist_header submnts;
248     struct llist_header sibmnts;
249     struct v_mount* parent;
250     struct v_dnode* mnt_point;
251     struct v_superblock* super_block;
252     u32_t busy_counter;
253     int flags;
254 };
255
256 struct v_dnode
257 {
258     mutex_t lock; // sync the path walking
259     struct lru_node lru;
260     struct hstr name;
261     struct v_inode* inode;
262     struct v_dnode* parent;
263     struct hlist_node hash_list;
264     struct llist_header aka_list;
265     struct llist_header children;
266     struct llist_header siblings;
267     struct v_superblock* super_block;
268     struct v_mount* mnt;
269     atomic_ulong ref_count;
270
271     void* data;
272 };
273
274 struct v_fdtable
275 {
276     struct v_fd* fds[VFS_MAX_FD];
277 };
278
279 struct pcache
280 {
281     struct v_inode* master;
282     struct btrie tree;
283     struct llist_header pages;
284     struct llist_header dirty;
285     u32_t n_dirty;
286     u32_t n_pages;
287 };
288
289 struct pcache_pg
290 {
291     struct llist_header pg_list;
292     struct llist_header dirty_list;
293     struct lru_node lru;
294     struct pcache* holder;
295     void* pg;
296     u32_t flags;
297     u32_t fpos;
298     u32_t len;
299 };
300
301 void
302 fsm_init();
303
304 void
305 fsm_register_all();
306
307 struct filesystem*
308 fsm_new_fs(char* name, size_t name_len);
309
310 void
311 fsm_register(struct filesystem* fs);
312
313 struct filesystem*
314 fsm_get(const char* fs_name);
315
316 void
317 vfs_init();
318
319 void
320 vfs_export_attributes();
321
322 struct v_dnode*
323 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
324
325 void
326 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
327
328 void
329 vfs_dcache_rehash(struct v_dnode* new_parent, struct v_dnode* dnode);
330
331 void
332 vfs_dcache_remove(struct v_dnode* dnode);
333
334 int
335 vfs_walk(struct v_dnode* start,
336          const char* path,
337          struct v_dnode** dentry,
338          struct hstr* component,
339          int walk_options);
340
341 int
342 vfs_walk_proc(const char* path,
343               struct v_dnode** dentry,
344               struct hstr* component,
345               int options);
346
347 int
348 vfs_mount(const char* target,
349           const char* fs_name,
350           struct device* device,
351           int options);
352
353 int
354 vfs_unmount(const char* target);
355
356 int
357 vfs_mount_at(const char* fs_name,
358              struct device* device,
359              struct v_dnode* mnt_point,
360              int options);
361
362 int
363 vfs_unmount_at(struct v_dnode* mnt_point);
364
365 int
366 vfs_mkdir(const char* path, struct v_dnode** dentry);
367
368 int
369 vfs_open(struct v_dnode* dnode, struct v_file** file);
370
371 int
372 vfs_pclose(struct v_file* file, pid_t pid);
373
374 int
375 vfs_close(struct v_file* file);
376
377 void
378 vfs_free_fd(struct v_fd* fd);
379
380 int
381 vfs_fsync(struct v_file* file);
382
383 void
384 vfs_assign_inode(struct v_dnode* assign_to, struct v_inode* inode);
385
386 struct v_superblock*
387 vfs_sb_alloc();
388
389 void
390 vfs_sb_free(struct v_superblock* sb);
391
392 struct v_dnode*
393 vfs_d_alloc();
394
395 void
396 vfs_d_free(struct v_dnode* dnode);
397
398 struct v_inode*
399 vfs_i_find(struct v_superblock* sb, u32_t i_id);
400
401 void
402 vfs_i_addhash(struct v_inode* inode);
403
404 struct v_inode*
405 vfs_i_alloc(struct v_superblock* sb);
406
407 void
408 vfs_i_free(struct v_inode* inode);
409
410 int
411 vfs_dup_fd(struct v_fd* old, struct v_fd** new);
412
413 int
414 vfs_getfd(int fd, struct v_fd** fd_s);
415
416 int
417 vfs_get_dtype(int itype);
418
419 void
420 vfs_ref_dnode(struct v_dnode* dnode);
421
422 void
423 vfs_ref_file(struct v_file* file);
424
425 void
426 vfs_unref_dnode(struct v_dnode* dnode);
427
428 int
429 vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth);
430
431 void
432 pcache_init(struct pcache* pcache);
433
434 void
435 pcache_release_page(struct pcache* pcache, struct pcache_pg* page);
436
437 struct pcache_pg*
438 pcache_new_page(struct pcache* pcache, u32_t index);
439
440 void
441 pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg);
442
443 int
444 pcache_get_page(struct pcache* pcache,
445                 u32_t index,
446                 u32_t* offset,
447                 struct pcache_pg** page);
448
449 int
450 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
451
452 int
453 pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos);
454
455 void
456 pcache_release(struct pcache* pcache);
457
458 int
459 pcache_commit(struct v_inode* inode, struct pcache_pg* page);
460
461 void
462 pcache_commit_all(struct v_inode* inode);
463
464 void
465 pcache_invalidate(struct pcache* pcache, struct pcache_pg* page);
466
467 /**
468  * @brief 将挂载点标记为繁忙
469  *
470  * @param mnt
471  */
472 void
473 mnt_mkbusy(struct v_mount* mnt);
474
475 /**
476  * @brief 将挂载点标记为清闲
477  *
478  * @param mnt
479  */
480 void
481 mnt_chillax(struct v_mount* mnt);
482
483 int
484 vfs_mount_root(const char* fs_name, struct device* device);
485
486 struct v_mount*
487 vfs_create_mount(struct v_mount* parent, struct v_dnode* mnt_point);
488
489 int
490 vfs_check_writable(struct v_dnode* dnode);
491
492 int
493 default_file_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
494
495 int
496 default_file_write(struct v_inode* inode,
497                    void* buffer,
498                    size_t len,
499                    size_t fpos);
500
501 int
502 default_file_read_page(struct v_inode* inode, void* buffer, size_t fpos);
503
504 int
505 default_file_write_page(struct v_inode* inode, void* buffer, size_t fpos);
506
507 int
508 default_file_readdir(struct v_file* file, struct dir_context* dctx);
509
510 int
511 default_inode_dirlookup(struct v_inode* this, struct v_dnode* dnode);
512
513 int
514 default_inode_rename(struct v_inode* from_inode,
515                      struct v_dnode* from_dnode,
516                      struct v_dnode* to_dnode);
517
518 int
519 default_file_close(struct v_file* file);
520
521 int
522 default_file_seek(struct v_inode* inode, size_t offset);
523
524 int
525 default_inode_open(struct v_inode* this, struct v_file* file);
526
527 int
528 default_inode_rmdir(struct v_inode* this, struct v_dnode* dir);
529
530 int
531 default_inode_mkdir(struct v_inode* this, struct v_dnode* dir);
532
533 struct v_xattr_entry*
534 xattr_new(struct hstr* name);
535
536 struct v_xattr_entry*
537 xattr_getcache(struct v_inode* inode, struct hstr* name);
538
539 void
540 xattr_addcache(struct v_inode* inode, struct v_xattr_entry* xattr);
541
542 #endif /* __LUNAIX_VFS_H */