1 /** 2 * @file VFS.h 3 * @author fslongjin (longjin@RinGoTek.cn) 4 * @brief 虚拟文件系统 5 * @version 0.1 6 * @date 2022-04-20 7 * 8 * @copyright Copyright (c) 2022 9 * 10 */ 11 12 #pragma once 13 14 #include <common/blk_types.h> 15 #include <common/fcntl.h> 16 #include <common/glib.h> 17 #include <common/lockref.h> 18 #include <common/user_namespace.h> 19 #include <mm/slab.h> 20 21 extern struct vfs_superblock_t *vfs_root_sb; 22 23 #define VFS_DPT_MBR 0 // MBR分区表 24 #define VFS_DPT_GPT 1 // GPT分区表 25 26 #define VFS_MAX_PATHLEN 1024 27 28 /** 29 * @brief inode的属性 30 * 31 */ 32 #define VFS_IF_FILE (1UL << 0) 33 #define VFS_IF_DIR (1UL << 1) // 文件夹 34 #define VFS_IF_DEVICE (1UL << 2) 35 #define VFS_IF_DEAD (1UL << 3) /* removed, but still open directory */ 36 37 struct vfs_super_block_operations_t; 38 struct vfs_inode_operations_t; 39 40 struct vfs_index_node_t; 41 struct vfs_dir_entry_operations_t; 42 43 #define VFS_DF_MOUNTED (1 << 0) // 当前dentry是一个挂载点 44 #define VFS_DF_CANNOT_MOUNT (1 << 1) // 当前dentry是一个挂载点 45 struct vfs_dir_entry_t 46 { 47 char *name; 48 int name_length; // 名字的长度(不包含字符串末尾的'\0') 49 uint32_t d_flags; // dentry标志位 50 struct List child_node_list; 51 struct List subdirs_list; 52 53 struct lockref lockref; // 该lockref包含了dentry的自旋锁以及引用计数 54 struct vfs_index_node_t *dir_inode; 55 struct vfs_dir_entry_t *parent; 56 struct vfs_dir_entry_operations_t *dir_ops; 57 }; 58 59 struct vfs_superblock_t 60 { 61 struct vfs_dir_entry_t *root; 62 struct vfs_super_block_operations_t *sb_ops; 63 struct vfs_dir_entry_operations_t *dir_ops; // dentry's operations 64 struct block_device *blk_device; 65 void *private_sb_info; 66 }; 67 68 /** 69 * @brief inode结构体 70 * 71 */ 72 struct vfs_index_node_t 73 { 74 uint64_t file_size; // 文件大小 75 uint64_t blocks; // 占用的扇区数 76 uint64_t attribute; 77 struct lockref lockref; // 自旋锁与引用计数 78 79 struct vfs_superblock_t *sb; 80 struct vfs_file_operations_t *file_ops; 81 struct vfs_inode_operations_t *inode_ops; 82 83 void *private_inode_info; 84 }; 85 86 /** 87 * @brief 文件的mode 88 * 89 */ 90 #define VFS_FILE_MODE_READ (1 << 0) 91 #define VFS_FILE_MODE_WRITE (1 << 1) 92 #define VFS_FILE_MODE_RW (VFS_FILE_MODE_READ | VFS_FILE_MODE_WRITE) 93 94 #define vfs_file_can_read(file) (((file)->mode) & VFS_FILE_MODE_READ) 95 #define vfs_file_can_write(file) (((file)->mode) & VFS_FILE_MODE_WRITE) 96 #define vfs_file_can_rw(file) ((((file)->mode) & VFS_FILE_MODE_RW) == VFS_FILE_MODE_RW) 97 98 /** 99 * @brief 文件描述符 100 * 101 */ 102 struct vfs_file_t 103 { 104 long position; 105 uint64_t mode; 106 107 struct vfs_dir_entry_t *dEntry; 108 struct vfs_file_operations_t *file_ops; 109 void *private_data; 110 }; 111 112 struct vfs_filesystem_type_t 113 { 114 char *name; 115 int fs_flags; 116 struct vfs_superblock_t *(*read_superblock)( 117 struct block_device *blk); // 解析文件系统引导扇区的函数,为文件系统创建超级块结构。 118 struct vfs_filesystem_type_t *next; 119 }; 120 121 struct vfs_super_block_operations_t 122 { 123 void (*write_superblock)(struct vfs_superblock_t *sb); // 将超级块信息写入磁盘 124 void (*put_superblock)(struct vfs_superblock_t *sb); 125 void (*write_inode)(struct vfs_index_node_t *inode); // 将inode信息写入磁盘 126 }; 127 128 /** 129 * @brief 对vfs的inode的操作抽象 130 * 131 */ 132 struct vfs_inode_operations_t 133 { 134 /** 135 * @brief 创建新的文件 136 * @param parent_inode 父目录的inode结构体 137 * @param dest_dEntry 新文件的dentry 138 * @param mode 创建模式 139 */ 140 long (*create)(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode); 141 /** 142 * @brief 在文件系统中查找指定的目录项 143 * @param parent_inode 父目录项(在这个目录下查找) 144 * @param dest_dEntry 构造的目标目录项的结构体(传入名称,然后更多的详细信息将在本函数中完成填写) 145 * 146 */ 147 struct vfs_dir_entry_t *(*lookup)(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry); 148 /** 149 * @brief 创建文件夹 150 * @param inode 父目录的inode 151 * @param dEntry 新的文件夹的dentry 152 * @param mode 创建文件夹的mode 153 */ 154 long (*mkdir)(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode); 155 long (*rmdir)(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry); 156 long (*rename)(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry, 157 struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry); 158 long (*getAttr)(struct vfs_dir_entry_t *dEntry, uint64_t *attr); 159 long (*setAttr)(struct vfs_dir_entry_t *dEntry, uint64_t *attr); 160 161 /** 162 * @brief 取消inode和dentry之间的链接关系(删除文件) 163 * 164 * @param inode 要被取消关联关系的目录项的【父目录项】 165 * @param dentry 要被取消关联关系的子目录项 166 */ 167 long (*unlink)(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dentry); 168 }; 169 170 struct vfs_dir_entry_operations_t 171 { 172 long (*compare)(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename); 173 long (*hash)(struct vfs_dir_entry_t *dEntry, char *filename); 174 long (*release)(struct vfs_dir_entry_t *dEntry); 175 long (*iput)(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode); 176 }; 177 178 /** 179 * @brief 填充dirent的函数指针的类型定义 180 * 181 */ 182 typedef int (*vfs_filldir_t)(void *buf, ino_t d_ino, char *name, int namelen, unsigned char type, off_t offset); 183 184 struct vfs_file_operations_t 185 { 186 long (*open)(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr); 187 long (*close)(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr); 188 long (*read)(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position); 189 long (*write)(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position); 190 long (*lseek)(struct vfs_file_t *file_ptr, long offset, long origin); 191 long (*ioctl)(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg); 192 193 long (*readdir)(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler); // 读取文件夹 194 }; 195 196 /** 197 * @brief 在VFS中注册文件系统 198 * 199 * @param fs 文件系统类型结构体 200 * @return uint64_t 201 */ 202 uint64_t vfs_register_filesystem(struct vfs_filesystem_type_t *fs); 203 uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs); 204 205 /** 206 * @brief 挂载文件系统 207 * 208 * @param path 要挂载到的路径 209 * @param name 文件系统名 210 * @param blk 块设备结构体 211 * @return struct vfs_superblock_t* 挂载后,文件系统的超级块 212 */ 213 struct vfs_superblock_t *vfs_mount_fs(const char *path, char *name, struct block_device *blk); 214 215 /** 216 * @brief 按照路径查找文件 217 * 218 * @param path 路径 219 * @param flags 1:返回父目录项, 0:返回结果目录项 220 * @return struct vfs_dir_entry_t* 目录项 221 */ 222 struct vfs_dir_entry_t *vfs_path_walk(const char *path, uint64_t flags); 223 224 /** 225 * @brief 填充dentry 226 * 227 */ 228 int vfs_fill_dirent(void *buf, ino_t d_ino, char *name, int namelen, unsigned char type, off_t offset); 229 230 /** 231 * @brief 初始化vfs 232 * 233 * @return int 错误码 234 */ 235 int vfs_init(); 236 237 /** 238 * @brief 动态分配dentry以及路径字符串名称 239 * 240 * @param name_size 名称字符串大小(字节)(注意考虑字符串最后需要有一个‘\0’作为结尾) 241 * @return struct vfs_dir_entry_t* 创建好的dentry 242 */ 243 struct vfs_dir_entry_t *vfs_alloc_dentry(const int name_size); 244 245 /** 246 * @brief 分配inode并将引用计数初始化为1 247 * 248 * @return struct vfs_index_node_t * 分配得到的inode 249 */ 250 struct vfs_index_node_t *vfs_alloc_inode(); 251 252 uint64_t do_open(const char *filename, int flags, bool from_user); 253 254 /** 255 * @brief 关闭文件 256 * 257 * @param fd_num 文件描述符 258 * @return uint64_t 错误码 259 */ 260 uint64_t vfs_close(int fd_num); 261 262 /** 263 * @brief 创建文件夹 264 * 265 * @param path 文件夹路径 266 * @param mode 创建模式 267 * @param from_userland 该创建请求是否来自用户态 268 * @return int64_t 错误码 269 */ 270 int64_t vfs_mkdir(const char *path, mode_t mode, bool from_userland); 271 272 /** 273 * @brief 删除文件夹 274 * 275 * @param path 文件夹路径 276 * @param from_userland 请求是否来自用户态 277 * @return int64_t 错误码 278 */ 279 int64_t vfs_rmdir(const char *path, bool from_userland); 280 281 /** 282 * @brief 释放dentry,并视情况自动释放inode。 在调用该函数前,需要将dentry加锁。 283 * 284 * @param dentry 目标dentry 285 * 286 * @return 错误码 287 * 注意,当dentry指向文件时,如果返回值为正数,则表示在释放了该dentry后,该dentry指向的inode的引用计数。 288 */ 289 int vfs_dentry_put(struct vfs_dir_entry_t *dentry); 290 291 int vfs_unlink(struct user_namespace *mnt_userns, struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dentry, 292 struct vfs_index_node_t **delegated_inode); 293 294 int do_unlink_at(int dfd, const char *pathname, bool name);