inode.rs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. use alloc::boxed::Box;
  2. use alloc::collections::btree_map::BTreeMap;
  3. use alloc::sync::{Arc, Weak};
  4. use core::any::Any;
  5. use core::future::Future;
  6. use core::ops::Deref;
  7. use async_trait::async_trait;
  8. use eonix_sync::{RwLock, Spin};
  9. use super::{Ino, RenameData, WriteOffset};
  10. use crate::io::{Buffer, Stream};
  11. use crate::kernel::constants::{EINVAL, EPERM};
  12. use crate::kernel::mem::{CachePage, PageCache, PageOffset};
  13. use crate::kernel::timer::Instant;
  14. use crate::kernel::vfs::dentry::Dentry;
  15. use crate::kernel::vfs::types::{DeviceId, Format, Mode, Permission};
  16. use crate::kernel::vfs::{SbRef, SbUse, SuperBlock};
  17. use crate::prelude::KResult;
  18. pub struct Inode {
  19. pub ino: Ino,
  20. pub format: Format,
  21. pub info: Spin<InodeInfo>,
  22. pub rwsem: RwLock<()>,
  23. page_cache: Spin<Weak<PageCache>>,
  24. sb: SbRef<dyn SuperBlock>,
  25. ops: Box<dyn InodeOpsErased>,
  26. }
  27. macro_rules! return_type {
  28. ($type:ty) => {
  29. $type
  30. };
  31. () => {
  32. ()
  33. };
  34. }
  35. macro_rules! define_inode_ops {
  36. {
  37. $(
  38. $(#[$attr:meta])*
  39. async fn $method:ident $(<$($lt:lifetime),+>)? (&self $(,)? $($name:ident : $type:ty $(,)?)*) $(-> $ret:ty)?
  40. $body:block
  41. )*
  42. ---
  43. $(
  44. $(#[$attr1:meta])*
  45. fn $method1:ident $(<$($lt1:lifetime),+>)? (&self $(,)? $($name1:ident : $type1:ty $(,)?)*) $(-> $ret1:ty)?
  46. $body1:block
  47. )*
  48. } => {
  49. #[allow(unused_variables)]
  50. pub trait InodeOps: Sized + Send + Sync + 'static {
  51. type SuperBlock: SuperBlock + Sized;
  52. $(
  53. $(#[$attr])*
  54. fn $method $(<$($lt),+>)? (
  55. &self,
  56. sb: SbUse<Self::SuperBlock>,
  57. inode: &InodeUse,
  58. $($name : $type),*
  59. ) -> impl Future<Output = return_type!($($ret)?)> + Send {
  60. async { $body }
  61. })*
  62. $(
  63. $(#[$attr1])*
  64. fn $method1 $(<$($lt1),+>)? (
  65. &self,
  66. sb: SbUse<Self::SuperBlock>,
  67. inode: &InodeUse,
  68. $($name1 : $type1),*
  69. ) -> return_type!($($ret1)?) {
  70. $body1
  71. })*
  72. }
  73. #[async_trait]
  74. trait InodeOpsErased: Any + Send + Sync + 'static {
  75. $(async fn $method $(<$($lt),+>)? (
  76. &self,
  77. sb: SbUse<dyn SuperBlock>,
  78. inode: &InodeUse,
  79. $($name : $type),*
  80. ) -> return_type!($($ret)?);)*
  81. $(fn $method1 $(<$($lt1),+>)? (
  82. &self,
  83. sb: SbUse<dyn SuperBlock>,
  84. inode: &InodeUse,
  85. $($name1 : $type1),*
  86. ) -> return_type!($($ret1)?);)*
  87. }
  88. #[async_trait]
  89. impl<T> InodeOpsErased for T
  90. where
  91. T: InodeOps,
  92. {
  93. $(async fn $method $(<$($lt),+>)? (
  94. &self,
  95. sb: SbUse<dyn SuperBlock>,
  96. inode: &InodeUse,
  97. $($name : $type),*
  98. ) -> return_type!($($ret)?) {
  99. self.$method(sb.downcast(), inode, $($name),*).await
  100. })*
  101. $(fn $method1 $(<$($lt1),+>)? (
  102. &self,
  103. sb: SbUse<dyn SuperBlock>,
  104. inode: &InodeUse,
  105. $($name1 : $type1),*
  106. ) -> return_type!($($ret1)?) {
  107. self.$method1(sb.downcast(), inode, $($name1),*)
  108. })*
  109. }
  110. impl InodeUse {
  111. $(pub async fn $method $(<$($lt),+>)? (
  112. &self,
  113. $($name : $type),*
  114. ) -> return_type!($($ret)?) {
  115. self.ops.$method(self.sbget()?, self, $($name),*).await
  116. })*
  117. $(pub fn $method1 $(<$($lt1),+>)? (
  118. &self,
  119. $($name1 : $type1),*
  120. ) -> return_type!($($ret1)?) {
  121. self.ops.$method1(self.sbget()?, self, $($name1),*)
  122. })*
  123. }
  124. };
  125. }
  126. define_inode_ops! {
  127. // DIRECTORY OPERATIONS
  128. async fn lookup(&self, dentry: &Arc<Dentry>) -> KResult<Option<InodeUse>> {
  129. Err(EPERM)
  130. }
  131. /// Read directory entries and call the given closure for each entry.
  132. ///
  133. /// # Returns
  134. /// - Ok(count): The number of entries read.
  135. /// - Ok(Err(err)): Some error occurred while calling the given closure.
  136. /// - Err(err): An error occurred while reading the directory.
  137. async fn readdir(
  138. &self,
  139. offset: usize,
  140. for_each_entry: &mut (dyn (for<'a> FnMut(&'a [u8], Ino) -> KResult<bool>) + Send),
  141. ) -> KResult<KResult<usize>> {
  142. Err(EPERM)
  143. }
  144. async fn create(&self, at: &Arc<Dentry>, mode: Permission) -> KResult<()> {
  145. Err(EPERM)
  146. }
  147. async fn mkdir(&self, at: &Dentry, mode: Permission) -> KResult<()> {
  148. Err(EPERM)
  149. }
  150. async fn mknod(&self, at: &Dentry, mode: Mode, dev: DeviceId) -> KResult<()> {
  151. Err(EPERM)
  152. }
  153. async fn unlink(&self, at: &Arc<Dentry>) -> KResult<()> {
  154. Err(EPERM)
  155. }
  156. async fn symlink(&self, at: &Arc<Dentry>, target: &[u8]) -> KResult<()> {
  157. Err(EPERM)
  158. }
  159. async fn rename(&self, rename_data: RenameData<'_, '_>) -> KResult<()> {
  160. Err(EPERM)
  161. }
  162. // FILE OPERATIONS
  163. async fn read(&self, buffer: &mut dyn Buffer, offset: usize) -> KResult<usize> {
  164. Err(EINVAL)
  165. }
  166. async fn read_direct(&self, buffer: &mut dyn Buffer, offset: usize) -> KResult<usize> {
  167. Err(EINVAL)
  168. }
  169. async fn write(
  170. &self,
  171. stream: &mut dyn Stream,
  172. offset: WriteOffset<'_>
  173. ) -> KResult<usize> {
  174. Err(EINVAL)
  175. }
  176. async fn write_direct(
  177. &self,
  178. stream: &mut dyn Stream,
  179. offset: usize,
  180. ) -> KResult<usize> {
  181. Err(EINVAL)
  182. }
  183. async fn readlink(&self, buffer: &mut dyn Buffer) -> KResult<usize> {
  184. Err(EINVAL)
  185. }
  186. async fn truncate(&self, length: usize) -> KResult<()> {
  187. Err(EPERM)
  188. }
  189. async fn chmod(&self, perm: Permission) -> KResult<()> {
  190. Err(EPERM)
  191. }
  192. async fn chown(&self, uid: u32, gid: u32) -> KResult<()> {
  193. Err(EPERM)
  194. }
  195. // PAGE CACHE OPERATIONS
  196. async fn read_page(&self, page: &mut CachePage, offset: PageOffset) -> KResult<()> {
  197. Err(EINVAL)
  198. }
  199. async fn write_page(&self, page: &mut CachePage, offset: PageOffset) -> KResult<()> {
  200. Err(EINVAL)
  201. }
  202. async fn write_begin<'a>(
  203. &self,
  204. page_cache: &PageCache,
  205. pages: &'a mut BTreeMap<PageOffset, CachePage>,
  206. offset: usize,
  207. len: usize,
  208. ) -> KResult<&'a mut CachePage> {
  209. Err(EINVAL)
  210. }
  211. async fn write_end(
  212. &self,
  213. page_cache: &PageCache,
  214. pages: &mut BTreeMap<PageOffset, CachePage>,
  215. offset: usize,
  216. len: usize,
  217. copied: usize
  218. ) -> KResult<()> {
  219. Err(EINVAL)
  220. }
  221. ---
  222. fn devid(&self) -> KResult<DeviceId> {
  223. Err(EINVAL)
  224. }
  225. }
  226. #[derive(Debug, Clone)]
  227. pub struct InodeInfo {
  228. pub size: u64,
  229. pub nlink: u64,
  230. pub uid: u32,
  231. pub gid: u32,
  232. pub perm: Permission,
  233. pub atime: Instant,
  234. pub ctime: Instant,
  235. pub mtime: Instant,
  236. }
  237. #[repr(transparent)]
  238. pub struct InodeUse(Arc<Inode>);
  239. impl InodeUse {
  240. pub fn new(
  241. sb: SbRef<dyn SuperBlock>,
  242. ino: Ino,
  243. format: Format,
  244. info: InodeInfo,
  245. ops: impl InodeOps,
  246. ) -> Self {
  247. let inode = Inode {
  248. sb,
  249. ino,
  250. format,
  251. info: Spin::new(info),
  252. rwsem: RwLock::new(()),
  253. page_cache: Spin::new(Weak::new()),
  254. ops: Box::new(ops),
  255. };
  256. Self(Arc::new(inode))
  257. }
  258. pub fn sbref(&self) -> SbRef<dyn SuperBlock> {
  259. self.sb.clone()
  260. }
  261. pub fn sbget(&self) -> KResult<SbUse<dyn SuperBlock>> {
  262. self.sb.get().map(|sb| sb as _)
  263. }
  264. pub fn get_priv<I>(&self) -> &I
  265. where
  266. I: InodeOps,
  267. {
  268. let ops = (&*self.ops) as &dyn Any;
  269. ops.downcast_ref()
  270. .expect("InodeUse::private: InodeOps type mismatch")
  271. }
  272. pub fn get_page_cache(&self) -> Arc<PageCache> {
  273. if let Some(cache) = self.page_cache.lock().upgrade() {
  274. return cache;
  275. }
  276. // Slow path...
  277. let cache = Arc::new(PageCache::new(self.clone()));
  278. let mut page_cache = self.page_cache.lock();
  279. if let Some(cache) = page_cache.upgrade() {
  280. return cache;
  281. }
  282. *page_cache = Arc::downgrade(&cache);
  283. cache
  284. }
  285. }
  286. impl Clone for InodeUse {
  287. fn clone(&self) -> Self {
  288. Self(self.0.clone())
  289. }
  290. }
  291. impl core::fmt::Debug for InodeUse {
  292. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  293. write!(f, "InodeUse(ino={})", self.ino)
  294. }
  295. }
  296. impl Deref for InodeUse {
  297. type Target = Inode;
  298. fn deref(&self) -> &Self::Target {
  299. self.0.deref()
  300. }
  301. }
  302. impl PartialEq for InodeUse {
  303. fn eq(&self, other: &Self) -> bool {
  304. Arc::ptr_eq(&self.0, &other.0)
  305. }
  306. }