pub struct FileLockManager {
locks: SpinLock<BTreeMap<FileId, Vec<FileLockEntry>>>,
}Expand description
全局文件锁管理器
Fields§
§locks: SpinLock<BTreeMap<FileId, Vec<FileLockEntry>>>文件锁表:FileId -> 锁列表
Implementations§
Source§impl FileLockManager
impl FileLockManager
Sourcepub fn test_lock(
&self,
dev: u64,
ino: u64,
start: usize,
len: usize,
flock: &mut Flock,
pid: i32,
) -> Result<(), FsError>
pub fn test_lock( &self, dev: u64, ino: u64, start: usize, len: usize, flock: &mut Flock, pid: i32, ) -> Result<(), FsError>
测试锁(F_GETLK)
检查是否有锁会阻塞请求的锁。如果有冲突,返回冲突锁的信息。
Sourcepub fn set_lock(
&self,
dev: u64,
ino: u64,
start: usize,
len: usize,
lock_type: LockType,
pid: i32,
_blocking: bool,
) -> Result<(), FsError>
pub fn set_lock( &self, dev: u64, ino: u64, start: usize, len: usize, lock_type: LockType, pid: i32, _blocking: bool, ) -> Result<(), FsError>
设置锁(F_SETLK / F_SETLKW)
§参数
blocking: true 表示阻塞(F_SETLKW),false 表示非阻塞(F_SETLK)
§TODO: 实现 F_SETLKW 阻塞等待
当前实现在锁冲突时立即返回 WouldBlock,即使 blocking=true。
完整的 F_SETLKW 实现需要:
- 在 FileLockManager 中为每个文件维护一个 WaitQueue
- 锁冲突时,如果 blocking=true:
- 将当前任务加入该文件的等待队列
- 调用 yield_task() 让出 CPU
- 被唤醒后重新检查并尝试获取锁(可能需要循环)
- 释放锁时(包括进程退出),唤醒等待队列中的所有任务
- 需要处理信号中断(返回 EINTR)
参考实现:
ⓘ
loop {
if can_acquire_lock() {
acquire_and_break();
}
if !blocking {
return Err(WouldBlock);
}
// 检查信号
if has_pending_signal() {
return Err(Interrupted);
}
wait_queue.sleep(current_task());
}Sourcepub fn release_all_locks(&self, pid: i32)
pub fn release_all_locks(&self, pid: i32)
释放进程持有的所有锁(进程退出时调用)