f2fs系列文章fsck(三)

本文详细探讨了f2fs文件系统在fsck检查过程中的各项操作,包括处理硬链接、内联属性、不同类型的文件数据检查等。通过检查inode及其数据块,确保文件系统的完整性和一致性。
摘要由CSDN通过智能技术生成

    fsck_chk_inode_blk接下来就是对一个文件进行处理了,内容比较丰富。首先对inode对应的地址在f2fs_fsck的main_area_bitmap中有没有置位,如果没有置位,也就是检查到了一个新的inode,将f2fs_fsck中的check_result的valid_inode_cnt++,这里需要检查的原因是,可能有硬链接这些在之前就已经将main_area_bitmap相应的位置位了。

if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0)
		fsck->chk.valid_inode_cnt++;

    接下来处理文件的硬链接问题。由于目录是没有硬链接的,所以检查该inode对应的文件类型时候不是目录F2FS_FT_DIR,如果是目录就直接将main_area_bitmap中相应的位置位,然后跳过硬链接的处理。如果不是目录就需要检查该inode所在的block地址在main_area_bitmap中有没有置位过,如果没有置位,那就是第一次检查这个inode,检查其i_links是否大于1,也就是这个inode存不存在其他的硬链接,满足就先通过函数add_into_hard_link_list其加入到f2fs_fsck管理的一个硬链接链表hard_link_list_head中。如果i_link不大于1,那就说明不存在硬链接,不用管了。如果置位过,那就说明,这是之前检查的inode的硬链接了。通过函数find_and_dec_hard_link_list在f2fs_fsck管理的一个硬链接链表hard_link_list_head中找到该inode对应的链表node,然后减少链表node中的链接数,当这个链接数达到1时,说明这个inode所有链接的地方全部处理完了,从链表里面删掉。但是如果出现意外,没有在硬链接的链表中找到对应的链表node,那就说明,实际的硬链接数超过了inode字段中的i_links,这个时候如果要修复那就需要将inode中的i_links++。所以正常情况下,这个链表在所有的inode检查完成之后是NULL,如果不为NULL,那就说明该链表node对应的inode的i_links字段多了,而其实际的链接数就记录在链表node的actual_links字段中,这个会在f2fs_verify中处理。

if (ftype == F2FS_FT_DIR) {
		f2fs_set_main_bitmap(sbi, ni->blk_addr, CURSEG_HOT_NODE);
} else {
	if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
		f2fs_set_main_bitmap(sbi, ni->blk_addr, CURSEG_WARM_NODE);
		if (i_links > 1 && ftype != F2FS_FT_ORPHAN && !is_qf_ino(F2FS_RAW_SUPER(sbi), nid)) {
			add_into_hard_link_list(sbi, nid, i_links);
			fsck->chk.multi_hard_link_files++;
		}
	} else {
		DBG(3, "[0x%x] has hard links [0x%x]\n", nid, i_links);
		if (find_and_dec_hard_link_list(sbi, nid)) {
			ASSERT_MSG("[0x%x] needs more i_links=0x%x", nid, i_links);
			if (c.fix_on) {
				node_blk->i.i_links = cpu_to_le32(i_links + 1);
					need_fix = 1;
					FIX_MSG("File: 0x%x " "i_links= 0x%x -> 0x%x", nid, i_links, i_links + 1);
			}
			goto skip_blkcnt_fix;
		}
		return;
	}
}

    接下来是内联属性的问题,这个通过函数fsck_chk_xattr_blk完成。fsck_chk_xattr_blk首先检查i_xattr_nid字段==0看一下存不存在内联属性块,如果没有直接返回。如果i_xattr_nid!=0,那就说明存在内联属性的node。存在内联属性的node之后,先调用sanity_check_nid对nid进行基本的检查,然后需要将inode的i_blocks++;并将内联node所在的block地址在f2fs_fsck的main_area_bitmap置位。如果检查过程中出错的话,这时其nid在f2fs_fsck的nat_area_bitmap是没有clear的,这个留着f2fs_verify处理,这时在inode对应的i_xattr_nid赋值0,表示丢掉这个内联的node。

if (fsck_chk_xattr_blk(sbi, nid, le32_to_cpu(node_blk->i.i_xattr_nid), blk_cnt) && c.fix_on) {
	node_blk->i.i_xattr_nid = 0;
	need_fix = 1;
	FIX_MSG("Remove xattr block: 0x%x, x_nid = 0x%x", nid, le32_to_cpu(node_blk->i.i_xattr_nid));
}
static int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino, u32 x_nid, u32 *blk_cnt)
{
	struct f2fs_node *node_blk = NULL;
	struct node_info ni;
	int ret = 0;
	if (x_nid == 0x0)
		return 0;

	node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
	ASSERT(node_blk != NULL);
	if (sanity_check_nid(sbi, x_nid, node_blk, F2FS_FT_XATTR, TYPE_XATTR, &ni)) {
		ret = -EINVAL;
		goto out;
	}
	*blk_cnt = *blk_cnt + 1;
	f2fs_set_main_bitmap(sbi, ni.blk_addr, CURSEG_COLD_NODE);
	DBG(2, "ino[0x%x] x_nid[0x%x]\n", ino, x_nid);
out:
	free(node_blk);
	return ret;
}

    如果文件类型是F2FS_FT_CHRDEV、F2FS_FT_BLKDEV、F2FS_FT_FIFO、F2FS_FT_SOCK直接跨过数据的检查。

if (ftype == F2FS_FT_CHRDEV || ftype == F2FS_FT_BLKDEV || ftype == F2FS_FT_FIFO || ftype == F2FS_FT_SOCK)
	goto check;

    接下来是处理inode下的数据的问题了,数据的检查分为下面的三种情况:

       第一种情况是内联数据F2FS_INLINE_DATA。首先检查i_addr的起始地址应该是0,不是就进行修复。另外就是如果没有设置F2FS_DATA_EXIST,但是在f2fs_in

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值