On Wed, Oct 18, 2023 at 09:24:59AM -0300, Wedson Almeida Filho wrote: > Rust file system modules can be declared with the `module_fs` macro and are > required to implement the following functions (which are part of the > `FileSystem` trait): > > impl FileSystem for MyFS { > fn super_params(sb: &NewSuperBlock<Self>) -> Result<SuperParams<Self::Data>>; > fn init_root(sb: &SuperBlock<Self>) -> Result<ARef<INode<Self>>>; > fn read_dir(inode: &INode<Self>, emitter: &mut DirEmitter) -> Result; > fn lookup(parent: &INode<Self>, name: &[u8]) -> Result<ARef<INode<Self>>>; > fn read_folio(inode: &INode<Self>, folio: LockedFolio<'_>) -> Result; > } Does it make sense to describe filesystem methods like this? As I understand (eg) how inodes are laid out, we typically malloc a foofs_inode { x; y; z; struct inode vfs_inode; }; and then the first line of many functions that take an inode is: struct ext2_inode_info *ei = EXT2_I(dir); That feels like unnecessary boilerplate, and might lead to questions like "What if I'm passed an inode that isn't an ext2 inode". Do we want to always pass in the foofs_inode instead of the inode? Also, I see you're passing an inode to read_dir. Why did you decide to do that? There's information in the struct file that's either necessary or useful to have in the filesystem. Maybe not in toy filesystems, but eg network filesystems need user credentials to do readdir, which are stored in struct file. Block filesystems store readahead data in struct file.