fat32.rs 9.7 KB

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