• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 #include "defs.h"
13 #include "namei.h"
14 #include <chcore/cpio.h>
15 #include <chcore/ipc.h>
16 #include <chcore/syscall.h>
17 
18 #include "../fs_base/fs_wrapper_defs.h"
19 #include "../fs_base/fs_vnode.h"
20 #include <stdlib.h>
21 #include <string.h>
22 
23 struct id_manager fidman;
24 struct fid_record fid_records[MAX_NR_FID_RECORDS];
25 
26 bool mounted;
27 bool using_page_cache;
28 
29 #ifdef TEST_COUNT_PAGE_CACHE
30 struct test_count count;
31 #endif
32 
33 struct server_entry *server_entrys[MAX_SERVER_ENTRY_NUM];
34 struct rb_root *fs_vnode_list;
35 
tmpfs_load_image(const char * start)36 int tmpfs_load_image(const char *start)
37 {
38     struct cpio_file *f;
39     struct inode *inode;
40     struct dentry *dentry;
41     const char *path;
42     size_t len;
43     int err = 0;
44     ssize_t write_count;
45     struct nameidata nd;
46 
47     BUG_ON(start == NULL);
48 
49     cpio_init_g_files();
50     cpio_extract(start, "/");
51 
52     char *tmp = malloc(MAX_PATH);
53 
54     for (f = g_files.head.next; f; f = f->next) {
55         if (!(f->header.c_filesize))
56             continue;
57 
58         path = f->name;
59 
60         memset(tmp, 0, MAX_PATH);
61         tmp[0] = '/';
62 
63         int i_tmp = 1;
64 
65         /* skipping '/'s. maybe this is unnecessary */
66         while (*path == '/') {
67             path++;
68         }
69 
70         /* copying path to tmp while creating every directory
71          * encountered during the copying process */
72         while (*path) {
73             if (*path == '/') {
74                 err = tmpfs_mkdir(tmp, 0);
75                 if (err && err != -EEXIST) {
76                     goto error;
77                 }
78             }
79             tmp[i_tmp++] = *path;
80             path++;
81         }
82 
83         if (*(path - 1) == '/') {
84             warn("empty dir in cpio\n");
85             continue;
86         }
87 
88         /* create the last non-directory component as a regular file,
89          * simply by calling path_openat() with O_CREAT */
90         err = path_openat(&nd, tmp, O_CREAT, 0, &dentry);
91         if (err) {
92             goto error;
93         }
94 
95         inode = dentry->inode;
96 
97         len = f->header.c_filesize;
98         write_count = inode->f_ops->write(inode, f->data, len, 0);
99         if (write_count != len) {
100             err = -ENOSPC;
101             goto error;
102         }
103     }
104 
105     err = tmpfs_mkdir("/tafs", 0);
106     BUG_ON(err);
107 
108 error:
109     free(tmp);
110     cpio_free_g_files();
111     return err;
112 }
113 
114 /* init tmpfs root, creating . and .. inside */
init_root(void)115 void init_root(void)
116 {
117     int err;
118     tmpfs_root_dent = malloc(sizeof(struct dentry));
119     assert(tmpfs_root_dent);
120 
121     tmpfs_root = tmpfs_inode_init(FS_DIR, 0);
122     assert(tmpfs_root);
123     tmpfs_root_dent->inode = tmpfs_root;
124 
125     struct dentry *d_root_dot = tmpfs_root->d_ops->alloc_dentry();
126     assert(!CHCORE_IS_ERR(d_root_dot));
127     err = tmpfs_root->d_ops->add_dentry(tmpfs_root, d_root_dot, ".", 1);
128     assert(!err);
129 
130     struct dentry *d_root_dotdot = tmpfs_root->d_ops->alloc_dentry();
131     assert(!CHCORE_IS_ERR(d_root_dotdot));
132     err = tmpfs_root->d_ops->add_dentry(tmpfs_root, d_root_dotdot, "..", 2);
133     assert(!err);
134 
135     tmpfs_root->d_ops->link(tmpfs_root, d_root_dot, tmpfs_root);
136     tmpfs_root->d_ops->link(tmpfs_root, d_root_dotdot, tmpfs_root);
137 }
138 
init_tmpfs(void)139 static int init_tmpfs(void)
140 {
141     init_root();
142 
143     init_id_manager(&fidman, MAX_NR_FID_RECORDS, DEFAULT_INIT_ID);
144     assert(alloc_id(&fidman) == 0);
145 
146     init_fs_wrapper();
147 
148     /* tmpfs should never use page cache. */
149     using_page_cache = false;
150     BUG_ON(using_page_cache);
151 
152     mounted = true;
153 
154     return 0;
155 }
156 
main(int argc,char * argv[],char * envp[])157 int main(int argc, char *argv[], char *envp[])
158 {
159     init_tmpfs();
160 
161     tmpfs_load_image((char *)&__binary_ramdisk_cpio_start);
162 
163     info("register server value = %u\n",
164          ipc_register_server_with_destructor(fs_server_dispatch,
165                                              DEFAULT_CLIENT_REGISTER_HANDLER,
166                                              fs_server_destructor));
167 
168     usys_exit(0);
169     return 0;
170 }
171