Skip to content

Commit 0d1d8cc

Browse files
committed
procfs self节点更改为软链接, vfs_node 增加挂载点标记
1 parent c859020 commit 0d1d8cc

File tree

10 files changed

+162
-140
lines changed

10 files changed

+162
-140
lines changed

module/all_include/fs_subsystem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct vfs_node { // vfs节点
100100
list_t child; // 子节点
101101
vfs_node_t root; // 根目录
102102
bool visited; // 是否与具体文件系统同步
103+
bool is_mount; // 是否是挂载点
103104
};
104105

105106
errno_t vfs_mkdir(const char *name);

src/x86_64/fs/procfs.c

Lines changed: 108 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "vfs.h"
1010

1111
static int procfs_id = 0;
12+
static int proc_self_id = 0;
1213
vfs_node_t procfs_root = NULL;
1314
spin_t procfs_oplock = SPIN_INIT;
1415

@@ -24,6 +25,10 @@ static int dummy() {
2425
return 0;
2526
}
2627

28+
static int udummy() {
29+
return VFS_STATUS_FAILED;
30+
}
31+
2732
const char *get_vma_permissions(vma_t *vma) {
2833
static char perms[5];
2934

@@ -86,39 +91,19 @@ char *proc_gen_maps_file(pcb_t task, size_t *content_len) {
8691
return buf;
8792
}
8893

94+
extern lock_queue *pgb_queue;
95+
8996
errno_t procfs_mount(const char *src, vfs_node_t node) {
9097
if (src != (void *)PROC_REGISTER_ID) return VFS_STATUS_FAILED;
9198
procfs_root = node;
9299

93100
procfs_root->fsid = procfs_id;
94101

95102
vfs_node_t procfs_self = vfs_node_alloc(procfs_root, "self");
96-
procfs_self->type = file_dir;
103+
procfs_self->type = file_symlink;
97104
procfs_self->mode = 0644;
98-
99-
vfs_node_t self_environ = vfs_node_alloc(procfs_self, "environ");
100-
self_environ->type = file_none;
101-
self_environ->mode = 0700;
102-
proc_handle_t *self_environ_handle = malloc(sizeof(proc_handle_t));
103-
self_environ->handle = self_environ_handle;
104-
self_environ_handle->task = NULL;
105-
sprintf(self_environ_handle->name, "self/environ");
106-
107-
vfs_node_t self_maps = vfs_node_alloc(procfs_self, "maps");
108-
self_maps->type = file_none;
109-
self_maps->mode = 0700;
110-
proc_handle_t *self_maps_handle = malloc(sizeof(proc_handle_t));
111-
self_maps->handle = self_maps_handle;
112-
self_maps_handle->task = NULL;
113-
sprintf(self_maps_handle->name, "self/maps");
114-
115-
vfs_node_t self_cmdline = vfs_node_alloc(procfs_self, "cmdline");
116-
self_cmdline->type = file_none;
117-
self_cmdline->mode = 0700;
118-
proc_handle_t *self_cmdline_handle = malloc(sizeof(proc_handle_t));
119-
self_cmdline->handle = self_cmdline_handle;
120-
self_cmdline_handle->task = NULL;
121-
sprintf(self_cmdline_handle->name, "self/cmdline");
105+
procfs_self->linkto = NULL;
106+
procfs_self->fsid = proc_self_id;
122107

123108
vfs_node_t cmdline = vfs_node_alloc(procfs_root, "cmdline");
124109
cmdline->type = file_none;
@@ -136,6 +121,10 @@ errno_t procfs_mount(const char *src, vfs_node_t node) {
136121
filesystems_handle->task = NULL;
137122
sprintf(filesystems_handle->name, "filesystems");
138123

124+
queue_foreach(pgb_queue, node) {
125+
procfs_on_new_task(node->data);
126+
}
127+
139128
return VFS_STATUS_SUCCESS;
140129
}
141130

@@ -177,30 +166,12 @@ size_t procfs_read(void *file, void *addr, size_t offset, size_t size) {
177166
len = (len + 1) > size ? size : len + 1;
178167
memcpy(addr, get_kernel_cmdline(), len);
179168
return len;
180-
} else if (!strcmp(handle->name, "self/maps")) {
181-
size_t content_len = 0;
182-
char *content = proc_gen_maps_file(get_current_task()->parent_group, &content_len);
183-
if (offset >= content_len) {
184-
free(content);
185-
return 0;
186-
}
187-
content_len = MIN(content_len, offset + size);
188-
size_t to_copy = MIN(content_len, size);
189-
memcpy(addr, content + offset, to_copy);
190-
free(content);
191-
((char *)addr)[to_copy] = '\0';
192-
return to_copy;
193-
} else if (!strcmp(handle->name, "self/cmdline")) {
194-
ssize_t len = strlen(get_current_task()->parent_group->cmdline);
195-
if (len == 0) return 0;
196-
len = (len + 1) > size ? size : len + 1;
197-
memcpy(addr, get_current_task()->parent_group->cmdline, len);
198-
return len;
199169
} else if (!strcmp(handle->name, "proc_cmdline")) {
200-
ssize_t len = strlen(task->cmdline);
170+
char *cmdline = task->cmdline ? task->cmdline : "no_cmdline";
171+
ssize_t len = strlen(cmdline);
201172
if (len == 0) return 0;
202173
len = (len + 1) > size ? size : len + 1;
203-
memcpy(addr, task->cmdline, len);
174+
memcpy(addr, cmdline, len);
204175
return len;
205176
} else if (!strcmp(handle->name, "proc_maps")) {
206177
size_t content_len = 0;
@@ -234,15 +205,8 @@ errno_t procfs_stat(void *file, vfs_node_t node) {
234205
node->size = strlen(filesystems_content);
235206
else if (!strcmp(handle->name, "cmdline"))
236207
node->size = strlen(get_kernel_cmdline());
237-
else if (!strcmp(handle->name, "self/maps")) {
238-
size_t content_len = 0;
239-
char *content = proc_gen_maps_file(get_current_task()->parent_group, &content_len);
240-
free(content);
241-
node->size = content_len;
242-
} else if (!strcmp(handle->name, "proc_cmdline"))
243-
node->size = strlen(handle->task->cmdline);
244-
else if (!strcmp(handle->name, "self/cmdline"))
245-
node->size = strlen(get_current_task()->parent_group->cmdline);
208+
else if (!strcmp(handle->name, "proc_cmdline"))
209+
node->size = strlen(handle->task->cmdline ? handle->task->cmdline : "null");
246210
else if (!strcmp(handle->name, "proc_maps")) {
247211
size_t content_len = 0;
248212
char *content = proc_gen_maps_file(handle->task, &content_len);
@@ -252,6 +216,77 @@ errno_t procfs_stat(void *file, vfs_node_t node) {
252216
node->size = strlen("cpkernel_drm");
253217
}
254218

219+
void procfs_self_open(void *parent, const char *name, vfs_node_t node) {
220+
logkf("procfs: self open node: %p\n", get_current_task()->parent_group->procfs_node);
221+
procfs_self_handle_t *handle = malloc(sizeof(procfs_self_handle_t));
222+
handle->self = node;
223+
node->linkto = get_current_task()->parent_group->procfs_node;
224+
node->handle = handle;
225+
vfs_node_t new_self_node = vfs_node_alloc(node->parent, "self");
226+
new_self_node->type = file_symlink;
227+
new_self_node->mode = 0644;
228+
new_self_node->fsid = proc_self_id;
229+
list_delete(node->parent->child, node);
230+
}
231+
232+
void procfs_self_close(void *current) {
233+
procfs_self_handle_t *handle = current;
234+
handle->self->type |= file_delete;
235+
free(handle);
236+
}
237+
238+
size_t procfs_self_read(void *fd, void *addr, size_t offset, size_t size) {
239+
procfs_self_handle_t *handle = fd;
240+
return procfs_read(handle->self->linkto->handle, addr, offset, size);
241+
}
242+
243+
size_t procfs_self_write(void *fd, const void *addr, size_t offset, size_t size) {
244+
procfs_self_handle_t *handle = fd;
245+
return procfs_write(handle->self->linkto->handle, addr, offset, size);
246+
}
247+
248+
size_t procfs_self_readlink(vfs_node_t file, void *addr, size_t offset, size_t size) {
249+
procfs_self_handle_t *handle = file->handle;
250+
if (offset >= strlen(handle->self->linkto->name)) return 0;
251+
logkf("procfs: readlink offset:%llu size:%llu", offset, size);
252+
char *ptr = handle->self->linkto->name + offset;
253+
ssize_t len = strlen(ptr);
254+
len = MIN(len, (ssize_t)size);
255+
memcpy(addr, ptr, len);
256+
return len;
257+
}
258+
259+
errno_t procfs_self_stat(void *file, vfs_node_t node) {
260+
procfs_self_handle_t *handle = file;
261+
node->type |= file_symlink;
262+
node->size = strlen(handle->self->linkto->name);
263+
}
264+
265+
void procfs_self_free_handle(procfs_self_handle_t *handle) {
266+
free(handle);
267+
}
268+
269+
static struct vfs_callback procfs_self_callbacks = {
270+
.open = procfs_self_open,
271+
.close = procfs_self_close,
272+
.read = procfs_self_read,
273+
.write = procfs_self_write,
274+
.readlink = procfs_self_readlink,
275+
.mkdir = (vfs_mk_t)dummy,
276+
.mkfile = (vfs_mk_t)dummy,
277+
.link = (vfs_mk_t)dummy,
278+
.symlink = (vfs_mk_t)dummy,
279+
.delete = (vfs_del_t)dummy,
280+
.rename = (vfs_rename_t)dummy,
281+
.stat = procfs_self_stat,
282+
.ioctl = (vfs_ioctl_t)dummy,
283+
.map = (vfs_mapfile_t)dummy,
284+
.poll = (vfs_poll_t)dummy,
285+
.mount = (vfs_mount_t)udummy,
286+
.unmount = (vfs_unmount_t)dummy,
287+
.dup = (vfs_dup_t)dummy,
288+
};
289+
255290
static struct vfs_callback procfs_callbacks = {
256291
.mount = procfs_mount,
257292
.unmount = (vfs_unmount_t)dummy,
@@ -274,30 +309,34 @@ static struct vfs_callback procfs_callbacks = {
274309
};
275310

276311
void procfs_setup() {
277-
procfs_id = vfs_regist("proc", &procfs_callbacks, PROC_REGISTER_ID);
278-
if (procfs_id == VFS_STATUS_FAILED) { kerror("procfs register error"); }
312+
procfs_id = vfs_regist("proc", &procfs_callbacks, PROC_REGISTER_ID);
313+
proc_self_id = vfs_regist("proc_self", &procfs_self_callbacks, PROC_REGISTER_ID);
314+
if (procfs_id == VFS_STATUS_FAILED || proc_self_id == VFS_STATUS_FAILED) {
315+
kerror("procfs register error");
316+
}
279317
}
280318

281319
void procfs_on_new_task(pcb_t task) {
282320
if (procfs_root == NULL) return;
283-
spin_lock(procfs_oplock);
284321

285322
char name[MAX_PID_NAME_LEN];
286323
sprintf(name, "%d", task->pid);
287324

288-
char fname[6 + MAX_PID_NAME_LEN];
289-
sprintf(fname, "/proc/%d", task->pid);
325+
char *root_path = vfs_get_fullpath(procfs_root);
326+
char fname[strlen(root_path) + 1 + MAX_PID_NAME_LEN];
327+
sprintf(fname, "%s/%d", root_path, task->pid);
290328
vfs_node_t pro = vfs_open(fname);
329+
free(root_path);
291330
if (pro != NULL) {
292331
vfs_close(pro);
293-
spin_unlock(procfs_oplock);
294332
return;
295333
}
296334

297-
vfs_node_t node = vfs_child_append(procfs_root, name, NULL);
298-
node->type = file_dir;
299-
node->mode = 0644;
300-
node->fsid = procfs_id;
335+
vfs_node_t node = vfs_child_append(procfs_root, name, NULL);
336+
node->type = file_dir;
337+
node->mode = 0644;
338+
node->fsid = procfs_id;
339+
task->procfs_node = node;
301340

302341
vfs_node_t cmdline = vfs_child_append(node, "cmdline", NULL);
303342
cmdline->type = file_none;
@@ -316,16 +355,16 @@ void procfs_on_new_task(pcb_t task) {
316355
mmaps->handle = handle_m;
317356
handle_m->task = task;
318357
sprintf(handle_m->name, "proc_maps");
319-
320-
spin_unlock(procfs_oplock);
321358
}
322359

323360
void procfs_on_exit_task(pcb_t task) {
324361
if (procfs_root == NULL) return;
325362
spin_lock(procfs_oplock);
326363

327-
char name[6 + MAX_PID_NAME_LEN];
328-
sprintf(name, "/proc/%d", task->pid);
364+
char *root_path = vfs_get_fullpath(procfs_root);
365+
char name[strlen(root_path) + 1 + MAX_PID_NAME_LEN];
366+
sprintf(name, "%s/%d", root_path, task->pid);
367+
free(root_path);
329368

330369
vfs_node_t node = vfs_open(name);
331370
if (node && node->parent) {
@@ -335,33 +374,3 @@ void procfs_on_exit_task(pcb_t task) {
335374

336375
spin_unlock(procfs_oplock);
337376
}
338-
339-
extern lock_queue *pgb_queue;
340-
341-
void procfs_update_task_list() {
342-
if (procfs_root == NULL) return;
343-
do {
344-
vfs_node_t proc_node = NULL;
345-
list_foreach(procfs_root->child, node) {
346-
vfs_node_t pnode = node->data;
347-
if (pnode->handle != NULL) {
348-
proc_handle_t *handle = pnode->handle;
349-
if (handle->task == NULL) continue;
350-
proc_node = pnode;
351-
break;
352-
}
353-
}
354-
if (proc_node == NULL) break;
355-
proc_handle_t *handle = proc_node->handle;
356-
if (handle->task->status == DEATH) {
357-
if (proc_node && proc_node->parent) {
358-
list_delete(proc_node->parent->child, proc_node);
359-
vfs_free(proc_node);
360-
}
361-
}
362-
} while (true);
363-
queue_foreach(pgb_queue, node) {
364-
pcb_t process = node->data;
365-
procfs_on_new_task(process);
366-
}
367-
}

src/x86_64/fs/vfs.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,11 @@ vfs_node_t get_rootdir() {
388388
return rootdir;
389389
}
390390

391+
void set_rootdir(vfs_node_t node) {
392+
rootdir = node;
393+
rootdir->parent = NULL;
394+
}
395+
391396
void *vfs_map(vfs_node_t node, uint64_t addr, uint64_t len, uint64_t prot, uint64_t flags,
392397
uint64_t offset) {
393398
if (unlikely(node == NULL)) return NULL;
@@ -461,8 +466,9 @@ errno_t vfs_mount(const char *src, vfs_node_t node) {
461466
if (node->type != file_dir) return VFS_STATUS_FAILED;
462467
for (int i = 1; i < fs_nextid; i++) {
463468
if (fs_callbacks[i]->mount(src, node) == 0) {
464-
node->fsid = i;
465-
node->root = node;
469+
node->fsid = i;
470+
node->root = node;
471+
node->is_mount = true;
466472
return VFS_STATUS_SUCCESS;
467473
}
468474
}
@@ -509,11 +515,11 @@ errno_t vfs_unmount(const char *path) {
509515
if (cur->root == cur) {
510516
vfs_free_child(cur);
511517
callbackof(cur, unmount)(cur->handle);
512-
cur->fsid = node->fsid; // 交给上级
513-
cur->root = node->root;
514-
cur->handle = NULL;
515-
cur->child = NULL;
516-
// cur->type = file_none;
518+
cur->fsid = node->fsid; // 交给上级
519+
cur->root = node->root;
520+
cur->handle = NULL;
521+
cur->child = NULL;
522+
cur->is_mount = false;
517523
if (cur->fsid) do_update(cur);
518524
return VFS_STATUS_SUCCESS;
519525
}

src/x86_64/include/pcb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ struct process_control_block {
113113
lock_queue *child_pcb; // 子进程列表
114114
page_directory_t *page_dir; // 进程页表
115115
vma_manager_t vma_manager; // VMA 分配管理器
116+
vfs_node_t procfs_node; // 进程私有 procfs 文件句柄
116117
char **envp; // 环境变量指针
117118
size_t envc; // 环境变量数量
118119
ucb_t user; // 用户会话

src/x86_64/include/procfs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ typedef struct proc_handle {
1212
pcb_t task;
1313
} proc_handle_t;
1414

15+
typedef struct procfs_self_handle {
16+
vfs_node_t self;
17+
} procfs_self_handle_t;
18+
1519
void procfs_update_task_list();
1620
void procfs_on_new_task(pcb_t task);
1721
void procfs_on_exit_task(pcb_t task);

src/x86_64/include/syscall.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@
171171
#define SYSCALL_ARCH_PRCTL 158
172172
#define SYSCALL_PIVOT_ROOT 155
173173
#define SYSCALL_G_AFFINITY 160
174+
#define SYSCALL_CHROOT 161
174175
#define SYSCALL_MOUNT 165
175176
#define SYSCALL_UMOUNT2 166
176177
#define SYSCALL_REBOOT 169

src/x86_64/include/vfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ struct vfs_node { // vfs节点
164164
list_t child; // 子节点
165165
vfs_node_t root; // 根目录
166166
bool visited; // 是否与具体文件系统同步
167+
bool is_mount; // 是否是挂载点
167168
};
168169

169170
struct fd {
@@ -317,6 +318,7 @@ errno_t vfs_unmount(const char *path);
317318
* @return 根目录节点
318319
*/
319320
vfs_node_t get_rootdir();
321+
void set_rootdir(vfs_node_t node);
320322

321323
char *vfs_get_fullpath(vfs_node_t node);
322324
char *at_resolve_pathname(int dirfd, char *pathname);

0 commit comments

Comments
 (0)