mount.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. use core::{
  2. any::Any,
  3. sync::atomic::{compiler_fence, Ordering},
  4. };
  5. use alloc::{
  6. collections::BTreeMap,
  7. sync::{Arc, Weak},
  8. };
  9. use crate::{libs::spinlock::SpinLock, syscall::SystemError};
  10. use super::{
  11. file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,
  12. };
  13. /// @brief 挂载文件系统
  14. /// 挂载文件系统的时候,套了MountFS这一层,以实现文件系统的递归挂载
  15. #[derive(Debug)]
  16. pub struct MountFS {
  17. // MountFS内部的文件系统
  18. inner_filesystem: Arc<dyn FileSystem>,
  19. /// 用来存储InodeID->挂载点的MountFS的B树
  20. mountpoints: SpinLock<BTreeMap<InodeId, Arc<MountFS>>>,
  21. /// 当前文件系统挂载到的那个挂载点的Inode
  22. self_mountpoint: Option<Arc<MountFSInode>>,
  23. /// 指向当前MountFS的弱引用
  24. self_ref: Weak<MountFS>,
  25. }
  26. /// @brief MountFS的Index Node 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。
  27. #[derive(Debug)]
  28. pub struct MountFSInode {
  29. /// 当前挂载点对应到具体的文件系统的Inode
  30. inner_inode: Arc<dyn IndexNode>,
  31. /// 当前Inode对应的MountFS
  32. mount_fs: Arc<MountFS>,
  33. /// 指向自身的弱引用
  34. self_ref: Weak<MountFSInode>,
  35. }
  36. impl MountFS {
  37. pub fn new(
  38. inner_fs: Arc<dyn FileSystem>,
  39. self_mountpoint: Option<Arc<MountFSInode>>,
  40. ) -> Arc<Self> {
  41. return MountFS {
  42. inner_filesystem: inner_fs,
  43. mountpoints: SpinLock::new(BTreeMap::new()),
  44. self_mountpoint: self_mountpoint,
  45. self_ref: Weak::default(),
  46. }
  47. .wrap();
  48. }
  49. /// @brief 用Arc指针包裹MountFS对象。
  50. /// 本函数的主要功能为,初始化MountFS对象中的自引用Weak指针
  51. /// 本函数只应在构造器中被调用
  52. fn wrap(self) -> Arc<Self> {
  53. // 创建Arc指针
  54. let mount_fs: Arc<MountFS> = Arc::new(self);
  55. // 创建weak指针
  56. let weak: Weak<MountFS> = Arc::downgrade(&mount_fs);
  57. // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值
  58. let ptr: *mut MountFS = Arc::into_raw(mount_fs) as *mut Self;
  59. unsafe {
  60. (*ptr).self_ref = weak;
  61. // 返回初始化好的MountFS对象
  62. return Arc::from_raw(ptr);
  63. }
  64. }
  65. /// @brief 获取挂载点的文件系统的root inode
  66. pub fn mountpoint_root_inode(&self) -> Arc<MountFSInode> {
  67. return MountFSInode {
  68. inner_inode: self.inner_filesystem.root_inode(),
  69. mount_fs: self.self_ref.upgrade().unwrap(),
  70. self_ref: Weak::default(),
  71. }
  72. .wrap();
  73. }
  74. pub fn inner_filesystem(&self) -> Arc<dyn FileSystem> {
  75. return self.inner_filesystem.clone();
  76. }
  77. }
  78. impl MountFSInode {
  79. /// @brief 用Arc指针包裹MountFSInode对象。
  80. /// 本函数的主要功能为,初始化MountFSInode对象中的自引用Weak指针
  81. /// 本函数只应在构造器中被调用
  82. fn wrap(self) -> Arc<Self> {
  83. // 创建Arc指针
  84. let inode: Arc<MountFSInode> = Arc::new(self);
  85. // 创建Weak指针
  86. let weak: Weak<MountFSInode> = Arc::downgrade(&inode);
  87. // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值
  88. compiler_fence(Ordering::SeqCst);
  89. let ptr: *mut MountFSInode = Arc::into_raw(inode.clone()) as *mut Self;
  90. compiler_fence(Ordering::SeqCst);
  91. unsafe {
  92. (*ptr).self_ref = weak;
  93. compiler_fence(Ordering::SeqCst);
  94. // 返回初始化好的MountFSInode对象
  95. return inode;
  96. }
  97. }
  98. /// @brief 判断当前inode是否为它所在的文件系统的root inode
  99. fn is_mountpoint_root(&self) -> Result<bool, SystemError> {
  100. return Ok(self.inner_inode.fs().root_inode().metadata()?.inode_id
  101. == self.inner_inode.metadata()?.inode_id);
  102. }
  103. /// @brief 在挂载树上进行inode替换。
  104. /// 如果当前inode是父MountFS内的一个挂载点,那么,本函数将会返回挂载到这个挂载点下的文件系统的root inode.
  105. /// 如果当前inode在父MountFS内,但不是挂载点,那么说明在这里不需要进行inode替换,因此直接返回当前inode。
  106. ///
  107. /// @return Arc<MountFSInode>
  108. fn overlaid_inode(&self) -> Arc<MountFSInode> {
  109. let inode_id = self.metadata().unwrap().inode_id;
  110. if let Some(sub_mountfs) = self.mount_fs.mountpoints.lock().get(&inode_id) {
  111. return sub_mountfs.mountpoint_root_inode();
  112. } else {
  113. return self.self_ref.upgrade().unwrap();
  114. }
  115. }
  116. }
  117. impl IndexNode for MountFSInode {
  118. fn open(&self, data: &mut FilePrivateData, mode: &FileMode) -> Result<(), SystemError> {
  119. return self.inner_inode.open(data, mode);
  120. }
  121. fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> {
  122. return self.inner_inode.close(data);
  123. }
  124. fn create_with_data(
  125. &self,
  126. name: &str,
  127. file_type: FileType,
  128. mode: ModeType,
  129. data: usize,
  130. ) -> Result<Arc<dyn IndexNode>, SystemError> {
  131. return Ok(MountFSInode {
  132. inner_inode: self
  133. .inner_inode
  134. .create_with_data(name, file_type, mode, data)?,
  135. mount_fs: self.mount_fs.clone(),
  136. self_ref: Weak::default(),
  137. }
  138. .wrap());
  139. }
  140. fn truncate(&self, len: usize) -> Result<(), SystemError> {
  141. return self.inner_inode.truncate(len);
  142. }
  143. fn read_at(
  144. &self,
  145. offset: usize,
  146. len: usize,
  147. buf: &mut [u8],
  148. data: &mut FilePrivateData,
  149. ) -> Result<usize, SystemError> {
  150. return self.inner_inode.read_at(offset, len, buf, data);
  151. }
  152. fn write_at(
  153. &self,
  154. offset: usize,
  155. len: usize,
  156. buf: &[u8],
  157. data: &mut FilePrivateData,
  158. ) -> Result<usize, SystemError> {
  159. return self.inner_inode.write_at(offset, len, buf, data);
  160. }
  161. #[inline]
  162. fn poll(&self) -> Result<super::PollStatus, SystemError> {
  163. return self.inner_inode.poll();
  164. }
  165. #[inline]
  166. fn fs(&self) -> Arc<dyn FileSystem> {
  167. return self.mount_fs.clone();
  168. }
  169. #[inline]
  170. fn as_any_ref(&self) -> &dyn core::any::Any {
  171. return self.inner_inode.as_any_ref();
  172. }
  173. #[inline]
  174. fn metadata(&self) -> Result<super::Metadata, SystemError> {
  175. return self.inner_inode.metadata();
  176. }
  177. #[inline]
  178. fn set_metadata(&self, metadata: &super::Metadata) -> Result<(), SystemError> {
  179. return self.inner_inode.set_metadata(metadata);
  180. }
  181. #[inline]
  182. fn resize(&self, len: usize) -> Result<(), SystemError> {
  183. return self.inner_inode.resize(len);
  184. }
  185. #[inline]
  186. fn create(
  187. &self,
  188. name: &str,
  189. file_type: FileType,
  190. mode: ModeType,
  191. ) -> Result<Arc<dyn IndexNode>, SystemError> {
  192. return Ok(MountFSInode {
  193. inner_inode: self.inner_inode.create(name, file_type, mode)?,
  194. mount_fs: self.mount_fs.clone(),
  195. self_ref: Weak::default(),
  196. }
  197. .wrap());
  198. }
  199. fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
  200. return self.inner_inode.link(name, other);
  201. }
  202. /// @brief 在挂载文件系统中删除文件/文件夹
  203. #[inline]
  204. fn unlink(&self, name: &str) -> Result<(), SystemError> {
  205. let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id;
  206. // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode
  207. if self.mount_fs.mountpoints.lock().contains_key(&inode_id) {
  208. return Err(SystemError::EBUSY);
  209. }
  210. // 调用内层的inode的方法来删除这个inode
  211. return self.inner_inode.unlink(name);
  212. }
  213. #[inline]
  214. fn rmdir(&self, name: &str) -> Result<(), SystemError> {
  215. let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id;
  216. // 先检查这个inode是否为一个挂载点,如果当前inode是一个挂载点,那么就不能删除这个inode
  217. if self.mount_fs.mountpoints.lock().contains_key(&inode_id) {
  218. return Err(SystemError::EBUSY);
  219. }
  220. // 调用内层的rmdir的方法来删除这个inode
  221. let r = self.inner_inode.rmdir(name);
  222. return r;
  223. }
  224. #[inline]
  225. fn move_(
  226. &self,
  227. old_name: &str,
  228. target: &Arc<dyn IndexNode>,
  229. new_name: &str,
  230. ) -> Result<(), SystemError> {
  231. return self.inner_inode.move_(old_name, target, new_name);
  232. }
  233. fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
  234. match name {
  235. // 查找的是当前目录
  236. "" | "." => return Ok(self.self_ref.upgrade().unwrap()),
  237. // 往父级查找
  238. ".." => {
  239. if self.is_mountpoint_root()? {
  240. // 当前inode是它所在的文件系统的root inode
  241. match &self.mount_fs.self_mountpoint {
  242. Some(inode) => {
  243. return inode.find(name);
  244. }
  245. None => {
  246. return Ok(self.self_ref.upgrade().unwrap());
  247. }
  248. }
  249. } else {
  250. // 向上查找时,不会跨过文件系统的边界,因此直接调用当前inode所在的文件系统的find方法进行查找
  251. return Ok(MountFSInode {
  252. inner_inode: self.inner_inode.find(name)?,
  253. mount_fs: self.mount_fs.clone(),
  254. self_ref: Weak::default(),
  255. }
  256. .wrap());
  257. }
  258. }
  259. // 在当前目录下查找
  260. _ => {
  261. // 直接调用当前inode所在的文件系统的find方法进行查找
  262. // 由于向下查找可能会跨越文件系统的边界,因此需要尝试替换inode
  263. return Ok(MountFSInode {
  264. inner_inode: self.inner_inode.find(name)?,
  265. mount_fs: self.mount_fs.clone(),
  266. self_ref: Weak::default(),
  267. }
  268. .wrap()
  269. .overlaid_inode());
  270. }
  271. }
  272. }
  273. #[inline]
  274. fn get_entry_name(&self, ino: InodeId) -> Result<alloc::string::String, SystemError> {
  275. return self.inner_inode.get_entry_name(ino);
  276. }
  277. #[inline]
  278. fn get_entry_name_and_metadata(
  279. &self,
  280. ino: InodeId,
  281. ) -> Result<(alloc::string::String, super::Metadata), SystemError> {
  282. return self.inner_inode.get_entry_name_and_metadata(ino);
  283. }
  284. #[inline]
  285. fn ioctl(&self, cmd: u32, data: usize) -> Result<usize, SystemError> {
  286. return self.inner_inode.ioctl(cmd, data);
  287. }
  288. #[inline]
  289. fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
  290. return self.inner_inode.list();
  291. }
  292. /// @brief 在当前inode下,挂载一个文件系统
  293. ///
  294. /// @return Ok(Arc<MountFS>) 挂载成功,返回指向MountFS的指针
  295. fn mount(&self, fs: Arc<dyn FileSystem>) -> Result<Arc<MountFS>, SystemError> {
  296. let metadata = self.inner_inode.metadata()?;
  297. if metadata.file_type != FileType::Dir {
  298. return Err(SystemError::ENOTDIR);
  299. }
  300. // 为新的挂载点创建挂载文件系统
  301. let new_mount_fs: Arc<MountFS> = MountFS::new(fs, Some(self.self_ref.upgrade().unwrap()));
  302. // 将新的挂载点-挂载文件系统添加到父级的挂载树
  303. self.mount_fs
  304. .mountpoints
  305. .lock()
  306. .insert(metadata.inode_id, new_mount_fs.clone());
  307. return Ok(new_mount_fs);
  308. }
  309. }
  310. impl FileSystem for MountFS {
  311. fn root_inode(&self) -> Arc<dyn IndexNode> {
  312. match &self.self_mountpoint {
  313. Some(inode) => return inode.mount_fs.root_inode(),
  314. // 当前文件系统是rootfs
  315. None => self.mountpoint_root_inode(),
  316. }
  317. }
  318. fn info(&self) -> super::FsInfo {
  319. return self.inner_filesystem.info();
  320. }
  321. /// @brief 本函数用于实现动态转换。
  322. /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
  323. fn as_any_ref(&self) -> &dyn Any {
  324. self
  325. }
  326. }