inode.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. use super::{dentry::Dentry, 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_IFBLK, S_IFCHR,
  6. S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
  7. };
  8. use crate::kernel::mem::PageCache;
  9. use crate::kernel::syscall::{FromSyscallArg, SyscallRetVal};
  10. use crate::kernel::task::block_on;
  11. use crate::kernel::timer::Instant;
  12. use crate::{io::Buffer, prelude::*};
  13. use alloc::sync::{Arc, Weak};
  14. use core::{
  15. mem::MaybeUninit,
  16. ops::ControlFlow,
  17. ptr::addr_of_mut,
  18. sync::atomic::{AtomicU32, AtomicU64, Ordering},
  19. };
  20. use eonix_sync::RwLock;
  21. use posix_types::stat::StatX;
  22. pub type Ino = u64;
  23. pub type AtomicIno = AtomicU64;
  24. #[allow(dead_code)]
  25. pub type ISize = u64;
  26. pub type AtomicISize = AtomicU64;
  27. #[allow(dead_code)]
  28. pub type Nlink = u64;
  29. pub type AtomicNlink = AtomicU64;
  30. #[allow(dead_code)]
  31. pub type Uid = u32;
  32. pub type AtomicUid = AtomicU32;
  33. #[allow(dead_code)]
  34. pub type Gid = u32;
  35. pub type AtomicGid = AtomicU32;
  36. #[derive(Clone, Copy, PartialEq, Eq)]
  37. pub struct Mode(u32);
  38. pub struct AtomicMode(AtomicU32);
  39. #[derive(Debug)]
  40. pub struct InodeData {
  41. pub ino: Ino,
  42. pub size: AtomicISize,
  43. pub nlink: AtomicNlink,
  44. pub uid: AtomicUid,
  45. pub gid: AtomicGid,
  46. pub mode: AtomicMode,
  47. pub atime: Spin<Instant>,
  48. pub ctime: Spin<Instant>,
  49. pub mtime: Spin<Instant>,
  50. pub rwsem: RwLock<()>,
  51. pub vfs: Weak<dyn Vfs>,
  52. }
  53. impl InodeData {
  54. pub fn new(ino: Ino, vfs: Weak<dyn Vfs>) -> Self {
  55. Self {
  56. ino,
  57. vfs,
  58. atime: Spin::new(Instant::now()),
  59. ctime: Spin::new(Instant::now()),
  60. mtime: Spin::new(Instant::now()),
  61. rwsem: RwLock::new(()),
  62. size: AtomicU64::new(0),
  63. nlink: AtomicNlink::new(0),
  64. uid: AtomicUid::new(0),
  65. gid: AtomicGid::new(0),
  66. mode: AtomicMode::new(0),
  67. }
  68. }
  69. }
  70. #[allow(dead_code)]
  71. pub trait InodeInner:
  72. Send + Sync + core::ops::Deref<Target = InodeData> + core::ops::DerefMut
  73. {
  74. fn data(&self) -> &InodeData;
  75. fn data_mut(&mut self) -> &mut InodeData;
  76. }
  77. pub enum WriteOffset<'end> {
  78. Position(usize),
  79. End(&'end mut usize),
  80. }
  81. pub struct RenameData<'a, 'b> {
  82. pub old_dentry: &'a Arc<Dentry>,
  83. pub new_dentry: &'b Arc<Dentry>,
  84. pub new_parent: Arc<dyn Inode>,
  85. pub vfs: Arc<dyn Vfs>,
  86. pub is_exchange: bool,
  87. pub no_replace: bool,
  88. }
  89. #[allow(unused_variables)]
  90. pub trait Inode: Send + Sync + InodeInner + Any {
  91. fn is_dir(&self) -> bool {
  92. self.mode.load().is_dir()
  93. }
  94. fn lookup(&self, dentry: &Arc<Dentry>) -> KResult<Option<Arc<dyn Inode>>> {
  95. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  96. }
  97. fn creat(&self, at: &Arc<Dentry>, mode: Mode) -> KResult<()> {
  98. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  99. }
  100. fn mkdir(&self, at: &Dentry, mode: Mode) -> KResult<()> {
  101. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  102. }
  103. fn mknod(&self, at: &Dentry, mode: Mode, dev: DevId) -> KResult<()> {
  104. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  105. }
  106. fn unlink(&self, at: &Arc<Dentry>) -> KResult<()> {
  107. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  108. }
  109. fn symlink(&self, at: &Arc<Dentry>, target: &[u8]) -> KResult<()> {
  110. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  111. }
  112. fn read(&self, buffer: &mut dyn Buffer, offset: usize) -> KResult<usize> {
  113. Err(if self.is_dir() { EISDIR } else { EINVAL })
  114. }
  115. fn read_direct(&self, buffer: &mut dyn Buffer, offset: usize) -> KResult<usize> {
  116. Err(if self.is_dir() { EISDIR } else { EINVAL })
  117. }
  118. fn write(&self, stream: &mut dyn Stream, offset: WriteOffset) -> KResult<usize> {
  119. Err(if self.is_dir() { EISDIR } else { EINVAL })
  120. }
  121. fn write_direct(&self, stream: &mut dyn Stream, offset: usize) -> KResult<usize> {
  122. Err(if self.is_dir() { EISDIR } else { EINVAL })
  123. }
  124. fn devid(&self) -> KResult<DevId> {
  125. Err(if self.is_dir() { EISDIR } else { EINVAL })
  126. }
  127. fn readlink(&self, buffer: &mut dyn Buffer) -> KResult<usize> {
  128. Err(if self.is_dir() { EISDIR } else { EINVAL })
  129. }
  130. fn truncate(&self, length: usize) -> KResult<()> {
  131. Err(if self.is_dir() { EISDIR } else { EPERM })
  132. }
  133. fn rename(&self, rename_data: RenameData) -> KResult<()> {
  134. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  135. }
  136. fn do_readdir(
  137. &self,
  138. offset: usize,
  139. callback: &mut dyn FnMut(&[u8], Ino) -> KResult<ControlFlow<(), ()>>,
  140. ) -> KResult<usize> {
  141. Err(if !self.is_dir() { ENOTDIR } else { EPERM })
  142. }
  143. fn chmod(&self, mode: Mode) -> KResult<()> {
  144. Err(EPERM)
  145. }
  146. fn chown(&self, uid: u32, gid: u32) -> KResult<()> {
  147. Err(EPERM)
  148. }
  149. fn page_cache(&self) -> Option<&PageCache> {
  150. None
  151. }
  152. fn statx(&self, stat: &mut StatX, mask: u32) -> KResult<()> {
  153. // Safety: ffi should have checked reference
  154. let vfs = self.vfs.upgrade().expect("Vfs is dropped");
  155. let size = self.size.load(Ordering::Relaxed);
  156. let mode = self.mode.load();
  157. if mask & STATX_NLINK != 0 {
  158. stat.stx_nlink = self.nlink.load(Ordering::Acquire) as _;
  159. stat.stx_mask |= STATX_NLINK;
  160. }
  161. if mask & STATX_ATIME != 0 {
  162. let atime = *self.atime.lock();
  163. stat.stx_atime = atime.into();
  164. stat.stx_mask |= STATX_ATIME;
  165. }
  166. if mask & STATX_MTIME != 0 {
  167. let mtime = *self.mtime.lock();
  168. stat.stx_mtime = mtime.into();
  169. stat.stx_mask |= STATX_MTIME;
  170. }
  171. if mask & STATX_CTIME != 0 {
  172. let ctime = *self.ctime.lock();
  173. stat.stx_ctime = ctime.into();
  174. stat.stx_mask |= STATX_CTIME;
  175. }
  176. if mask & STATX_SIZE != 0 {
  177. stat.stx_size = self.size.load(Ordering::Relaxed) as _;
  178. stat.stx_mask |= STATX_SIZE;
  179. }
  180. stat.stx_mode = 0;
  181. if mask & STATX_MODE != 0 {
  182. stat.stx_mode |= mode.non_format_bits() as u16;
  183. stat.stx_mask |= STATX_MODE;
  184. }
  185. if mask & STATX_TYPE != 0 {
  186. stat.stx_mode |= mode.format_bits() as u16;
  187. if mode.is_blk() || mode.is_chr() {
  188. let devid = self.devid();
  189. stat.stx_rdev_major = (devid? >> 8) & 0xff;
  190. stat.stx_rdev_minor = devid? & 0xff;
  191. }
  192. stat.stx_mask |= STATX_TYPE;
  193. }
  194. if mask & STATX_INO != 0 {
  195. stat.stx_ino = self.ino as _;
  196. stat.stx_mask |= STATX_INO;
  197. }
  198. if mask & STATX_BLOCKS != 0 {
  199. stat.stx_blocks = (size + 512 - 1) / 512;
  200. stat.stx_blksize = vfs.io_blksize() as _;
  201. stat.stx_mask |= STATX_BLOCKS;
  202. }
  203. if mask & STATX_UID != 0 {
  204. stat.stx_uid = self.uid.load(Ordering::Relaxed) as _;
  205. stat.stx_mask |= STATX_UID;
  206. }
  207. if mask & STATX_GID != 0 {
  208. stat.stx_gid = self.gid.load(Ordering::Relaxed) as _;
  209. stat.stx_mask |= STATX_GID;
  210. }
  211. let fsdev = vfs.fs_devid();
  212. stat.stx_dev_major = (fsdev >> 8) & 0xff;
  213. stat.stx_dev_minor = fsdev & 0xff;
  214. // TODO: support more attributes
  215. stat.stx_attributes_mask = 0;
  216. Ok(())
  217. }
  218. fn new_locked<F>(ino: Ino, vfs: Weak<dyn Vfs>, f: F) -> Arc<Self>
  219. where
  220. Self: Sized,
  221. F: FnOnce(*mut Self, &()),
  222. {
  223. let mut uninit = Arc::<Self>::new_uninit();
  224. let uninit_mut = Arc::get_mut(&mut uninit).unwrap();
  225. // Safety: `idata` is owned by `uninit`
  226. let idata = unsafe {
  227. addr_of_mut!(*(*uninit_mut.as_mut_ptr()).data_mut())
  228. .cast::<MaybeUninit<InodeData>>()
  229. .as_mut()
  230. .unwrap()
  231. };
  232. idata.write(InodeData::new(ino, vfs));
  233. f(
  234. uninit_mut.as_mut_ptr(),
  235. // SAFETY: `idata` is initialized and we will never move the lock.
  236. &block_on(unsafe { idata.assume_init_ref() }.rwsem.read()),
  237. );
  238. // Safety: `uninit` is initialized
  239. unsafe { uninit.assume_init() }
  240. }
  241. }
  242. // TODO: define multiple inode structs a time
  243. macro_rules! define_struct_inode {
  244. ($v:vis struct $inode_t:ident;) => {
  245. $v struct $inode_t {
  246. /// Do not use this directly
  247. idata: $crate::kernel::vfs::inode::InodeData,
  248. }
  249. impl core::ops::Deref for $inode_t {
  250. type Target = $crate::kernel::vfs::inode::InodeData;
  251. fn deref(&self) -> &Self::Target {
  252. &self.idata
  253. }
  254. }
  255. impl core::ops::DerefMut for $inode_t {
  256. fn deref_mut(&mut self) -> &mut Self::Target {
  257. &mut self.idata
  258. }
  259. }
  260. impl $crate::kernel::vfs::inode::InodeInner for $inode_t {
  261. fn data(&self) -> &$crate::kernel::vfs::inode::InodeData {
  262. &self.idata
  263. }
  264. fn data_mut(&mut self) -> &mut $crate::kernel::vfs::inode::InodeData {
  265. &mut self.idata
  266. }
  267. }
  268. };
  269. ($v:vis struct $inode_t:ident { $($vis:vis $name:ident: $type:ty,)* }) => {
  270. $v struct $inode_t {
  271. /// Do not use this directly
  272. idata: $crate::kernel::vfs::inode::InodeData,
  273. $($vis $name: $type,)*
  274. }
  275. impl core::ops::Deref for $inode_t {
  276. type Target = $crate::kernel::vfs::inode::InodeData;
  277. fn deref(&self) -> &Self::Target {
  278. &self.idata
  279. }
  280. }
  281. impl core::ops::DerefMut for $inode_t {
  282. fn deref_mut(&mut self) -> &mut Self::Target {
  283. &mut self.idata
  284. }
  285. }
  286. impl $crate::kernel::vfs::inode::InodeInner for $inode_t {
  287. fn data(&self) -> &$crate::kernel::vfs::inode::InodeData {
  288. &self.idata
  289. }
  290. fn data_mut(&mut self) -> &mut $crate::kernel::vfs::inode::InodeData {
  291. &mut self.idata
  292. }
  293. }
  294. };
  295. }
  296. pub(crate) use define_struct_inode;
  297. impl Mode {
  298. pub const REG: Self = Self(S_IFREG);
  299. pub const DIR: Self = Self(S_IFDIR);
  300. pub const LNK: Self = Self(S_IFLNK);
  301. pub const BLK: Self = Self(S_IFBLK);
  302. pub const CHR: Self = Self(S_IFCHR);
  303. pub const fn new(bits: u32) -> Self {
  304. Self(bits)
  305. }
  306. pub const fn is_blk(&self) -> bool {
  307. (self.0 & S_IFMT) == S_IFBLK
  308. }
  309. pub const fn is_chr(&self) -> bool {
  310. (self.0 & S_IFMT) == S_IFCHR
  311. }
  312. pub const fn is_reg(&self) -> bool {
  313. (self.0 & S_IFMT) == S_IFREG
  314. }
  315. pub const fn is_dir(&self) -> bool {
  316. (self.0 & S_IFMT) == S_IFDIR
  317. }
  318. pub const fn is_lnk(&self) -> bool {
  319. (self.0 & S_IFMT) == S_IFLNK
  320. }
  321. pub const fn bits(&self) -> u32 {
  322. self.0
  323. }
  324. pub const fn format_bits(&self) -> u32 {
  325. self.0 & S_IFMT
  326. }
  327. pub const fn format(&self) -> Self {
  328. Self::new(self.format_bits())
  329. }
  330. pub const fn non_format_bits(&self) -> u32 {
  331. self.0 & !S_IFMT
  332. }
  333. pub const fn non_format(&self) -> Self {
  334. Self::new(self.non_format_bits())
  335. }
  336. pub const fn perm(self, perm: u32) -> Self {
  337. Self::new((self.0 & !0o777) | (perm & 0o777))
  338. }
  339. pub const fn set_perm(&mut self, perm: u32) {
  340. *self = self.perm(perm);
  341. }
  342. pub const fn mask_perm(&mut self, perm_mask: u32) {
  343. let perm_mask = perm_mask & 0o777;
  344. let self_perm = self.non_format_bits() & 0o777;
  345. *self = self.perm(self_perm & perm_mask);
  346. }
  347. }
  348. impl AtomicMode {
  349. pub const fn new(bits: u32) -> Self {
  350. Self(AtomicU32::new(bits))
  351. }
  352. pub const fn from(mode: Mode) -> Self {
  353. Self::new(mode.0)
  354. }
  355. pub fn load(&self) -> Mode {
  356. Mode(self.0.load(Ordering::Relaxed))
  357. }
  358. pub fn store(&self, mode: Mode) {
  359. self.0.store(mode.0, Ordering::Relaxed);
  360. }
  361. }
  362. impl core::fmt::Debug for AtomicMode {
  363. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  364. f.debug_struct("AtomicMode")
  365. .field("bits", &self.load().0)
  366. .finish()
  367. }
  368. }
  369. impl core::fmt::Debug for Mode {
  370. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  371. let format_name = match self.format() {
  372. Mode::REG => "REG",
  373. Mode::DIR => "DIR",
  374. Mode::LNK => "LNK",
  375. Mode::BLK => "BLK",
  376. Mode::CHR => "CHR",
  377. _ => "UNK",
  378. };
  379. match self.non_format_bits() & !0o777 {
  380. 0 => write!(
  381. f,
  382. "Mode({format_name}, {perm:#o})",
  383. perm = self.non_format_bits()
  384. )?,
  385. rem => write!(
  386. f,
  387. "Mode({format_name}, {perm:#o}, rem={rem:#x})",
  388. perm = self.non_format_bits() & 0o777
  389. )?,
  390. }
  391. Ok(())
  392. }
  393. }
  394. impl FromSyscallArg for Mode {
  395. fn from_arg(value: usize) -> Self {
  396. Mode::new(value as u32)
  397. }
  398. }
  399. impl SyscallRetVal for Mode {
  400. fn into_retval(self) -> Option<usize> {
  401. Some(self.bits() as usize)
  402. }
  403. }