-
-
Notifications
You must be signed in to change notification settings - Fork 184
fix(procfs): drop stale /proc/<pid> entries after reap #1819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -85,22 +85,20 @@ impl DirOps for RootDirOps { | |
| ) -> Result<Arc<dyn IndexNode>, SystemError> { | ||
| // 首先检查是否是 PID 目录 | ||
| if let Ok(pid) = name.parse::<RawPid>() { | ||
| // 检查进程是否存在 | ||
| if ProcessManager::find(pid).is_some() { | ||
| let mut cached_children = dir.cached_children().write(); | ||
|
|
||
| // 检查缓存中是否已存在 | ||
| if let Some(child) = cached_children.get(name) { | ||
| return Ok(child.clone()); | ||
| } | ||
|
|
||
| // 创建新的 PID 目录(只传递 PID,不传递进程引用) | ||
| let inode = PidDirOps::new_inode(pid, dir.self_ref_weak().clone()); | ||
| cached_children.insert(name.to_string(), inode.clone()); | ||
| return Ok(inode); | ||
| } else { | ||
| let mut cached_children = dir.cached_children().write(); | ||
|
|
||
| if ProcessManager::find(pid).is_none() { | ||
| cached_children.remove(name); | ||
| return Err(SystemError::ENOENT); | ||
| } | ||
|
|
||
| if let Some(child) = cached_children.get(name) { | ||
| return Ok(child.clone()); | ||
| } | ||
|
|
||
| let inode = PidDirOps::new_inode(pid, dir.self_ref_weak().clone()); | ||
| cached_children.insert(name.to_string(), inode.clone()); | ||
| return Ok(inode); | ||
| } | ||
|
|
||
| // 查找静态条目 | ||
|
|
@@ -132,8 +130,17 @@ impl DirOps for RootDirOps { | |
| // 获取缓存写锁并填充 | ||
| let mut cached_children = dir.cached_children().write(); | ||
|
|
||
| // 填充进程目录(只传递 PID) | ||
| for pid in pid_list { | ||
| // 先删除已经失效的 PID 目录缓存 | ||
| cached_children.retain(|name, _| { | ||
| if let Ok(pid) = name.parse::<RawPid>() { | ||
| pid_list.contains(&pid) | ||
|
Comment on lines
+134
to
+136
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This cache cleanup performs Useful? React with 👍 / 👎. |
||
| } else { | ||
| true | ||
| } | ||
| }); | ||
|
|
||
| // 再填充当前仍存在的 PID 目录 | ||
| for pid in pid_list.iter().copied() { | ||
| cached_children | ||
| .entry(pid.to_string()) | ||
| .or_insert_with(|| PidDirOps::new_inode(pid, dir.self_ref_weak().clone())); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ProcDir::findreturns a cached child immediately unlessvalidate_childrejects it (seetemplate/dir.rs), butRootDirOpsstill uses the default validator, so cached/proc/<pid>entries bypass this new existence check entirely. In practice, if a PID directory was cached before reap, later lookups can still resolve that stale inode without entering thislookup_childpath, so/proc/<pid>may remain visible until a separatereaddirtriggers cache pruning.Useful? React with 👍 / 👎.