os/vfs/impls/
reg_file.rs

1//! 普通文件(Regular File)的 File trait 实现
2
3use crate::sync::SpinLock;
4use crate::vfs::{Dentry, File, FsError, Inode, InodeMetadata, OpenFlags, SeekWhence};
5use alloc::sync::Arc;
6
7/// 普通文件的 File 实现
8///
9/// 对底层 Inode 的会话包装,维护:
10/// - 当前文件偏移量(offset)
11/// - 打开标志位(O_RDONLY/O_WRONLY/O_APPEND 等)
12/// - 异步 I/O 所有者 PID
13///
14/// # 并发安全
15///
16/// `offset`、`flags` 和 `owner` 使用 `SpinLock` 保护,因为多线程可能通过 `fork()` 共享同一个 fd。
17pub struct RegFile {
18    /// 关联的 dentry (保留,用于某些操作如 fstat)
19    pub dentry: Arc<Dentry>,
20
21    /// 关联的 inode (缓存,避免每次从 dentry 获取)
22    pub inode: Arc<dyn Inode>,
23
24    /// 当前文件偏移量 (需要锁保护,因为多线程可能共享 fd)
25    offset: SpinLock<usize>,
26
27    /// 打开标志位 (需要锁保护以支持 F_SETFL)
28    flags: SpinLock<OpenFlags>,
29
30    /// 异步 I/O 所有者 PID (接收 SIGIO 信号的进程)
31    owner: SpinLock<Option<i32>>,
32}
33
34impl RegFile {
35    /// 创建新的 RegFile 实例
36    pub fn new(dentry: Arc<Dentry>, flags: OpenFlags) -> Self {
37        let inode = dentry.inode.clone();
38        Self {
39            dentry,
40            inode,
41            offset: SpinLock::new(0),
42            flags: SpinLock::new(flags),
43            owner: SpinLock::new(None),
44        }
45    }
46
47    /// 获取底层 inode 引用 (用于某些系统调用)
48    pub fn inode(&self) -> Arc<dyn Inode> {
49        self.inode.clone()
50    }
51
52    /// 获取底层 dentry 引用 (用于某些系统调用)
53    pub fn dentry(&self) -> Arc<Dentry> {
54        self.dentry.clone()
55    }
56
57    /// 设置文件状态标志 (F_SETFL)
58    ///
59    /// 只能修改部分标志,访问模式等不能被修改
60    pub fn set_flags(&self, new_flags: OpenFlags) -> Result<(), FsError> {
61        let mut flags = self.flags.lock();
62        *flags = new_flags;
63        Ok(())
64    }
65}
66
67impl File for RegFile {
68    fn readable(&self) -> bool {
69        self.flags.lock().readable()
70    }
71
72    fn writable(&self) -> bool {
73        self.flags.lock().writable()
74    }
75
76    fn read(&self, buf: &mut [u8]) -> Result<usize, FsError> {
77        // 检查权限
78        if !self.readable() {
79            return Err(FsError::PermissionDenied);
80        }
81
82        // 获取当前偏移量
83        let mut offset_guard = self.offset.lock();
84        let current_offset = *offset_guard;
85
86        // 调用 inode 的 read_at
87        let nread = self.inode.read_at(current_offset, buf)?;
88
89        // 更新偏移量
90        *offset_guard = current_offset + nread;
91
92        Ok(nread)
93    }
94
95    fn write(&self, buf: &[u8]) -> Result<usize, FsError> {
96        // 检查权限
97        if !self.writable() {
98            return Err(FsError::PermissionDenied);
99        }
100
101        // 获取写入偏移量
102        let mut offset_guard = self.offset.lock();
103        let flags = self.flags.lock();
104        let write_offset = if flags.contains(OpenFlags::O_APPEND) {
105            // O_APPEND: 总是写到文件末尾
106            self.inode.metadata()?.size
107        } else {
108            *offset_guard
109        };
110        drop(flags); // 释放 flags 锁
111
112        // 调用 inode 的 write_at
113        let nwritten = self.inode.write_at(write_offset, buf)?;
114
115        // 更新偏移量
116        *offset_guard = write_offset + nwritten;
117
118        Ok(nwritten)
119    }
120
121    fn metadata(&self) -> Result<InodeMetadata, FsError> {
122        self.inode.metadata()
123    }
124
125    fn lseek(&self, offset: isize, whence: SeekWhence) -> Result<usize, FsError> {
126        let mut offset_guard = self.offset.lock();
127        let current = *offset_guard as isize;
128        let file_size = self.inode.metadata()?.size as isize;
129
130        let new_offset = match whence {
131            SeekWhence::Set => offset,
132            SeekWhence::Cur => current + offset,
133            SeekWhence::End => file_size + offset,
134        };
135
136        // 检查偏移量合法性 (不能为负)
137        if new_offset < 0 {
138            return Err(FsError::InvalidArgument);
139        }
140
141        *offset_guard = new_offset as usize;
142        Ok(new_offset as usize)
143    }
144
145    fn offset(&self) -> usize {
146        *self.offset.lock()
147    }
148
149    fn flags(&self) -> OpenFlags {
150        *self.flags.lock()
151    }
152
153    fn inode(&self) -> Result<Arc<dyn Inode>, FsError> {
154        Ok(self.inode())
155    }
156
157    fn dentry(&self) -> Result<Arc<Dentry>, FsError> {
158        Ok(self.dentry())
159    }
160
161    fn set_status_flags(&self, new_flags: OpenFlags) -> Result<(), FsError> {
162        self.set_flags(new_flags)
163    }
164
165    fn get_owner(&self) -> Result<i32, FsError> {
166        Ok(self.owner.lock().unwrap_or(0))
167    }
168
169    fn set_owner(&self, pid: i32) -> Result<(), FsError> {
170        *self.owner.lock() = if pid == 0 { None } else { Some(pid) };
171        Ok(())
172    }
173
174    fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize, FsError> {
175        self.inode.read_at(offset, buf)
176    }
177
178    fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize, FsError> {
179        self.inode.write_at(offset, buf)
180    }
181
182    fn as_any(&self) -> &dyn core::any::Any {
183        self
184    }
185}