feat: symlink(2) and realpathat syscall
[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 #define VFS_INODE_TYPE_SYMLINK 0x8
18
19 #define VFS_ENOFS -2
20 #define VFS_EBADMNT -3
21
22 #define VFS_EENDOFDIR -5
23
24 #define VFS_EINVLD -8
25 #define VFS_EEOF -9
26
27 #define VFS_WALK_MKPARENT 0x1
28 #define VFS_WALK_FSRELATIVE 0x2
29 #define VFS_WALK_PARENT 0x4
30 #define VFS_WALK_NOFOLLOW 0x4
31
32 #define VFS_IOBUF_FDIRTY 0x1
33
34 #define FSTYPE_ROFS 0x1
35
36 #define VFS_VALID_CHAR(chr)                                                    \
37     ('A' <= (chr) && (chr) <= 'Z' || 'a' <= (chr) && (chr) <= 'z' ||           \
38      '0' <= (chr) && (chr) <= '9' || (chr) == '.' || (chr) == '_' ||           \
39      (chr) == '-')
40
41 extern struct hstr vfs_ddot;
42 extern struct hstr vfs_dot;
43
44 struct v_dnode;
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     bdev_t 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_file* file, void* buffer, size_t len);
83     int (*read)(struct v_file* file, void* buffer, size_t len);
84     int (*readdir)(struct v_file* file, struct dir_context* dctx);
85     int (*seek)(struct v_file* file, size_t offset);
86     int (*rename)(struct v_file* file, char* new_name);
87     int (*close)(struct v_file* file);
88     int (*sync)(struct v_file* file);
89 };
90
91 struct v_file
92 {
93     struct v_inode* inode;
94     struct v_dnode* dnode;
95     struct llist_header* f_list;
96     uint32_t f_pos;
97     void* data; // 允许底层FS绑定他的一些专有数据
98     struct v_file_ops ops;
99 };
100
101 struct v_fd
102 {
103     struct v_file* file;
104     int pos;
105     int flags;
106 };
107
108 struct v_inode
109 {
110     uint32_t itype;
111     uint32_t ctime;
112     uint32_t mtime;
113     uint64_t lb_addr;
114     uint32_t open_count;
115     uint32_t link_count;
116     uint32_t lb_usage;
117     uint32_t fsize;
118     void* data; // 允许底层FS绑定他的一些专有数据
119     struct
120     {
121         int (*create)(struct v_inode* this, struct v_file* file);
122         int (*open)(struct v_inode* this, struct v_file* file);
123         int (*sync)(struct v_inode* this);
124         int (*mkdir)(struct v_inode* this, struct v_dnode* dnode);
125         int (*rmdir)(struct v_inode* this);
126         int (*unlink)(struct v_inode* this);
127         int (*link)(struct v_inode* this, struct v_dnode* new_name);
128         int (*read_symlink)(struct v_inode* this, const char** path_out);
129         int (*symlink)(struct v_inode* this, const char* target);
130         int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode);
131     } ops;
132 };
133
134 struct v_dnode
135 {
136     struct hstr name;
137     struct v_inode* inode;
138     struct v_dnode* parent;
139     struct hlist_node hash_list;
140     struct llist_header children;
141     struct llist_header siblings;
142     struct v_superblock* super_block;
143     struct
144     {
145         void (*destruct)(struct v_dnode* dnode);
146     } ops;
147 };
148
149 struct v_fdtable
150 {
151     struct v_fd* fds[VFS_MAX_FD];
152 };
153
154 /* --- file system manager --- */
155 void
156 fsm_init();
157
158 void
159 fsm_register(struct filesystem* fs);
160
161 struct filesystem*
162 fsm_get(const char* fs_name);
163
164 void
165 vfs_init();
166
167 struct v_dnode*
168 vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
169
170 void
171 vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode);
172
173 int
174 vfs_walk(struct v_dnode* start,
175          const char* path,
176          struct v_dnode** dentry,
177          struct hstr* component,
178          int walk_options);
179
180 int
181 vfs_mount(const char* target, const char* fs_name, bdev_t device);
182
183 int
184 vfs_unmount(const char* target);
185
186 int
187 vfs_mount_at(const char* fs_name, bdev_t device, struct v_dnode* mnt_point);
188
189 int
190 vfs_unmount_at(struct v_dnode* mnt_point);
191
192 int
193 vfs_mkdir(const char* path, struct v_dnode** dentry);
194
195 int
196 vfs_open(struct v_dnode* dnode, struct v_file** file);
197
198 int
199 vfs_close(struct v_file* file);
200
201 int
202 vfs_fsync(struct v_file* file);
203
204 struct v_superblock*
205 vfs_sb_alloc();
206
207 void
208 vfs_sb_free(struct v_superblock* sb);
209
210 struct v_dnode*
211 vfs_d_alloc();
212
213 void
214 vfs_d_free(struct v_dnode* dnode);
215
216 struct v_inode*
217 vfs_i_alloc();
218
219 void
220 vfs_i_free(struct v_inode* inode);
221 #endif /* __LUNAIX_VFS_H */