Fix the memory leak in procfs

This commit is contained in:
LI Qing 2021-10-14 17:00:34 +08:00 committed by Zongmin.Gu
parent 16966c0b28
commit 030b1c7fdf

@ -51,9 +51,6 @@ impl LockedPidDirINode {
// exe // exe
let exe_inode = ProcExeSymINode::new(&file.process_ref); let exe_inode = ProcExeSymINode::new(&file.process_ref);
file.entries.insert(String::from("exe"), exe_inode); file.entries.insert(String::from("exe"), exe_inode);
// fd
let fd_inode = LockedProcFdDirINode::new(&file.process_ref, file.this.upgrade().unwrap());
file.entries.insert(String::from("fd"), fd_inode);
// root // root
let root_inode = ProcRootSymINode::new(&file.process_ref); let root_inode = ProcRootSymINode::new(&file.process_ref);
file.entries.insert(String::from("root"), root_inode); file.entries.insert(String::from("root"), root_inode);
@ -77,6 +74,16 @@ impl DirProcINode for LockedPidDirINode {
if name == ".." { if name == ".." {
return Ok(Arc::clone(&file.parent)); return Ok(Arc::clone(&file.parent));
} }
// The 'fd' entry holds 1 Arc of LockedPidDirINode, so the LockedPidDirINode
// ifself will hold 2 Arcs. This makes it cannot be dropped automatically.
// We initialize the 'fd' here to avoid this.
// TODO:: Try to find a better solution.
if name == "fd" {
let fd_inode =
LockedProcFdDirINode::new(&file.process_ref, file.this.upgrade().unwrap());
return Ok(fd_inode);
}
if let Some(inode) = file.entries.get(name) { if let Some(inode) = file.entries.get(name) {
Ok(Arc::clone(inode)) Ok(Arc::clone(inode))
} else { } else {
@ -90,12 +97,13 @@ impl DirProcINode for LockedPidDirINode {
1 => Ok(String::from("..")), 1 => Ok(String::from("..")),
i => { i => {
let file = self.0.read().unwrap(); let file = self.0.read().unwrap();
let name = file if let Some(name) = file.entries.keys().nth(i - 2) {
.entries Ok(name.to_owned())
.keys() } else if i == file.entries.len() + 2 {
.nth(i - 2) Ok(String::from("fd"))
.ok_or(FsError::EntryNotFound)?; } else {
Ok(name.to_owned()) Err(FsError::EntryNotFound)
}
} }
} }
} }
@ -114,6 +122,17 @@ impl DirProcINode for LockedPidDirINode {
write_inode_entry!(&mut ctx, name, inode, &mut total_written_len); write_inode_entry!(&mut ctx, name, inode, &mut total_written_len);
} }
// Write the fd entry
if idx <= 2 + file.entries.len() {
write_entry!(
&mut ctx,
"fd",
PROC_INO,
vfs::FileType::Dir,
&mut total_written_len
);
}
Ok(total_written_len) Ok(total_written_len)
} }
} }