fat32.rs 12 KB

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