f2fs读取磁盘block过程:do_read_inode

本文详细探讨了f2fs文件系统如何通过do_read_inode函数读取磁盘block。从f2fs_iget查找或创建inode,到get_node_page和__get_node_page函数的页缓存操作,再到read_node_page的磁盘读取,最后阐述了f2fs_submit_page_bio在bio请求中的作用,全面解析了f2fs读取磁盘数据的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

f2fs:依据inode的节点号,将inode对应的block读到页缓存
f2fs_iget依据索引节点号,查找对应的inode,若没有,则创建一个新的inode,读取磁盘上的inode所在的block,生成f2f2_inode对象去初始化这个新inode。

其中,当inode不存在时,需要创建新的inode,同时还要从磁盘上读取inode所在的block;
因此,这次主要针对f2fs读取磁盘block过程进行分析,do_read_inode是主要函数。

/* 
	依据节点号ino,获得对应的inode;
	若没有,则创建一个新的inode,读取磁盘上的inode所在的block,生成f2f2_inode对象去初始化这个新inode
*/
struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
{
	struct f2fs_sb_info *sbi = F2FS_SB(sb);
	struct inode *inode;
	int ret = 0;

	//依据索引节点号ino,获得对应的inode;若没有,则创建一个新的inode
	inode = iget_locked(sb, ino);
	if (!inode)
		return ERR_PTR(-ENOMEM);

	/* 该inode不是新inode,直接返回该inode */
	if (!(inode->i_state & I_NEW)) {
		trace_f2fs_iget(inode);
		return inode;
	}

	/* 如果索引节点号是NODE节点或者META节点,调到make_now */
	if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi))
		goto make_now;

	/* 索引节点是DATA节点:依据inode的节点号,将inode对应的block读到页缓存,此时磁盘上的f2fs_node节点就位于页缓存中。
		使用f2fs_node 对inode初始化 */
	ret = do_read_inode(inode);
	if (ret)
		goto bad_inode;
