erofs in-tree 驱动 in-tree 的代码也是模块的形式,以 module_init
开始
1 2 3 4 5 6 7 8 9 10 11 12 13 14 module_init(erofs_module_init); module_exit(erofs_module_exit); err = register_filesystem(&erofs_fs_type); static struct file_system_type erofs_fs_type = { .owner = THIS_MODULE, .name = "erofs" , .init_fs_context = erofs_init_fs_context, .kill_sb = erofs_kill_sb, .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP, }; MODULE_ALIAS_FS("erofs" );
Kconfig
中包含的一些选项:
EROFS_FS_DEBUG
DEBUG支持EROFS_FS_XATTR
拓展属性支持EROFS_FS_POSIX_ACL
ACL支持EROFS_FS_SECURITY
安全标签支持EROFS_FS_ZIP
压缩支持,默认只支持读取 LZ4 压缩的数据EROFS_FS_ZIP_LZMA
支持读取 microLZMA 压缩的数据EROFS_FS_ZIP_DEFLATE
支持读取 DEFLATE 压缩的数据EROFS_FS_PCPU_KTHREAD
用per-cpu的线程池去作异步数据解压缩EROFS_FS_PCPU_KTHREAD_HIPRI
把这些线程设为高优先级EROFS_FS_ONDEMAND
利用 fscache 实现 on-demand 读初始化流程 1 2 3 4 5 6 static const struct fs_context_operations erofs_context_ops = { .parse_param = erofs_fc_parse_param, .get_tree = erofs_fc_get_tree, .reconfigure = erofs_fc_reconfigure, .free = erofs_fc_free, };
内核的 fs_context
结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 struct fs_context { const struct fs_context_operations *ops ; struct file_system_type *fs_type ; void *fs_private; struct dentry *root ; struct user_namespace *user_ns ; struct net *net_ns ; const struct cred *cred ; char *source; char *subtype; void *security; void *s_fs_info; unsigned int sb_flags; unsigned int sb_flags_mask; unsigned int s_iflags; enum fs_context_purpose purpose :8 ; ... };
EROFS 的元数据 erofs_sb_info
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 struct erofs_sb_info { struct erofs_mount_opts opt ; #ifdef CONFIG_EROFS_FS_ZIP struct list_head list ; struct mutex umount_mutex ; struct xarray managed_pslots ; unsigned int shrinker_run_no; u16 available_compr_algs; struct inode *managed_cache ; struct erofs_sb_lz4_info lz4 ; #endif struct inode *packed_inode ; struct erofs_dev_context *devs ; struct dax_device *dax_dev ; u64 dax_part_off; u64 total_blocks; u32 primarydevice_blocks; u32 meta_blkaddr; #ifdef CONFIG_EROFS_FS_XATTR u32 xattr_blkaddr; u32 xattr_prefix_start; u8 xattr_prefix_count; struct erofs_xattr_prefix_item *xattr_prefixes ; unsigned int xattr_filter_reserved; #endif u16 device_id_mask; unsigned char islotbits; unsigned char blkszbits; u32 sb_size; u32 build_time_nsec; u64 build_time; erofs_nid_t root_nid; erofs_nid_t packed_nid; u64 inos; u8 uuid[16 ]; u8 volume_name[16 ]; u32 feature_compat; u32 feature_incompat; struct kobject s_kobj ; struct completion s_kobj_unregister ; struct fscache_volume *volume ; struct erofs_fscache *s_fscache ; struct erofs_domain *domain ; char *fsid; char *domain_id; };
bdev.c
中负责硬盘块操作
申请super_block
erofs_fc_fill_super
其实是从硬盘上读取数据,初始化user的sb信息
inode 操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const struct inode_operations erofs_generic_iops = { .getattr = erofs_getattr, .listxattr = erofs_listxattr, .get_inode_acl = erofs_get_acl, .fiemap = erofs_fiemap, }; const struct inode_operations erofs_symlink_iops = { .get_link = page_get_link, .getattr = erofs_getattr, .listxattr = erofs_listxattr, .get_inode_acl = erofs_get_acl, }; const struct inode_operations erofs_fast_symlink_iops = { .get_link = simple_get_link, .getattr = erofs_getattr, .listxattr = erofs_listxattr, .get_inode_acl = erofs_get_acl, };
erofs-utils mkfs.erofs
创建一个 erofs 文件系统;fsck.erofs
检查 erofs 镜像的完整性;dump.erofs
导出 erofs 镜像中的相关细节;erofsfuse
用户态mkfs fsck dump erofsfuse