inode.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. use super::{dentry::Dentry, s_isblk, s_ischr, vfs::Vfs, DevId};
  2. use crate::io::Stream;
  3. use crate::kernel::constants::{
  4. EINVAL, EISDIR, ENOTDIR, EPERM, STATX_ATIME, STATX_BLOCKS, STATX_CTIME, STATX_GID, STATX_INO,
  5. STATX_MODE, STATX_MTIME, STATX_NLINK, STATX_SIZE, STATX_TYPE, STATX_UID, S_IFDIR, S_IFMT,
  6. };
  7. use crate::kernel::mem::PageCache;
  8. use crate::kernel::timer::Instant;
  9. use crate::{io::Buffer, prelude::*};
  10. use alloc::sync::{Arc, Weak};
  11. use core::{
  12. mem::MaybeUninit,
  13. ops::ControlFlow,
  14. ptr::addr_of_mut,
  15. sync::atomic::{AtomicU32, AtomicU64, Ordering},
  16. };
  17. use eonix_runtime::task::Task;
  18. use eonix_sync::RwLock;
  19. use posix_types::stat::StatX;
  20. pub type Ino = u64;
  21. pub type AtomicIno = AtomicU64;
  22. #[allow(dead_code)]
  23. pub type ISize = u64;
  24. pub type AtomicISize = AtomicU64;
  25. #[allow(dead_code)]
  26. pub type Nlink = u64;
  27. pub type AtomicNlink = AtomicU64;
  28. #[allow(dead_code)]
  29. pub type Uid = u32;
  30. pub type AtomicUid = AtomicU32;
  31. #[allow(dead_code)]
  32. pub type Gid = u32;
  33. pub type AtomicGid = AtomicU32;
  34. pub type Mode = u32;
  35. pub type AtomicMode = AtomicU32;
  36. #[derive(Debug)]
  37. pub struct InodeData {
  38. pub ino: Ino,
  39. pub size: AtomicISize,
  40. pub nlink: AtomicNlink,
  41. pub uid: AtomicUid,
  42. pub gid: AtomicGid,
  43. pub mode: AtomicMode,
  44. pub atime: Spin<Instant>,
  45. pub ctime: Spin<Instant>,
  46. pub mtime: Spin<Instant>,
  47. pub rwsem: RwLock<()>,
  48. pub vfs: Weak<dyn Vfs>,
  49. }
  50. impl InodeData {
  51. pub fn new(ino: Ino, vfs: Weak<dyn Vfs>) -> Self {
  52. Self {
  53. ino,
  54. vfs,
  55. atime: Spin::new(Instant::now()),
  56. ctime: Spin::new(Instant::now()),
  57. mtime: Spin::new(Instant::now()),
  58. rwsem: RwLock::new(()),
  59. size: AtomicU64::new(0),
  60. nlink: AtomicNlink::new(0),
  61. uid: AtomicUid::new(0),
  62. gid: AtomicGid::new(0),
  63. mode: AtomicMode::new(0),
  64. }
  65. }
  66. }
  67. #[allow(dead_code)]
  68. pub trait InodeInner:
  69. Send + Sync + core::ops::Deref<Target = InodeData> + core::ops::DerefMut
  70. {
  71. fn data(&self) -> &InodeData;
  72. fn data_mut(&mut self) -> &mut InodeData;
  73. }
  74. pub enum WriteOffset<'end> {
  75. Position(usize),
  76. End(&'end mut usize),
  77. }
  78. pub struct RenameData<'a, 'b> {
  79. pub old_dentry: &'a Arc<Dentry>,
  80. pub new_dentry: &'b Arc<Dentry>,
  81. pub new_parent: Arc<dyn Inode>,
  82. pub vfs: Arc<dyn Vfs>,
  83. pub is_exchange: bool,
  84. pub no_replace: bool,
  85. }
  86. #[allow(unused_variables)]
  87. pub trait Inode: Send + Sync + InodeInner + Any {
  88. fn is_dir(&self) -> bool {
  89. self.mode.load(Ordering::SeqCst) & S_IFDIR != 0
  90. }
  91. fn lookup(&self, dentry: &Arc<Dentry>) -> KResult<Option<Arc<dyn Inode>>> {
  92. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  93. }
  94. fn creat(&self, at: &Arc<Dentry>, mode: Mode) -> KResult<()> {
  95. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  96. }
  97. fn mkdir(&self, at: &Dentry, mode: Mode) -> KResult<()> {
  98. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  99. }
  100. fn mknod(&self, at: &Dentry, mode: Mode, dev: DevId) -> KResult<()> {
  101. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  102. }
  103. fn unlink(&self, at: &Arc<Dentry>) -> KResult<()> {
  104. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  105. }
  106. fn symlink(&self, at: &Arc<Dentry>, target: &[u8]) -> KResult<()> {
  107. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  108. }
  109. fn read(&self, buffer: &mut dyn Buffer, offset: usize) -> KResult<usize> {
  110. Err(if self.is_dir() { EISDIR } else { EINVAL })
  111. }
  112. fn read_direct(&self, buffer: &mut dyn Buffer, offset: usize) -> KResult<usize> {
  113. Err(if self.is_dir() { EISDIR } else { EINVAL })
  114. }
  115. fn write(&self, stream: &mut dyn Stream, offset: WriteOffset) -> KResult<usize> {
  116. Err(if self.is_dir() { EISDIR } else { EINVAL })
  117. }
  118. fn write_direct(&self, stream: &mut dyn Stream, offset: WriteOffset) -> KResult<usize> {
  119. Err(if self.is_dir() { EISDIR } else { EINVAL })
  120. }
  121. fn devid(&self) -> KResult<DevId> {
  122. Err(if self.is_dir() { EISDIR } else { EINVAL })
  123. }
  124. fn readlink(&self, buffer: &mut dyn Buffer) -> KResult<usize> {
  125. Err(if self.is_dir() { EISDIR } else { EINVAL })
  126. }
  127. fn truncate(&self, length: usize) -> KResult<()> {
  128. Err(if self.is_dir() { EISDIR } else { EPERM })
  129. }
  130. fn rename(&self, rename_data: RenameData) -> KResult<()> {
  131. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  132. }
  133. fn do_readdir(
  134. &self,
  135. offset: usize,
  136. callback: &mut dyn FnMut(&[u8], Ino) -> KResult<ControlFlow<(), ()>>,
  137. ) -> KResult<usize> {
  138. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  139. }
  140. fn chmod(&self, mode: Mode) -> KResult<()> {
  141. Err(EPERM)
  142. }
  143. fn chown(&self, uid: u32, gid: u32) -> KResult<()> {
  144. Err(EPERM)
  145. }
  146. fn page_cache(&self) -> Option<&PageCache> {
  147. None
  148. }
  149. fn statx(&self, stat: &mut StatX, mask: u32) -> KResult<()> {
  150. // Safety: ffi should have checked reference
  151. let vfs = self.vfs.upgrade().expect("Vfs is dropped");
  152. let size = self.size.load(Ordering::Relaxed);
  153. let mode = self.mode.load(Ordering::Relaxed);
  154. if mask & STATX_NLINK != 0 {
  155. stat.stx_nlink = self.nlink.load(Ordering::Acquire) as _;
  156. stat.stx_mask |= STATX_NLINK;
  157. }
  158. if mask & STATX_ATIME != 0 {
  159. let atime = *self.atime.lock();
  160. stat.stx_atime = atime.into();
  161. stat.stx_mask |= STATX_ATIME;
  162. }
  163. if mask & STATX_MTIME != 0 {
  164. let mtime = *self.mtime.lock();
  165. stat.stx_mtime = mtime.into();
  166. stat.stx_mask |= STATX_MTIME;
  167. }
  168. if mask & STATX_CTIME != 0 {
  169. let ctime = *self.ctime.lock();
  170. stat.stx_ctime = ctime.into();
  171. stat.stx_mask |= STATX_CTIME;
  172. }
  173. if mask & STATX_SIZE != 0 {
  174. stat.stx_size = self.size.load(Ordering::Relaxed) as _;
  175. stat.stx_mask |= STATX_SIZE;
  176. }
  177. stat.stx_mode = 0;
  178. if mask & STATX_MODE != 0 {
  179. stat.stx_mode |= (mode & !S_IFMT) as u16;
  180. stat.stx_mask |= STATX_MODE;
  181. }
  182. if mask & STATX_TYPE != 0 {
  183. stat.stx_mode |= (mode & S_IFMT) as u16;
  184. if s_isblk(mode) || s_ischr(mode) {
  185. let devid = self.devid();
  186. stat.stx_rdev_major = (devid? >> 8) & 0xff;
  187. stat.stx_rdev_minor = devid? & 0xff;
  188. }
  189. stat.stx_mask |= STATX_TYPE;
  190. }
  191. if mask & STATX_INO != 0 {
  192. stat.stx_ino = self.ino as _;
  193. stat.stx_mask |= STATX_INO;
  194. }
  195. if mask & STATX_BLOCKS != 0 {
  196. stat.stx_blocks = (size + 512 - 1) / 512;
  197. stat.stx_blksize = vfs.io_blksize() as _;
  198. stat.stx_mask |= STATX_BLOCKS;
  199. }
  200. if mask & STATX_UID != 0 {
  201. stat.stx_uid = self.uid.load(Ordering::Relaxed) as _;
  202. stat.stx_mask |= STATX_UID;
  203. }
  204. if mask & STATX_GID != 0 {
  205. stat.stx_gid = self.gid.load(Ordering::Relaxed) as _;
  206. stat.stx_mask |= STATX_GID;
  207. }
  208. let fsdev = vfs.fs_devid();
  209. stat.stx_dev_major = (fsdev >> 8) & 0xff;
  210. stat.stx_dev_minor = fsdev & 0xff;
  211. // TODO: support more attributes
  212. stat.stx_attributes_mask = 0;
  213. Ok(())
  214. }
  215. fn new_locked<F>(ino: Ino, vfs: Weak<dyn Vfs>, f: F) -> Arc<Self>
  216. where
  217. Self: Sized,
  218. F: FnOnce(*mut Self, &()),
  219. {
  220. let mut uninit = Arc::<Self>::new_uninit();
  221. let uninit_mut = Arc::get_mut(&mut uninit).unwrap();
  222. // Safety: `idata` is owned by `uninit`
  223. let idata = unsafe {
  224. addr_of_mut!(*(*uninit_mut.as_mut_ptr()).data_mut())
  225. .cast::<MaybeUninit<InodeData>>()
  226. .as_mut()
  227. .unwrap()
  228. };
  229. idata.write(InodeData::new(ino, vfs));
  230. f(
  231. uninit_mut.as_mut_ptr(),
  232. // SAFETY: `idata` is initialized and we will never move the lock.
  233. &Task::block_on(unsafe { idata.assume_init_ref() }.rwsem.read()),
  234. );
  235. // Safety: `uninit` is initialized
  236. unsafe { uninit.assume_init() }
  237. }
  238. }
  239. // TODO: define multiple inode structs a time
  240. macro_rules! define_struct_inode {
  241. ($v:vis struct $inode_t:ident;) => {
  242. $v struct $inode_t {
  243. /// Do not use this directly
  244. idata: $crate::kernel::vfs::inode::InodeData,
  245. }
  246. impl core::ops::Deref for $inode_t {
  247. type Target = $crate::kernel::vfs::inode::InodeData;
  248. fn deref(&self) -> &Self::Target {
  249. &self.idata
  250. }
  251. }
  252. impl core::ops::DerefMut for $inode_t {
  253. fn deref_mut(&mut self) -> &mut Self::Target {
  254. &mut self.idata
  255. }
  256. }
  257. impl $crate::kernel::vfs::inode::InodeInner for $inode_t {
  258. fn data(&self) -> &$crate::kernel::vfs::inode::InodeData {
  259. &self.idata
  260. }
  261. fn data_mut(&mut self) -> &mut $crate::kernel::vfs::inode::InodeData {
  262. &mut self.idata
  263. }
  264. }
  265. };
  266. ($v:vis struct $inode_t:ident { $($vis:vis $name:ident: $type:ty,)* }) => {
  267. $v struct $inode_t {
  268. /// Do not use this directly
  269. idata: $crate::kernel::vfs::inode::InodeData,
  270. $($vis $name: $type,)*
  271. }
  272. impl core::ops::Deref for $inode_t {
  273. type Target = $crate::kernel::vfs::inode::InodeData;
  274. fn deref(&self) -> &Self::Target {
  275. &self.idata
  276. }
  277. }
  278. impl core::ops::DerefMut for $inode_t {
  279. fn deref_mut(&mut self) -> &mut Self::Target {
  280. &mut self.idata
  281. }
  282. }
  283. impl $crate::kernel::vfs::inode::InodeInner for $inode_t {
  284. fn data(&self) -> &$crate::kernel::vfs::inode::InodeData {
  285. &self.idata
  286. }
  287. fn data_mut(&mut self) -> &mut $crate::kernel::vfs::inode::InodeData {
  288. &mut self.idata
  289. }
  290. }
  291. };
  292. }
  293. pub(crate) use define_struct_inode;