1 #include "mount.h"
2 #include "VFS.h"
3 #include <common/glib.h>
4 #include <common/string.h>
5 
6 static struct List mnt_list_head; // 挂载点链表头
7 
8 /**
9  * @brief 初始化mount机制
10  *
11  * @return int 错误码
12  */
mount_init()13 int mount_init()
14 {
15     list_init(&mnt_list_head);
16     return 0;
17 }
18 
19 /**
20  * @brief 将new_dentry挂载
21  *
22  * @param old_dentry 挂载点的dentry
23  * @param new_dentry 待挂载的新的dentry(需使用vfs_alloc_dentry来分配)
24  * @return int 错误码
25  */
do_mount(struct vfs_dir_entry_t * old_dentry,struct vfs_dir_entry_t * new_dentry)26 int do_mount(struct vfs_dir_entry_t *old_dentry, struct vfs_dir_entry_t *new_dentry)
27 {
28     struct mountpoint *mp = (struct mountpoint *)kzalloc(sizeof(struct mountpoint), 0);
29     list_init(&mp->mnt_list);
30     mp->dentry = old_dentry;
31     mp->parent_dentry = old_dentry->parent;
32 
33     // 拷贝名称
34     strncpy(new_dentry->name, old_dentry->name, old_dentry->name_length);
35     kdebug("new_dentry->name=%s, old_dentry->name=%s, old_dentry->name_length=%d", new_dentry->name, old_dentry->name, old_dentry->name_length);
36 
37     new_dentry->d_flags |= VFS_DF_MOUNTED; // 标记新的dentry是一个挂载点
38 
39     list_init(&new_dentry->child_node_list);
40     list_init(&new_dentry->subdirs_list);
41     new_dentry->parent = old_dentry->parent;
42 
43     // 将新的dentry的list结点替换掉父dentry的列表中的old_dentry的list结点
44     list_replace(&old_dentry->child_node_list, &new_dentry->child_node_list);
45 
46     // 后挂载的dentry在链表的末尾(umount恢复的时候需要依赖这个性质)
47     list_append(&mnt_list_head, &mp->mnt_list);
48 
49     return 0;
50 }
51 
52 /**
53  * @brief 取消某个文件系统的挂载
54  *
55  * @param dentry 对应文件系统的根dentry
56  * @return int 错误码
57  */
do_umount(struct vfs_dir_entry_t * dentry)58 int do_umount(struct vfs_dir_entry_t *dentry)
59 {
60     // todo: 实现umount(主要是结点的恢复问题)
61 
62     return 0;
63 }
64 
65 /**
66  * @brief 根据mountpoint的父目录dentry查找第一个符合条件的mountpoint结构体
67  *
68  * @param dentry 父dentry
69  * @return struct mountpoint* 第一个符合条件的mountpoint结构体的指针
70  */
mount_find_mnt_list_by_parent(struct vfs_dir_entry_t * dentry)71 struct mountpoint *mount_find_mnt_list_by_parent(struct vfs_dir_entry_t *dentry)
72 {
73     struct List *list = &mnt_list_head;
74     struct mountpoint *ret = NULL;
75     if (list_empty(list))
76         return NULL;
77 
78     while (list_next(list) != &mnt_list_head)
79     {
80         list = list_next(list);
81         struct mountpoint *tmp = container_of(list, struct mountpoint, mnt_list);
82         if (dentry == tmp->parent_dentry)
83             return tmp;
84     }
85 
86     return NULL;
87 }
88 
89 /**
90  * @brief 将挂载点结构体从链表中删除并释放
91  *
92  * @param mp mountpoint结构体
93  * @return int 错误码
94  */
mount_release_mountpoint(struct mountpoint * mp)95 int mount_release_mountpoint(struct mountpoint *mp)
96 {
97     list_del(&mp->mnt_list);
98     return kfree(mp);
99 }