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