1 #include "rootfs.h"
2 #include <filesystem/vfs/VFS.h>
3 #include <common/string.h>
4 #include <filesystem/vfs/mount.h>
5 
6 static struct vfs_superblock_t rootfs_sb = {0};
7 extern struct vfs_superblock_t *vfs_root_sb;
8 
9 /**
10  * @brief 释放dentry本身所占的内存
11  *
12  * @param dentry
13  */
__release_dentry(struct vfs_dir_entry_t * dentry)14 static inline void __release_dentry(struct vfs_dir_entry_t *dentry)
15 {
16     kfree(dentry->name);
17     kfree(dentry);
18 }
19 
20 struct vfs_super_block_operations_t rootfs_sb_ops = {
21     .put_superblock = NULL,
22     .write_inode = NULL,
23     .write_superblock = NULL,
24 };
25 
rootfs_lookup(struct vfs_index_node_t * parent_inode,struct vfs_dir_entry_t * dest_dEntry)26 static struct vfs_dir_entry_t *rootfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry)
27 {
28     return NULL;
29 }
30 struct vfs_inode_operations_t rootfs_inode_ops = {
31     .create = NULL,
32     .getAttr = NULL,
33     .lookup = NULL,
34     .lookup = &rootfs_lookup,
35     .mkdir = NULL,
36     .rename = NULL,
37     .rmdir = NULL,
38     .setAttr = NULL,
39 };
40 
rootfs_open(struct vfs_index_node_t * inode,struct vfs_file_t * file_ptr)41 static long rootfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
42 {
43     return 0;
44 }
rootfs_close(struct vfs_index_node_t * inode,struct vfs_file_t * file_ptr)45 static long rootfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) { return 0; }
rootfs_read(struct vfs_file_t * file_ptr,char * buf,int64_t count,long * position)46 static long rootfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; }
rootfs_write(struct vfs_file_t * file_ptr,char * buf,int64_t count,long * position)47 static long rootfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) { return 0; }
rootfs_lseek(struct vfs_file_t * file_ptr,long offset,long origin)48 static long rootfs_lseek(struct vfs_file_t *file_ptr, long offset, long origin) { return 0; }
rootfs_ioctl(struct vfs_index_node_t * inode,struct vfs_file_t * file_ptr,uint64_t cmd,uint64_t arg)49 static long rootfs_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg) { return 0; }
50 
rootfs_readdir(struct vfs_file_t * file_ptr,void * dirent,vfs_filldir_t filler)51 static long rootfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler)
52 {
53     // 循环读取目录下的目录项
54     struct vfs_dir_entry_t *dentry = file_ptr->dEntry;
55     struct List *list = &dentry->subdirs_list;
56     // 先切换到position处
57     for (int i = 0; i <= file_ptr->position; ++i)
58     {
59         list = list_next(list);
60         if (list == &dentry->subdirs_list) // 找完了
61             goto failed;
62     }
63 
64     // 存在目录项
65     // 增加偏移量
66     ++file_ptr->position;
67     // 获取目标dentry(由于是子目录项,因此是child_node_list)
68     struct vfs_dir_entry_t *target_dent = container_of(list, struct vfs_dir_entry_t, child_node_list);
69     // kdebug("target name=%s, namelen=%d", target_dent->name, target_dent->name_length);
70 
71     char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
72     strncpy(name, target_dent->name, target_dent->name_length);
73 
74     uint32_t dentry_type = target_dent->dir_inode->attribute;
75 
76     return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1);
77 failed:;
78     return 0;
79 }
80 
rootfs_compare(struct vfs_dir_entry_t * parent_dEntry,char * source_filename,char * dest_filename)81 static long rootfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename) { return 0; }
82 
rootfs_hash(struct vfs_dir_entry_t * dEntry,char * filename)83 static long rootfs_hash(struct vfs_dir_entry_t *dEntry, char *filename) { return 0; }
84 
rootfs_release(struct vfs_dir_entry_t * dEntry)85 static long rootfs_release(struct vfs_dir_entry_t *dEntry) { return 0; }
86 
rootfs_iput(struct vfs_dir_entry_t * dEntry,struct vfs_index_node_t * inode)87 static long rootfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) { return 0; }
88 
89 struct vfs_dir_entry_operations_t rootfs_dentry_ops =
90     {
91         .compare = &rootfs_compare,
92         .hash = &rootfs_hash,
93         .release = &rootfs_release,
94         .iput = &rootfs_iput,
95 };
96 
97 struct vfs_file_operations_t rootfs_file_ops = {
98     .open = &rootfs_open,
99     .close = &rootfs_close,
100     .read = &rootfs_read,
101     .write = &rootfs_write,
102     .lseek = &rootfs_lseek,
103     .ioctl = &rootfs_ioctl,
104     .readdir = &rootfs_readdir,
105 };
106 
107 /**
108  * @brief 为在rootfs下创建目录(仅仅是形式上的目录,为了支持文件系统挂载)
109  *
110  * @param name 目录名称
111  * @return int
112  */
rootfs_add_dir(const char * name)113 static int rootfs_add_dir(const char *name)
114 {
115     {
116         // 检查名称重复
117         struct List *list = &rootfs_sb.root->subdirs_list;
118         while (list_next(list) != &rootfs_sb.root->subdirs_list)
119         {
120             list = list_next(list);
121             struct vfs_dir_entry_t *tmp = container_of(list, struct vfs_dir_entry_t, child_node_list);
122             if (strcmp(tmp->name, name) == 0)
123                 return -EEXIST;
124         }
125     }
126 
127     struct vfs_dir_entry_t *dentry = vfs_alloc_dentry(strlen(name) + 1);
128     strcpy(dentry->name, name);
129     dentry->name_length = strlen(name);
130     dentry->parent = rootfs_sb.root;
131     list_append(&rootfs_sb.root->subdirs_list, &dentry->child_node_list);
132     return 0;
133 }
134 
rootfs_init()135 void rootfs_init()
136 {
137     // 初始化超级块
138     rootfs_sb.blk_device = NULL;
139     rootfs_sb.private_sb_info = NULL;
140     rootfs_sb.sb_ops = &rootfs_sb_ops;
141     rootfs_sb.dir_ops = &rootfs_dentry_ops;
142 
143     // 初始化dentry
144     rootfs_sb.root = vfs_alloc_dentry(sizeof("/"));
145     struct vfs_dir_entry_t *dentry = rootfs_sb.root;
146     strncpy(dentry->name, "/", 2);
147     dentry->name_length = 1;
148     dentry->parent = dentry;
149 
150     // 初始化root inode
151     dentry->dir_inode = vfs_alloc_inode();
152     dentry->dir_inode->sb = &rootfs_sb;
153     dentry->dir_inode->inode_ops = &rootfs_inode_ops;
154     dentry->dir_inode->file_ops = &rootfs_file_ops;
155     dentry->dir_inode->attribute = VFS_IF_DIR;
156 
157     // 直接将vfs的根superblock设置为rootfs的超级块
158     vfs_root_sb = &rootfs_sb;
159 
160     // 创建/dev等目录的dentry(以便文件系统的mount)
161     if (rootfs_add_dir("dev") != 0)
162         kerror("create dir 'dev' in rootfs failed");
163 
164     // 创建/procfs目录的dentry
165     if (rootfs_add_dir("proc") != 0)
166         kerror("create dir 'proc' in rootfs failed");
167 }
168 
169 /**
170  * @brief 当新的根文件系统被挂载后,将原有的挂载在rootfs下的文件系统,迁移到新的根文件系统上
171  *
172  */
rootfs_migrate()173 static void rootfs_migrate()
174 {
175     kdebug("Migrating rootfs's dentries...");
176     struct List *list = &rootfs_sb.root->subdirs_list;
177     if (unlikely(list_empty(list)))
178         return;
179     list = list_next(list);
180     while (list != &rootfs_sb.root->subdirs_list)
181     {
182 
183         struct vfs_dir_entry_t *tmp = container_of(list, struct vfs_dir_entry_t, child_node_list);
184         if (tmp->dir_inode != NULL)
185         {
186             list = list_next(list); // 获取下一个列表结点(不然的话下面的几行代码就覆盖掉了正确的值了)
187 
188             tmp->parent = vfs_root_sb->root;
189             list_init(&tmp->child_node_list);
190             list_append(&vfs_root_sb->root->subdirs_list, &tmp->child_node_list);
191         }
192         else
193         {
194             list = list_next(list); // 不迁移空的dentry,直接释放他们
195             list_del(&tmp->child_node_list);
196             __release_dentry(tmp);
197         }
198     }
199 }
200 
201 /**
202  * @brief 当磁盘文件系统被成功挂载后,释放rootfs所占的空间
203  *
204  */
rootfs_umount()205 void rootfs_umount()
206 {
207     // 将原有的“dev”文件夹等进行迁移
208     rootfs_migrate();
209     kinfo("Umounting rootfs...");
210 
211     // 遍历mount链表,删除所有父目录是rootfs的dentry
212     struct mountpoint *mp = NULL;
213     while (1)
214     {
215         mp = mount_find_mnt_list_by_parent(rootfs_sb.root);
216         if (mp == NULL)
217             break;
218 
219         // 释放dentry(由于没有创建inode,因此不需要释放)
220         __release_dentry(mp->dentry);
221         // 释放mountpoint结构体
222         mount_release_mountpoint(mp);
223     }
224 
225     // 释放root dentry及其inode
226     kfree(rootfs_sb.root->dir_inode);
227     __release_dentry(rootfs_sb.root);
228 }