make_now:

	/* 依据ino对应的节点类型或者文件类型,赋予inode不同的操作方法 */
	if (ino == F2FS_NODE_INO(sbi)) {   //ino是NODE节点
		inode->i_mapping->a_ops = &f2fs_node_aops;
		mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
	} else if (ino == F2FS_META_INO(sbi)) {  //ino是META节点
		inode->i_mapping->a_ops = &f2fs_meta_aops;
		mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
	} else if (S_ISREG(inode->i_mode)) {    //inode代表普通文件
		inode->i_op = &f2fs_file_inode_operations;
		inode->i_fop = &f2fs_file_operations;
		inode->i_mapping->a_ops = &f2fs_dblock_aops;
	} else if (S_ISDIR(inode->i_mode)) {   //inode代表目录文件
		inod
<think>我们正在讨论F2FS文件系统中的两个关键结构体:f2fs_inode_info 和 f2fs_inode。 首先,f2fs_inode磁盘上存储的inode结构,它保存在磁盘inode表中,是持久化的数据结构。 而f2fs_inode_info是内存中的结构体,用于表示一个inode在内存中的状态,属于VFS inode的私有数据部分。 关系总结: 1. f2fs_inode_info 是内存中表示F2FS inode的结构,它嵌入在VFS inode的i_private字段中(通过container_of关联)。 2. f2fs_inode磁盘F2FS inode的表示,当从磁盘读取一个inode时,会将磁盘上的f2fs_inode数据读取到内存,并填充到f2fs_inode_info的某些字段中(但并非直接对应,因为内存中需要更多状态信息)。 具体说明: - 磁盘结构:f2fs_inode 定义在f2fs_format.h中,包含了磁盘inode的元数据,如文件大小、块地址、扩展属性等。 例如: struct f2fs_inode { __le16 i_mode; // 文件类型和权限 __u8 i_advise; // 提示信息 ... 其他字段 ... __le32 i_addr[DEF_ADDRS_PER_INODE]; // 直接指针 ... 可能还有间接块指针 ... }; - 内存结构:f2fs_inode_info 定义在f2fs.h中,它包含了VFS inode的私有数据,用于管理该inode在内存中的状态。 例如: struct f2fs_inode_info { struct inode vfs_inode; // 嵌入的VFS inode(注意:实际是作为container_of的容器) ... // 一些内存中的状态 unsigned int i_flags; // 文件标志(如压缩、加密等) unsigned char i_advise; // 从磁盘f2fs_inode读取的advise ... // 用于缓存磁盘inode的某些信息,以及内存中管理的额外信息 struct f2fs_inode *i_addr_array; // 指向磁盘f2fs_inode的指针(在内存中缓存)? // 实际上,磁盘上的f2fs_inode会被读入内存,但内存中f2fs_inode_info并不直接包含整个f2fs_inode,而是包含一些从磁盘上提取出来的信息以及内存管理需要的额外字段。 }; 实际关系: 当需要读取一个inode时,F2FS会通过f2fs_iget()函数(或类似函数)从磁盘读取f2fs_inode结构,然后将其中的信息提取出来,设置到f2fs_inode_info结构体的相应字段中,同时也会设置VFS inode的字段。 注意:内存中的f2fs_inode_info并不直接包含磁盘上的f2fs_inode结构,而是将磁盘上的信息分散存储到内存结构体的各个字段中。例如,磁盘上的i_mode会设置到VFS inode的i_mode字段,而i_advise会设置到f2fs_inode_info的i_advise字段。 另外,f2fs_inode_info还包含了很多磁盘f2fs_inode没有的信息,比如用于缓存的列表、锁、状态标志等,这些都是为了内存管理而设计的。 因此,它们的关系是:f2fs_inode_info是内存中表示一个inode的完整结构,它包含了从磁盘f2fs_inode读取的信息,并添加了内存管理所需的额外信息。 示例代码片段(简化): 在读取inode时(f2fs_iget): - 首先分配一个VFS inode(实际上是包含f2fs_inode_info的结构,因为f2fs_inode_info中嵌入了VFS inode) - 从磁盘读取f2fs_inode结构 - 将f2fs_inode中的信息填充到VFS inodef2fs_inode_info的相应字段 总结:f2fs_inode_info是内存中使用的结构体,而f2fs_inode磁盘上存储的结构体。它们之间是内存表示和磁盘表示的关系,内存结构会从磁盘结构获取信息,但内存结构有更多用于管理的字段。 现在,根据规则,在最后提出3-5个相关问题。</think>`f2fs_inode_info`与`f2fs_inode`是F2FS文件系统中的两个关键结构体,它们的关系如下: ### 核心关系 1. **磁盘 vs 内存** - `f2fs_inode`:**磁盘上的持久化结构** 定义在`f2fs_format.h`中,存储于磁盘inode区域,包含文件元数据(大小、权限、时间戳等)和数据块指针。 ```c struct f2fs_inode { __le16 i_mode; // 文件类型和权限 __u8 i_advise; // F2FS特有标志位 __le32 i_uid; // 用户ID __le32 i_gid; // 组ID __le64 i_size; // 文件大小 __le64 i_blocks; // 占用块数 __le64 i_addr[DEF_ADDRS_PER_INODE]; // 数据块指针数组 // ... 其他元数据字段 }; ``` - `f2fs_inode_info`:**内存中的运行时结构** 定义在`f2fs.h`中,挂载到VFS inode的`i_private`字段,管理inode在内存中的状态。 2. **数据关联** - 当文件被访问时,磁盘上的`f2fs_inode`被读入内存 - `f2fs_inode_info`通过`vfs_inode`关联磁盘数据: ```c struct f2fs_inode_info { struct inode vfs_inode; // 嵌入VFS inode unsigned char i_advise; // 从磁盘inode复制的标志 unsigned int i_flags; // 内存特有状态标志 atomic_t dirty_dents; // 脏目录项计数 // ... 其他运行时状态 }; ``` 3. **功能分工** | 特性 | `f2fs_inode` (磁盘) | `f2fs_inode_info` (内存) | |--------------------|-----------------------------------|----------------------------------| | **存储位置** | 磁盘inode区域 | 内存页缓存 | | **生命周期** | 持久化存储 | 进程访问期间存在 | | **主要作用** | 存储文件元数据和数据块位置 | 管理inode状态和缓存一致性 | | **关键操作** | 读写磁盘 | 处理锁、日志、压缩等运行时逻辑 | | **扩展性** | 固定格式 | 包含动态状态字段(如脏页计数) | ### 工作流程示例 ```mermaid graph LR A[磁盘 f2fs_inode] -->|挂载时读取| B(内存页缓存) B --> C[f2fs_inode_info] C --> D[VFS inode] D -->|文件操作| E[更新f2fs_inode_info状态] E -->|同步时| F[写回磁盘f2fs_inode] ``` ### 关键交互场景 1. **文件读取** - VFS调用`f2fs_read_inode()` - 从磁盘加载`f2fs_inode`到内存页 - 初始化`f2fs_inode_info`并关联VFS inode 2. **数据修改** - 更新`f2fs_inode_info`中的状态标志(如`FI_DIRTY_INODE`) - 通过日志机制(如`f2fs_write_inode()`)将修改写回磁盘的`f2fs_inode` 3. **特性支持** - **压缩**:`f2fs_inode_info`存储压缩块的实际位置 - **加密**:内存结构管理加密上下文 - **原子写**:通过`f2fs_inode_info`跟踪原子操作状态
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值