xref: /DragonOS/kernel/src/driver/disk/ahci/ahci_inode.rs (revision 0d48c3c9c21a2dd470d0e1e58b507db60e0887bb)
1 use crate::filesystem::devfs::{DevFS, DeviceINode};
2 use crate::filesystem::vfs::file::FileMode;
3 use crate::filesystem::vfs::{
4     core::generate_inode_id, make_rawdev, FilePrivateData, FileSystem, FileType, IndexNode,
5     Metadata, PollStatus,
6 };
7 use crate::io::device::BlockDevice;
8 use crate::{
9     include::bindings::bindings::{EINVAL, ENOTSUP},
10     libs::spinlock::SpinLock,
11     time::TimeSpec,
12 };
13 use alloc::{
14     string::String,
15     sync::{Arc, Weak},
16     vec::Vec,
17 };
18 
19 use super::ahcidisk::LockedAhciDisk;
20 
21 #[derive(Debug)]
22 pub struct AhciInode {
23     /// uuid 暂时不知道有什么用(x
24     // uuid: Uuid,
25     /// 指向自身的弱引用
26     self_ref: Weak<LockedAhciInode>,
27     /// 指向inode所在的文件系统对象的指针
28     fs: Weak<DevFS>,
29     /// INode 元数据
30     metadata: Metadata,
31     /// INode 对应的磁盘
32     disk: Arc<LockedAhciDisk>,
33 }
34 
35 #[derive(Debug)]
36 pub struct LockedAhciInode(pub SpinLock<AhciInode>);
37 
38 impl LockedAhciInode {
39     pub fn new(disk: Arc<LockedAhciDisk>) -> Arc<Self> {
40         let inode = AhciInode {
41             // uuid: Uuid::new_v5(),
42             self_ref: Weak::default(),
43             fs: Weak::default(),
44             disk: disk,
45             metadata: Metadata {
46                 dev_id: 1,
47                 inode_id: generate_inode_id(),
48                 size: 0,
49                 blk_size: 0,
50                 blocks: 0,
51                 atime: TimeSpec::default(),
52                 mtime: TimeSpec::default(),
53                 ctime: TimeSpec::default(),
54                 file_type: FileType::BlockDevice, // 文件夹,block设备,char设备
55                 mode: 0o666,
56                 nlinks: 1,
57                 uid: 0,
58                 gid: 0,
59                 raw_dev: make_rawdev(1, 3), // 这里用来作为device number
60             },
61         };
62 
63         let result = Arc::new(LockedAhciInode(SpinLock::new(inode)));
64         result.0.lock().self_ref = Arc::downgrade(&result);
65 
66         return result;
67     }
68 }
69 
70 impl DeviceINode for LockedAhciInode {
71     fn set_fs(&self, fs: Weak<DevFS>) {
72         self.0.lock().fs = fs;
73     }
74 }
75 
76 impl IndexNode for LockedAhciInode {
77     fn as_any_ref(&self) -> &dyn core::any::Any {
78         self
79     }
80 
81     fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), i32> {
82         Err(-(ENOTSUP as i32))
83     }
84 
85     fn close(&self, _data: &mut FilePrivateData) -> Result<(), i32> {
86         Err(-(ENOTSUP as i32))
87     }
88 
89     fn metadata(&self) -> Result<Metadata, i32> {
90         return Ok(self.0.lock().metadata.clone());
91     }
92 
93     fn fs(&self) -> Arc<dyn FileSystem> {
94         return self.0.lock().fs.upgrade().unwrap();
95     }
96 
97     fn list(&self) -> Result<Vec<String>, i32> {
98         Err(-(ENOTSUP as i32))
99     }
100 
101     fn set_metadata(&self, metadata: &Metadata) -> Result<(), i32> {
102         let mut inode = self.0.lock();
103         inode.metadata.atime = metadata.atime;
104         inode.metadata.mtime = metadata.mtime;
105         inode.metadata.ctime = metadata.ctime;
106         inode.metadata.mode = metadata.mode;
107         inode.metadata.uid = metadata.uid;
108         inode.metadata.gid = metadata.gid;
109 
110         return Ok(());
111     }
112 
113     fn poll(&self) -> Result<PollStatus, i32> {
114         return Ok(PollStatus {
115             flags: PollStatus::READ_MASK | PollStatus::WRITE_MASK,
116         });
117     }
118 
119     /// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写
120     fn read_at(
121         &self,
122         offset: usize, // lba地址
123         len: usize,
124         buf: &mut [u8],
125         data: &mut FilePrivateData,
126     ) -> Result<usize, i32> {
127         if buf.len() < len {
128             return Err(-(EINVAL as i32));
129         }
130 
131         if let FilePrivateData::Unused = data {
132             return self.0.lock().disk.read_at(offset, len, buf);
133         }
134 
135         return Err(-(EINVAL as i32));
136     }
137 
138     /// 写设备 - 应该调用设备的函数读写,而不是通过文件系统读写
139     fn write_at(
140         &self,
141         offset: usize, // lba地址
142         len: usize,
143         buf: &[u8],
144         data: &mut FilePrivateData,
145     ) -> Result<usize, i32> {
146         if buf.len() < len {
147             return Err(-(EINVAL as i32));
148         }
149 
150         if let FilePrivateData::Unused = data {
151             return self.0.lock().disk.write_at(offset, len, buf);
152         }
153 
154         return Err(-(EINVAL as i32));
155     }
156 }
157