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