fcca8abaa513c4caee6917d04432c56521186ba2
[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/llist.h>
10 #include <lunaix/ds/lru.h>
11 #include <lunaix/ds/mutex.h>
12 #include <lunaix/status.h>
13 #include <stdatomic.h>
14
15 #define VFS_NAME_MAXLEN 128
16 #define VFS_MAX_FD 32
17
18 #define VFS_IFDIR 0x1
19 #define VFS_IFFILE 0x2
20 #define VFS_IFSEQDEV 0x4
21 #define VFS_IFVOLDEV 0x8
22 #define VFS_IFSYMLINK 0x16
23
24 #define VFS_WALK_MKPARENT 0x1
25 #define VFS_WALK_FSRELATIVE 0x2
26 #define VFS_WALK_PARENT 0x4
27 #define VFS_WALK_NOFOLLOW 0x4
28
29 #define FSTYPE_ROFS 0x1
30
31 #define VFS_VALID_CHAR(chr)                                                    \
32     (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') ||       \
33      ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' ||         \
34      (chr) == '-')
35
36 extern struct hstr vfs_ddot;
37 extern struct hstr vfs_dot;
38
39 struct v_dnode;
40 struct v_inode;
41 struct v_superblock;
42 struct v_file;
43 struct v_fd;
44 struct pcache;
45
46 struct filesystem
47 {
48     struct hlist_node fs_list;
49     struct hstr fs_name;
50     uint32_t types;
51     int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point);
52     int (*unmount)(struct v_superblock* vsb);
53 };
54
55 struct v_superblock
56 {
57     struct llist_header sb_list;
58     int fs_id;
59     struct device* dev;
60     struct v_dnode* root;
61     struct filesystem* fs;
62     uint32_t iobuf_size;
63     struct
64     {
65         uint32_t (*read_capacity)(struct v_superblock* vsb);
66         uint32_t (*read_usage)(struct v_superblock* vsb);
67     } ops;
68 };
69
70 struct dir_context
71 {
72     int index;
73     void* cb_data;
74     void (*read_complete_callback)(struct dir_context* dctx,
75                                    const char* name,
76                                    const int len,
77                                    const int dtype);
78 };
79
80 struct v_file_ops
81 {
82     int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
83     int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
84     int (*readdir)(struct v_inode* inode, struct dir_context* dctx);
85     int (*seek)(struct v_inode* inode, size_t offset);
86     int (*close)(struct v_file* file);
87     int (*sync)(struct v_inode* inode);
88 };
89
90 struct v_file
91 {
92     struct v_inode* inode;
93     struct v_dnode* dnode;
94     struct llist_header* f_list;
95     uint32_t f_pos;
96     atomic_ulong ref_count;
97     struct v_file_ops ops;
98 };
99
100 struct v_fd
101 {
102     struct v_file* file;
103     int flags;
104 };
105
106 struct v_inode
107 {
108     uint32_t id;
109     mutex_t lock;
110     uint32_t itype;
111     time_t ctime;
112     time_t mtime;
113     time_t atime;
114     lba_t lb_addr;
115     uint32_t open_count;
116     uint32_t link_count;
117     uint32_t lb_usage;
118     uint32_t fsize;
119     struct pcache* pg_cache;
120     void* data; // 允许底层FS绑定他的一些专有数据
121     struct
122     {
123         int (*create)(struct v_inode* this, struct v_dnode* dnode);
124         int (*open)(struct v_inode* this, struct v_file* file);
125         int (*sync)(struct v_inode* this);
126         int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
127         int (*rmdir)(struct v_inode* this);
128         int (*unlink)(struct v_inode* this);
129         int (*link)(struct v_inode* this, struct v_dnode* new_name);
130         int (*read_symlink)(struct v_inode* this, const char** path_out);
131         int (*symlink)(struct v_inode* this, const char* target);
132         int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
133         int (*rename)(struct v_inode* from_inode,
134                       struct v_dnode* from_dnode,
135                       struct v_dnode* to_dnode);
136     } ops;
137     struct v_file_ops default_fops;
138 };
139
140 struct v_dnode
141 {
142     mutex_t lock; // sync the path walking
143     struct hstr name;
144     struct v_inode* inode;
145     struct v_dnode* parent;
146     struct hlist_node hash_list;
147     struct llist_header children;
148     struct llist_header siblings;
149     struct v_superblock* super_block;
150     atomic_ulong ref_count;
151 };
152
153 struct v_fdtable
154 {
155     struct v_fd* fds[VFS_MAX_FD];
156 };
157
158 struct pcache_pg
159 {
160     struct llist_header pg_list;
161     struct llist_header dirty_list;
162     struct lru_node lru;
163     void* pg;
164     uint32_t flags;
165     uint32_t fpos;
166 };
167
168 struct pcache
169 {
170     struct v_inode* master;
171     struct btrie tree;
172     struct llist_header pages;
173     struct llist_header dirty;
174     uint32_t n_dirty;
175     uint32_t n_pages;
176 };
177
178 /* --- file system manager --- */
179 void
180 fsm_init();
181
182 void
183 fsm_register(struct filesystem* fs);
184
185 struct filesystem*
186 fsm_get(const char* fs_name);
187
188 void
189 vfs_init();
190
191 struct v_dnode*
192 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
193
194 void
195 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
196
197 int
198 vfs_walk(struct v_dnode* start,
199          const char* path,
200          struct v_dnode** dentry,
201          struct hstr* component,
202          int walk_options);
203
204 int
205 vfs_mount(const char* target, const char* fs_name, struct device* device);
206
207 int
208 vfs_unmount(const char* target);
209
210 int
211 vfs_mount_at(const char* fs_name,
212              struct device* device,
213              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 */