Skip to content

[BUG REPORT] File::drop 在调度敏感上下文中触发阻塞 metadata 读取,导致 schedule() 断言 panic #1825

@xboHodx

Description

@xboHodx

问题描述

File::drop() 会进入 flock 清理路径,而 flock 清理为了生成锁 key,会调用 inode.metadata()。在 ext4 上,这一步可能触发块
设备 I/O 和等待完成。若此时正处于调度/切换等不允许普通睡眠的上下文,就会在 schedule() 的 preempt_count == 0 断言处
panic。

已观察到的主调用链:

File::drop
-> flock::release_all_for_file
-> FlockManager::release_file
-> FlockManager::key_from_file
-> inode.metadata
-> VirtIOBlkDevice::read_at
-> BioRequest::wait
-> schedule
-> panic

相关代码:

  • kernel/src/filesystem/vfs/file.rs:1412
  • kernel/src/filesystem/vfs/flock.rs:176
  • kernel/src/filesystem/vfs/flock.rs:296
  • kernel/src/sched/mod.rs:848

初步判断根因是:flock release/drop 路径不应该依赖可能阻塞的 metadata 读取。

Fix Ideas

简单修复:

在 File 生命周期早期缓存 flock 所需的稳定 key,例如 (dev_id, inode_id),后续 flock 获取和释放都只读缓存,不再在 File::drop() 中调用 inode.metadata()。

贴近 Linux 的做法:

重构 flock 模型,让锁状态直接挂在 inode 上,锁 owner 直接绑定到 File/open file 身份;close/drop 时按 file 身份清理锁,而不是在释放路径中重新通过 metadata 计算 key。这样更符合 Linux 的 file lock 设计,也能从根本上避免这类问题。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug-report这是一个bug报告(如果确认是一个bug,请管理人员添加`bug` label)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions