erofs代码分析:on-disk inode layout
参考staging erofs,on-disk inode layout相关实现是erofs_fs.h + super.c + inode.c。
data mappings
先看文档介绍:
- Metadata & data could be mixed by design;
Different from other read-only file systems, an EROFS volume is designed to be as simple as possible:
|-> aligned with the block size
_____________________________________________________________
| |SB| | ... | Metadata | ... | Data | Metadata | ... | Data |
|_|__|_|_____|__________|_____|______|__________|_____|______|
0 +1K
What is metadata in fs? refer below from wikipedia:
metadata is data information that provides infor about other data.
erofs super block放到了1K偏移处。superblock_read()
:
static int superblock_read(struct super_block *sb) |
All data areas should be aligned with the block size, but metadata areas may not. All metadatas can be now observed in two different spaces (views):
Inode metadata space
Each valid inode should be aligned with an inode slot, which is a fixed value (32 bytes) and designed to be kept in line with v1 inode size.Each inode can be directly found with the following formula:
\ \ \ \ \ inode offset = meta_blkaddr * block_size + 32 * nid
|-> aligned with 8B
|-> followed closely
+ meta_blkaddr blocks |-> another slot
_____________________________________________________________________
| ... | inode | xattrs | extents | data inline | ... | inode ...
|________|_______|(optional)|(optional)|__(optional)_|_____|__________
|-> aligned with the inode slot size
Xattrs, extents, data inline are followed by the corresponding inode with proper alignes, and they could be optional for different data mappings, currently there are totally 3 valid data mappings supported:
1) flat file data without data inline (no extent);
2) fixed-output size data compression (must have extents);
3) flat file data with tail-end data inline (no extent);
三种inode data mapping:
/* |
read super block
erofs_mount() > erofs_fill_super() > erofs_read_super() |
mount时会call erofs_read_super()
:
static int erofs_read_super(struct super_block *sb, |
superblock_read()
就是find super block,super block结构赋值来源mkfs.erofs.
接下来在解析mount选项后会获取root inode给->s_root
:
/* get the root inode */ |
如果root inode不是目录,那就无效了。
get inode
主要看下erofs_iget()
:
struct inode *erofs_iget(struct super_block *sb, |
先是call erofs_iget_locked()
获取,如果没有get到(几率小)就出错了,如果是I_NEW
状态,那就生成一个新inode via fill_inode()
。
64bits及以上平台用iget_locked()
,其他用iget5_locked()
,两个vfs接口,not care now,lets check fill_inode()
:
static int fill_inode(struct inode *inode, int isdir) |
typedef u64 erofs_off_t; |
按inode metadata view来,->meta_blkaddr
是block number? iloc()
负责找到inode address。
接下来会get inode page, mark to check later.
page = erofs_get_meta_page(inode->i_sb, blkaddr, isdir); |
read_inode()
会读data(来自inode page)的->i_advise
走inode v1 or v2。没有错误会check是否是inline data。
static int fill_inline_data(struct inode *inode, void *data, |
fast symlink看条件就是比较小的inode, rt? inline data是for fast symlink? let’s check mkfs.erofs:
int mkfs_relocate_sub_inodes(struct erofs_vnode *inode) |
EROFS_FT_DIR type的貌似也可以吧。
Done.
版权声明:本站所有文章均采用 CC BY-NC-SA 4.0 CN 许可协议。转载请注明原文链接!