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 }