1 #include "devfs.h"
2 #include "internal.h"
3 #include <filesystem/vfs/VFS.h>
4 #include <common/glib.h>
5 #include <common/string.h>
6 #include <mm/slab.h>
7 #include <common/spinlock.h>
8 #include <debug/bug.h>
9 
10 struct vfs_super_block_operations_t devfs_sb_ops;
11 struct vfs_dir_entry_operations_t devfs_dentry_ops;
12 struct vfs_file_operations_t devfs_file_ops;
13 struct vfs_inode_operations_t devfs_inode_ops;
14 
15 struct vfs_dir_entry_t *devfs_root_dentry; // 根结点的dentry
16 struct vfs_superblock_t devfs_sb = {0};
17 const char __devfs_mount_path[] = "/dev";
18 
19 static spinlock_t devfs_global_lock; // devfs的全局锁
20 static uint64_t __tmp_uuid = 0;      // devfs的临时uuid变量(todo:在引入uuid lib之后删除这里)
21 
__devfs_get_uuid()22 static inline uint64_t __devfs_get_uuid()
23 {
24     // todo : 更改为使用uuid库来生成uuid
25     return ++__tmp_uuid;
26 }
27 
28 /**
29  * @brief 创建devfs的super block
30  *
31  * @param blk 未使用(devfs为伪文件系统,不需要物理设备)
32  * @return struct vfs_superblock_t*
33  */
devfs_read_superblock(struct block_device * blk)34 struct vfs_superblock_t *devfs_read_superblock(struct block_device *blk)
35 {
36     devfs_sb.blk_device = NULL;
37     devfs_sb.root = devfs_root_dentry;
38     devfs_sb.sb_ops = &devfs_sb_ops;
39     devfs_sb.dir_ops = &devfs_dentry_ops;
40     // todo: 为devfs增加私有信息
41     devfs_sb.private_sb_info = NULL;
42     kdebug("devfs read superblock done");
43     return &devfs_sb;
44 }
45 
devfs_write_superblock(struct vfs_superblock_t * sb)46 static void devfs_write_superblock(struct vfs_superblock_t *sb) { return; }
47 
devfs_put_superblock(struct vfs_superblock_t * sb)48 static void devfs_put_superblock(struct vfs_superblock_t *sb) { return; }
49 
devfs_write_inode(struct vfs_index_node_t * inode)50 static void devfs_write_inode(struct vfs_index_node_t *inode) { return; }
51 struct vfs_super_block_operations_t devfs_sb_ops =
52     {
53         .write_superblock = &devfs_write_superblock,
54         .put_superblock = &devfs_put_superblock,
55         .write_inode = &devfs_write_inode,
56 };
57 
devfs_compare(struct vfs_dir_entry_t * parent_dEntry,char * source_filename,char * dest_filename)58 static long devfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename) { return 0; }
59 
devfs_hash(struct vfs_dir_entry_t * dEntry,char * filename)60 static long devfs_hash(struct vfs_dir_entry_t *dEntry, char *filename) { return 0; }
61 
devfs_release(struct vfs_dir_entry_t * dEntry)62 static long devfs_release(struct vfs_dir_entry_t *dEntry) { return 0; }
63 
devfs_iput(struct vfs_dir_entry_t * dEntry,struct vfs_index_node_t * inode)64 static long devfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) { return 0; }
65 
66 struct vfs_dir_entry_operations_t devfs_dentry_ops =
67     {
68         .compare = &devfs_compare,
69         .hash = &devfs_hash,
70         .release = &devfs_release,
71         .iput = &devfs_iput,
72 };
73 
devfs_open(struct vfs_index_node_t * inode,struct vfs_file_t * file_ptr)74 static long devfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
75 {
76     return 0;
77 }
devfs_close(struct vfs_index_node_t * inode,struct vfs_file_t * file_ptr)78 static long devfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) { return 0; }
devfs_read(struct vfs_file_t * file_ptr,char * buf,int64_t count,long * position)79 static long devfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; }
devfs_write(struct vfs_file_t * file_ptr,char * buf,int64_t count,long * position)80 static long devfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; }
devfs_lseek(struct vfs_file_t * file_ptr,long offset,long origin)81 static long devfs_lseek(struct vfs_file_t *file_ptr, long offset, long origin) { return 0; }
devfs_ioctl(struct vfs_index_node_t * inode,struct vfs_file_t * file_ptr,uint64_t cmd,uint64_t arg)82 static long devfs_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg) { return 0; }
83 
devfs_readdir(struct vfs_file_t * file_ptr,void * dirent,vfs_filldir_t filler)84 static long devfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler)
85 {
86     // 循环读取目录下的目录项
87     struct vfs_dir_entry_t *dentry = file_ptr->dEntry;
88     struct List *list = &dentry->subdirs_list;
89     // 先切换到position处
90     for (int i = 0; i <= file_ptr->position; ++i)
91     {
92         list = list_next(list);
93         if (list == &dentry->subdirs_list) // 找完了
94             goto failed;
95     }
96 
97     // 存在目录项
98     // 增加偏移量
99     ++file_ptr->position;
100     // 获取目标dentry(由于是子目录项,因此是child_node_list)
101     struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list);
102     // kdebug("target name=%s, namelen=%d", target_dent->name, target_dent->name_length);
103 
104     char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
105     strncpy(name, target_dent->name, target_dent->name_length);
106     uint32_t dentry_type;
107     if (target_dent->dir_inode->attribute & VFS_IF_DIR)
108         dentry_type = VFS_IF_DIR;
109     else
110         dentry_type = VFS_IF_DEVICE;
111 
112     return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1);
113 failed:;
114     return 0;
115 }
116 
117 struct vfs_file_operations_t devfs_file_ops =
118     {
119         .open = &devfs_open,
120         .close = &devfs_close,
121         .read = &devfs_read,
122         .write = &devfs_write,
123         .lseek = &devfs_lseek,
124         .ioctl = &devfs_ioctl,
125         .readdir = &devfs_readdir,
126 };
127 
128 /**
129  * @brief 创建新的文件
130  * @param parent_inode 父目录的inode结构体
131  * @param dest_dEntry 新文件的dentry
132  * @param mode 创建模式
133  */
devfs_create(struct vfs_index_node_t * parent_inode,struct vfs_dir_entry_t * dest_dEntry,int mode)134 static long devfs_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode)
135 {
136     return 0;
137 }
138 
devfs_lookup(struct vfs_index_node_t * parent_inode,struct vfs_dir_entry_t * dest_dEntry)139 static struct vfs_dir_entry_t *devfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry)
140 {
141     /*
142         由于devfs是伪文件系统,其所有的搜索都依赖于dentry缓存。
143         因此,不需要根据inode来搜索目标目录项。除非目录项不存在,否则不会调用这个函数。
144         当本函数调用的时候,也就意味着devfs中没有这个文件/文件夹。
145         综上,本函数直接返回NULL即可
146     */
147     return NULL;
148 }
149 /**
150  * @brief 在devfs中创建文件夹(作用是完善子文件夹的inode信息)
151  *
152  * @param inode 父目录的inode
153  * @param dEntry 目标dentry
154  * @param mode 创建模式
155  * @return long 错误码
156  */
devfs_mkdir(struct vfs_index_node_t * inode,struct vfs_dir_entry_t * dEntry,int mode)157 static long devfs_mkdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode)
158 {
159     dEntry->dir_inode = vfs_alloc_inode();
160     dEntry->dir_inode->file_ops = &devfs_file_ops;
161     dEntry->dir_inode->inode_ops = &devfs_inode_ops;
162     dEntry->dir_ops = &devfs_dentry_ops;
163     // todo: 增加private inode info
164     dEntry->dir_inode->private_inode_info = NULL;
165     dEntry->dir_inode->sb = &devfs_sb;
166     dEntry->dir_inode->attribute = VFS_IF_DIR;
167     return 0;
168 }
169 
devfs_rmdir(struct vfs_index_node_t * inode,struct vfs_dir_entry_t * dEntry)170 static long devfs_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry) { return 0; }
devfs_rename(struct vfs_index_node_t * old_inode,struct vfs_dir_entry_t * old_dEntry,struct vfs_index_node_t * new_inode,struct vfs_dir_entry_t * new_dEntry)171 static long devfs_rename(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry, struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry) { return 0; }
devfs_getAttr(struct vfs_dir_entry_t * dEntry,uint64_t * attr)172 static long devfs_getAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) { return 0; }
devfs_setAttr(struct vfs_dir_entry_t * dEntry,uint64_t * attr)173 static long devfs_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) { return 0; }
174 struct vfs_inode_operations_t devfs_inode_ops = {
175     .create = &devfs_create,
176     .lookup = &devfs_lookup,
177     .mkdir = &devfs_mkdir,
178     .rmdir = &devfs_rmdir,
179     .rename = &devfs_rename,
180     .getAttr = &devfs_getAttr,
181     .setAttr = &devfs_setAttr,
182 };
183 
184 struct vfs_filesystem_type_t devfs_fs_type =
185     {
186         .name = "DEVFS",
187         .fs_flags = 0,
188         .read_superblock = devfs_read_superblock,
189         .next = NULL,
190 };
191 
__devfs_init_root_inode()192 static __always_inline void __devfs_init_root_inode()
193 {
194     devfs_root_dentry->dir_inode = vfs_alloc_inode();
195     devfs_root_dentry->dir_inode->file_ops = &devfs_file_ops;
196     devfs_root_dentry->dir_inode->inode_ops = &devfs_inode_ops;
197 
198     // todo: 增加private inode info
199     devfs_root_dentry->dir_inode->private_inode_info = NULL;
200     devfs_root_dentry->dir_inode->sb = &devfs_sb;
201     devfs_root_dentry->dir_inode->attribute = VFS_IF_DIR;
202 }
203 /**
204  * @brief 初始化devfs的根dentry
205  */
__devfs_init_root_dentry()206 static __always_inline void __devfs_init_root_dentry()
207 {
208     devfs_root_dentry = vfs_alloc_dentry(0);
209     devfs_root_dentry->dir_ops = &devfs_dentry_ops;
210 
211     __devfs_init_root_inode();
212 }
213 
214 /**
215  * @brief 在devfs中注册设备
216  *
217  * @param device_type 设备主类型
218  * @param sub_type 设备子类型
219  * @param file_ops 设备的文件操作接口
220  * @param ret_private_inode_info_ptr 返回的指向inode私有信息结构体的指针
221  * @return int 错误码
222  */
devfs_register_device(uint16_t device_type,uint16_t sub_type,struct vfs_file_operations_t * file_ops,struct devfs_private_inode_info_t ** ret_private_inode_info_ptr)223 int devfs_register_device(uint16_t device_type, uint16_t sub_type, struct vfs_file_operations_t *file_ops, struct devfs_private_inode_info_t **ret_private_inode_info_ptr)
224 {
225     spin_lock(&devfs_global_lock);
226     int retval = 0;
227     // 申请private info结构体
228     struct devfs_private_inode_info_t *private_info = (struct devfs_private_inode_info_t *)kzalloc(sizeof(struct devfs_private_inode_info_t), 0);
229     private_info->f_ops = file_ops;
230     private_info->type = device_type;
231     private_info->sub_type = sub_type;
232     private_info->uuid = __devfs_get_uuid();
233 
234     struct vfs_dir_entry_t *dentry = NULL; // 该指针由对应类型设备的注册函数设置
235 
236     switch (device_type)
237     {
238     case DEV_TYPE_CHAR:
239         retval = __devfs_chardev_register(private_info, &dentry);
240         break;
241 
242     default:
243         kerror("Unsupported device type [ %d ].", device_type);
244         retval = -ENOTSUP;
245         goto failed;
246         break;
247     }
248     if (ret_private_inode_info_ptr != NULL)
249         *ret_private_inode_info_ptr = private_info;
250 
251     spin_unlock(&devfs_global_lock);
252     return retval;
253 failed:;
254     kfree(private_info);
255     spin_unlock(&devfs_global_lock);
256     return retval;
257 }
258 
259 /**
260  * @brief 卸载设备
261  *
262  * @param private_inode_info 待卸载的设备的inode私有信息
263  * @param put_private_info 设备被卸载后,执行的函数
264  * @return int 错误码
265  */
devfs_unregister_device(struct devfs_private_inode_info_t * private_inode_info)266 int devfs_unregister_device(struct devfs_private_inode_info_t *private_inode_info)
267 {
268     int retval = 0;
269     spin_lock(&devfs_global_lock);
270     struct vfs_dir_entry_t *base_dentry = NULL;
271     struct vfs_dir_entry_t *target_dentry = NULL;
272 
273     // 找到父目录的dentry
274     {
275 
276         char base_path[64] = {0};
277         switch (private_inode_info->type)
278         {
279         case DEV_TYPE_CHAR:
280             strcpy(base_path, "/dev/char");
281             break;
282         default:
283             retval = -ENOTSUP;
284             goto out;
285             break;
286         }
287 
288         base_dentry = vfs_path_walk(base_path, 0);
289         // bug
290         if (unlikely(base_dentry == NULL))
291         {
292             BUG_ON(1);
293             retval = -ENODEV;
294             goto out;
295         }
296     }
297 
298     // 遍历子目录,寻找拥有指定inode的dentry(暂时不支持一个inode对应多个dentry的情况)
299     // todo: 支持链接文件的卸载
300     struct List *tmp_list = NULL, *target_list = NULL;
301     list_for_each_safe(target_list, tmp_list, &base_dentry->subdirs_list)
302     {
303         target_dentry = list_entry(target_list, struct vfs_dir_entry_t, child_node_list);
304         if (target_dentry->dir_inode == private_inode_info->inode)
305         {
306             spin_lock(&target_dentry->lockref.lock);
307             retval = vfs_dentry_put(target_dentry);
308             if (retval < 0)
309             {
310                 kerror("Error when try to unregister device");
311                 spin_unlock(&target_dentry->lockref.lock);
312             }
313             else if (retval == 0) // 该设备的所有dentry均被卸载完成,不必继续迭代
314                 break;
315         }
316     }
317     retval = 0;
318 out:;
319     spin_unlock(&devfs_global_lock);
320     return retval;
321 }
322 
323 /**
324  * @brief 初始化devfs
325  *
326  */
devfs_init()327 void devfs_init()
328 {
329     __devfs_init_root_dentry();
330     vfs_register_filesystem(&devfs_fs_type);
331     spin_init(&devfs_global_lock);
332     vfs_mount_fs(__devfs_mount_path, "DEVFS", NULL);
333 
334     __devfs_chardev_init();
335 }