f2fs系列文章fsck(四)
阿新 • • 發佈:2018-12-18
補充一下之前略過的關於direct node、indirect node、dindirect node的檢查。
fsck_chk_didnode_blk,對NIDS_PER_BLOCK個nid進行遍歷,如果nid ==0,就直接跳過,nid!=0的話,就呼叫以TYPE_INDIRECT_NODE的標誌呼叫fsck_chk_node_blk。如果成功就直接將i_block++。否則將該位置的nid置為0。最後如果進行過修復,則將修復過的node寫回。
int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode, enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt, struct child_info *child) { int i = 0; int need_fix = 0, ret = 0; for (i = 0; i < NIDS_PER_BLOCK; i++) { if (le32_to_cpu(node_blk->in.nid[i]) == 0x0) goto skip; ret = fsck_chk_node_blk(sbi, inode, le32_to_cpu(node_blk->in.nid[i]),ftype, TYPE_INDIRECT_NODE, blk_cnt, child); if (!ret) *blk_cnt = *blk_cnt + 1; else if (ret == -EINVAL) { if (!c.fix_on) printf("should delete in.nid[i] = 0;\n"); else { node_blk->in.nid[i] = 0; need_fix = 1; FIX_MSG("Set double indirect node 0x%x -> 0", i); } skip: child->pgofs += ADDRS_PER_BLOCK * NIDS_PER_BLOCK; } } if (need_fix && !c.ro) { struct node_info ni; nid_t nid = le32_to_cpu(node_blk->footer.nid); get_node_info(sbi, nid, &ni); ret = dev_write_block(node_blk, ni.blk_addr); ASSERT(ret >= 0); } return 0; }
fsck_chk_idnode_blk,對NIDS_PER_BLOCK個nid進行遍歷,如果nid ==0,就直接跳過,nid!=0的話,就呼叫以TYPE_DIRECT_NODE的標誌呼叫fsck_chk_node_blk。如果成功就直接將i_block++。否則將該位置的nid置為0。最後如果進行過修復,則將修復過的node寫回。
int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode, enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt, struct child_info *child) { int need_fix = 0, ret; int i = 0; for (i = 0; i < NIDS_PER_BLOCK; i++) { if (le32_to_cpu(node_blk->in.nid[i]) == 0x0) goto skip; ret = fsck_chk_node_blk(sbi, inode, le32_to_cpu(node_blk->in.nid[i]), ftype, TYPE_DIRECT_NODE, blk_cnt, child); if (!ret) *blk_cnt = *blk_cnt + 1; else if (ret == -EINVAL) { if (!c.fix_on) printf("should delete in.nid[i] = 0;\n"); else { node_blk->in.nid[i] = 0; need_fix = 1; FIX_MSG("Set indirect node 0x%x -> 0", i); } skip: child->pgofs += ADDRS_PER_BLOCK; } } if (need_fix && !c.ro) { struct node_info ni; nid_t nid = le32_to_cpu(node_blk->footer.nid); get_node_info(sbi, nid, &ni); ret = dev_write_block(node_blk, ni.blk_addr); ASSERT(ret >= 0); } return 0; }
fsck_chk_idnode_blk,對ADDRS_PER_BLOCK個塊地址進行遍歷,如果addr ==0,就直接跳過,addr!=0的話,就呼叫fsck_chk_data_blk對資料塊進行檢查。如果成功就直接將i_block++。否則將該位置的addr置為0。最後如果進行過修復,則將修復過的node寫回。
int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode, u32 nid, enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt, struct child_info *child, struct node_info *ni) { int idx, ret; int need_fix = 0; child->p_ino = nid; child->pp_ino = le32_to_cpu(inode->i_pino); for (idx = 0; idx < ADDRS_PER_BLOCK; idx++, child->pgofs++) { block_t blkaddr = le32_to_cpu(node_blk->dn.addr[idx]); check_extent_info(child, blkaddr, 0); if (blkaddr == 0x0) continue; ret = fsck_chk_data_blk(sbi, blkaddr, child, le64_to_cpu(inode->i_blocks) == *blk_cnt, ftype, nid, idx, ni->version, file_is_encrypt(inode)); if (!ret) { *blk_cnt = *blk_cnt + 1; } else if (c.fix_on) { node_blk->dn.addr[idx] = 0; need_fix = 1; FIX_MSG("[0x%x] dn.addr[%d] = 0", nid, idx); } } if (need_fix && !c.ro) { ret = dev_write_block(node_blk, ni->blk_addr); ASSERT(ret >= 0); } return 0; }