fat32.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. mod dir;
  2. mod file;
  3. use crate::io::Stream;
  4. use crate::kernel::constants::EIO;
  5. use crate::kernel::mem::AsMemoryBlock;
  6. use crate::kernel::task::block_on;
  7. use crate::kernel::vfs::inode::WriteOffset;
  8. use crate::{
  9. io::{Buffer, ByteBuffer, UninitBuffer},
  10. kernel::{
  11. block::{make_device, BlockDevice, BlockDeviceRequest},
  12. constants::{S_IFDIR, S_IFREG},
  13. mem::{
  14. paging::Page,
  15. {CachePage, PageCache, PageCacheBackend},
  16. },
  17. vfs::{
  18. dentry::Dentry,
  19. inode::{define_struct_inode, Ino, Inode, InodeData},
  20. mount::{register_filesystem, Mount, MountCreator},
  21. vfs::Vfs,
  22. DevId,
  23. },
  24. },
  25. prelude::*,
  26. KResult,
  27. };
  28. use alloc::{
  29. collections::btree_map::BTreeMap,
  30. sync::{Arc, Weak},
  31. vec::Vec,
  32. };
  33. use core::{ops::ControlFlow, sync::atomic::Ordering};
  34. use dir::Dirs as _;
  35. use eonix_sync::RwLock;
  36. use file::ClusterRead;
  37. type ClusterNo = u32;
  38. const SECTOR_SIZE: usize = 512;
  39. #[derive(Clone, Copy)]
  40. #[repr(C, packed)]
  41. struct Bootsector {
  42. jmp: [u8; 3],
  43. oem: [u8; 8],
  44. bytes_per_sector: u16,
  45. sectors_per_cluster: u8,
  46. reserved_sectors: u16,
  47. fat_copies: u8,
  48. root_entries: u16, // should be 0 for FAT32
  49. _total_sectors: u16, // outdated
  50. media: u8,
  51. _sectors_per_fat: u16, // outdated
  52. sectors_per_track: u16,
  53. heads: u16,
  54. hidden_sectors: u32,
  55. total_sectors: u32,
  56. sectors_per_fat: u32,
  57. flags: u16,
  58. fat_version: u16,
  59. root_cluster: ClusterNo,
  60. fsinfo_sector: u16,
  61. backup_bootsector: u16,
  62. _reserved: [u8; 12],
  63. drive_number: u8,
  64. _reserved2: u8,
  65. ext_sig: u8,
  66. serial: u32,
  67. volume_label: [u8; 11],
  68. fs_type: [u8; 8],
  69. bootcode: [u8; 420],
  70. mbr_signature: u16,
  71. }
  72. impl_any!(FatFs);
  73. /// # Lock order
  74. /// 2. FatTable
  75. /// 3. Inodes
  76. ///
  77. struct FatFs {
  78. sectors_per_cluster: u8,
  79. rootdir_cluster: ClusterNo,
  80. data_start: u64,
  81. volume_label: [u8; 11],
  82. device: Arc<BlockDevice>,
  83. fat: RwLock<Vec<ClusterNo>>,
  84. weak: Weak<FatFs>,
  85. icache: BTreeMap<Ino, FatInode>,
  86. }
  87. impl Vfs for FatFs {
  88. fn io_blksize(&self) -> usize {
  89. 4096
  90. }
  91. fn fs_devid(&self) -> DevId {
  92. self.device.devid()
  93. }
  94. fn is_read_only(&self) -> bool {
  95. true
  96. }
  97. }
  98. impl FatFs {
  99. fn read_cluster(&self, cluster: ClusterNo, buf: &Page) -> KResult<()> {
  100. let cluster = cluster - 2;
  101. let rq = BlockDeviceRequest::Read {
  102. sector: self.data_start as u64 + cluster as u64 * self.sectors_per_cluster as u64,
  103. count: self.sectors_per_cluster as u64,
  104. buffer: core::slice::from_ref(buf),
  105. };
  106. self.device.commit_request(rq)?;
  107. Ok(())
  108. }
  109. fn get_or_alloc_inode(&self, ino: Ino, is_directory: bool, size: u32) -> Arc<dyn Inode> {
  110. self.icache
  111. .get(&ino)
  112. .cloned()
  113. .map(FatInode::unwrap)
  114. .unwrap_or_else(|| {
  115. if is_directory {
  116. DirInode::new(ino, self.weak.clone(), size)
  117. } else {
  118. FileInode::new(ino, self.weak.clone(), size)
  119. }
  120. })
  121. }
  122. }
  123. impl FatFs {
  124. pub fn create(device: DevId) -> KResult<(Arc<Self>, Arc<dyn Inode>)> {
  125. let device = BlockDevice::get(device)?;
  126. let mut fatfs_arc = Arc::new_cyclic(|weak: &Weak<FatFs>| Self {
  127. device,
  128. sectors_per_cluster: 0,
  129. rootdir_cluster: 0,
  130. data_start: 0,
  131. fat: RwLock::new(Vec::new()),
  132. weak: weak.clone(),
  133. icache: BTreeMap::new(),
  134. volume_label: [0; 11],
  135. });
  136. let fatfs = unsafe { Arc::get_mut_unchecked(&mut fatfs_arc) };
  137. let mut info: UninitBuffer<Bootsector> = UninitBuffer::new();
  138. fatfs.device.read_some(0, &mut info)?.ok_or(EIO)?;
  139. let info = info.assume_filled_ref()?;
  140. fatfs.sectors_per_cluster = info.sectors_per_cluster;
  141. fatfs.rootdir_cluster = info.root_cluster;
  142. fatfs.data_start =
  143. info.reserved_sectors as u64 + info.fat_copies as u64 * info.sectors_per_fat as u64;
  144. let fat = fatfs.fat.get_mut();
  145. fat.resize(
  146. 512 * info.sectors_per_fat as usize / core::mem::size_of::<ClusterNo>(),
  147. 0,
  148. );
  149. let mut buffer = ByteBuffer::from(fat.as_mut_slice());
  150. fatfs
  151. .device
  152. .read_some(info.reserved_sectors as usize * 512, &mut buffer)?
  153. .ok_or(EIO)?;
  154. info.volume_label
  155. .iter()
  156. .take_while(|&&c| c != ' ' as u8)
  157. .take(11)
  158. .enumerate()
  159. .for_each(|(idx, c)| fatfs.volume_label[idx] = *c);
  160. let root_dir_cluster_count = ClusterIterator::new(fat, fatfs.rootdir_cluster).count();
  161. let root_dir_size = root_dir_cluster_count as u32 * info.sectors_per_cluster as u32 * 512;
  162. let root_inode = DirInode::new(
  163. (info.root_cluster & !0xF000_0000) as Ino,
  164. fatfs.weak.clone(),
  165. root_dir_size,
  166. );
  167. Ok((fatfs_arc, root_inode))
  168. }
  169. }
  170. struct ClusterIterator<'fat> {
  171. fat: &'fat [ClusterNo],
  172. cur: ClusterNo,
  173. }
  174. impl<'fat> ClusterIterator<'fat> {
  175. fn new(fat: &'fat [ClusterNo], start: ClusterNo) -> Self {
  176. Self { fat, cur: start }
  177. }
  178. }
  179. impl<'fat> Iterator for ClusterIterator<'fat> {
  180. type Item = ClusterNo;
  181. fn next(&mut self) -> Option<Self::Item> {
  182. const EOC: ClusterNo = 0x0FFF_FFF8;
  183. const INVL: ClusterNo = 0xF000_0000;
  184. match self.cur {
  185. ..2 | EOC..INVL => None,
  186. INVL.. => unreachable!("Invalid cluster number: {}", self.cur),
  187. next => {
  188. self.cur = self.fat[next as usize] & !INVL;
  189. Some(next)
  190. }
  191. }
  192. }
  193. }
  194. #[allow(dead_code)]
  195. #[derive(Clone)]
  196. enum FatInode {
  197. File(Arc<FileInode>),
  198. Dir(Arc<DirInode>),
  199. }
  200. impl FatInode {
  201. fn unwrap(self) -> Arc<dyn Inode> {
  202. match self {
  203. FatInode::File(inode) => inode,
  204. FatInode::Dir(inode) => inode,
  205. }
  206. }
  207. }
  208. define_struct_inode! {
  209. struct FileInode {
  210. page_cache: PageCache,
  211. }
  212. }
  213. impl FileInode {
  214. fn new(ino: Ino, weak: Weak<FatFs>, size: u32) -> Arc<Self> {
  215. let inode = Arc::new_cyclic(|weak_self: &Weak<FileInode>| Self {
  216. idata: InodeData::new(ino, weak),
  217. page_cache: PageCache::new(weak_self.clone()),
  218. });
  219. // Safety: We are initializing the inode
  220. inode.nlink.store(1, Ordering::Relaxed);
  221. inode.mode.store(S_IFREG | 0o777, Ordering::Relaxed);
  222. inode.size.store(size as u64, Ordering::Relaxed);
  223. inode
  224. }
  225. }
  226. impl Inode for FileInode {
  227. fn page_cache(&self) -> Option<&PageCache> {
  228. Some(&self.page_cache)
  229. }
  230. fn read(&self, buffer: &mut dyn Buffer, offset: usize) -> KResult<usize> {
  231. block_on(self.page_cache.read(buffer, offset))
  232. }
  233. fn read_direct(&self, buffer: &mut dyn Buffer, offset: usize) -> KResult<usize> {
  234. let vfs = self.vfs.upgrade().ok_or(EIO)?;
  235. let vfs = vfs.as_any().downcast_ref::<FatFs>().unwrap();
  236. let fat = block_on(vfs.fat.read());
  237. if self.size.load(Ordering::Relaxed) as usize == 0 {
  238. return Ok(0);
  239. }
  240. let cluster_size = vfs.sectors_per_cluster as usize * SECTOR_SIZE;
  241. assert!(cluster_size <= 0x1000, "Cluster size is too large");
  242. let skip_clusters = offset / cluster_size;
  243. let inner_offset = offset % cluster_size;
  244. let cluster_iter =
  245. ClusterIterator::new(fat.as_ref(), self.ino as ClusterNo).skip(skip_clusters);
  246. let buffer_page = Page::alloc();
  247. for cluster in cluster_iter {
  248. vfs.read_cluster(cluster, &buffer_page)?;
  249. let data = unsafe {
  250. // SAFETY: We are the only one holding this page.
  251. &buffer_page.as_memblk().as_bytes()[inner_offset..]
  252. };
  253. let end = offset + data.len();
  254. let real_end = core::cmp::min(end, self.size.load(Ordering::Relaxed) as usize);
  255. let real_size = real_end - offset;
  256. if buffer.fill(&data[..real_size])?.should_stop() {
  257. break;
  258. }
  259. }
  260. Ok(buffer.wrote())
  261. }
  262. fn write(&self, stream: &mut dyn Stream, offset: WriteOffset) -> KResult<usize> {
  263. todo!()
  264. }
  265. fn write_direct(&self, stream: &mut dyn Stream, offset: WriteOffset) -> KResult<usize> {
  266. todo!()
  267. }
  268. }
  269. impl PageCacheBackend for FileInode {
  270. fn read_page(&self, page: &mut CachePage, offset: usize) -> KResult<usize> {
  271. self.read_direct(page, offset)
  272. }
  273. fn write_page(&self, page: &CachePage, offset: usize) -> KResult<usize> {
  274. todo!()
  275. }
  276. fn size(&self) -> usize {
  277. self.size.load(Ordering::Relaxed) as usize
  278. }
  279. }
  280. define_struct_inode! {
  281. struct DirInode;
  282. }
  283. impl DirInode {
  284. fn new(ino: Ino, weak: Weak<FatFs>, size: u32) -> Arc<Self> {
  285. let inode = Arc::new(Self {
  286. idata: InodeData::new(ino, weak),
  287. });
  288. // Safety: We are initializing the inode
  289. inode.nlink.store(2, Ordering::Relaxed);
  290. inode.mode.store(S_IFDIR | 0o777, Ordering::Relaxed);
  291. inode.size.store(size as u64, Ordering::Relaxed);
  292. inode
  293. }
  294. }
  295. impl Inode for DirInode {
  296. fn lookup(&self, dentry: &Arc<Dentry>) -> KResult<Option<Arc<dyn Inode>>> {
  297. let vfs = self.vfs.upgrade().ok_or(EIO)?;
  298. let vfs = vfs.as_any().downcast_ref::<FatFs>().unwrap();
  299. let fat = block_on(vfs.fat.read());
  300. let mut entries = ClusterIterator::new(fat.as_ref(), self.ino as ClusterNo)
  301. .read(vfs, 0)
  302. .dirs();
  303. let entry = entries.find(|entry| {
  304. entry
  305. .as_ref()
  306. .map(|entry| &entry.filename == &***dentry.name())
  307. .unwrap_or(true)
  308. });
  309. match entry {
  310. None => Ok(None),
  311. Some(Err(err)) => Err(err),
  312. Some(Ok(entry)) => Ok(Some(vfs.get_or_alloc_inode(
  313. entry.cluster as Ino,
  314. entry.is_directory,
  315. entry.size,
  316. ))),
  317. }
  318. }
  319. fn do_readdir(
  320. &self,
  321. offset: usize,
  322. callback: &mut dyn FnMut(&[u8], Ino) -> KResult<ControlFlow<(), ()>>,
  323. ) -> KResult<usize> {
  324. let vfs = self.vfs.upgrade().ok_or(EIO)?;
  325. let vfs = vfs.as_any().downcast_ref::<FatFs>().unwrap();
  326. let fat = block_on(vfs.fat.read());
  327. let cluster_iter = ClusterIterator::new(fat.as_ref(), self.ino as ClusterNo)
  328. .read(vfs, offset)
  329. .dirs();
  330. let mut nread = 0usize;
  331. for entry in cluster_iter {
  332. let entry = entry?;
  333. vfs.get_or_alloc_inode(entry.cluster as Ino, entry.is_directory, entry.size);
  334. if callback(&entry.filename, entry.cluster as Ino)?.is_break() {
  335. break;
  336. }
  337. nread += entry.entry_offset as usize;
  338. }
  339. Ok(nread)
  340. }
  341. }
  342. struct FatMountCreator;
  343. impl MountCreator for FatMountCreator {
  344. fn check_signature(&self, mut first_block: &[u8]) -> KResult<bool> {
  345. match first_block.split_off(82..) {
  346. Some([b'F', b'A', b'T', b'3', b'2', b' ', b' ', b' ', ..]) => Ok(true),
  347. Some(..) => Ok(false),
  348. None => Err(EIO),
  349. }
  350. }
  351. fn create_mount(&self, _source: &str, _flags: u64, mp: &Arc<Dentry>) -> KResult<Mount> {
  352. let (fatfs, root_inode) = FatFs::create(make_device(8, 1))?;
  353. Mount::new(mp, fatfs, root_inode)
  354. }
  355. }
  356. pub fn init() {
  357. register_filesystem("fat32", Arc::new(FatMountCreator)).unwrap();
  358. }