公众号:
整体流程请看:xfs_repair在做什么 https://blog.csdn.net/Angel_94/article/details/88200369
源码:xfsprogs-4.19.0
本文分析xfs_repair流程第二步
步骤2、检查AG头结构信息
检查AG头结构信息(AGI,AGF和AGFL)并扫描AGF和AGI btree。
入口
/*
* ok, at this point, the fs is mounted but the root inode may be
* trashed and the ag headers haven't been checked. So we have
* a valid xfs_mount_t and superblock but that's about it. That
* means we can use macros that use mount/sb fields in calculations
* but I/O or btree routines that depend on space maps or inode maps
* being correct are verboten.
*/
void
phase2(
struct xfs_mount *mp,
int scan_threads)
{
int j;
ino_tree_node_t *ino_rec;
/* now we can start using the buffer cache routines */
set_mp(mp);/*将磁盘上未完成的cache下刷到磁盘*/
/* Check whether this fs has internal or external log */
/* starting block of log if internal 日志区域的开始块号,检查是否有外部日志信息*/
if (mp->m_sb.sb_logstart == 0) {
if (!x.logname)
do_error(_("This filesystem has an external log. "
"Specify log device with the -l option.\n"));
do_log(_("Phase 2 - using external log on %s\n"), x.logname);
} else
do_log(_("Phase 2 - using internal log\n"));
/* Zero log if applicable */
do_log(_(" - zero log...\n"));
zero_log(mp);/*清空日志数据*/
do_log(_(" - scan filesystem freespace and inode maps...\n"));
bad_ino_btree = 0;
set_progress_msg(PROG_FMT_SCAN_AG, (uint64_t) glob_agcount);
/* scan ags ,扫描AGS,多线程并行*/
/*修复每个AG上的超级块信息,AGI,AGF*/
scan_ags(mp, scan_threads);
print_final_rpt();
/*
* make sure we know about the root inode chunk
*/
if ((ino_rec = find_inode_rec(mp, 0, mp->m_sb.sb_rootino)) == NULL) {
ASSERT(mp->m_sb.sb_rbmino == mp->m_sb.sb_rootino + 1 &&
mp->m_sb.sb_rsumino == mp->m_sb.sb_rootino + 2);
do_warn(_("root inode chunk not found\n"));
/*
* mark the first 3 used, the rest are free
*/
ino_rec = set_inode_used_alloc(mp, 0,
(xfs_agino_t) mp->m_sb.sb_rootino);
set_inode_used(ino_rec, 1);
set_inode_used(ino_rec, 2);
for (j = 3; j < XFS_INODES_PER_CHUNK; j++)
set_inode_free(ino_rec, j);
/*
* also mark blocks
*/
set_bmap_ext(0, XFS_INO_TO_AGBNO(mp, mp->m_sb.sb_rootino),
mp->m_ialloc_blks, XR_E_INO);
} else {
do_log(_(" - found root inode chunk\n"));
/*
* blocks are marked, just make sure they're in use
*/
if (is_inode_free(ino_rec, 0)) {
do_warn(_("root inode marked free, "));
set_inode_used(ino_rec, 0);
if (!no_modify)
do_warn(_("correcting\n"));
else
do_warn(_("would correct\n"));
}
if (is_inode_free(ino_rec, 1)) {
do_warn(_("realtime bitmap inode marked free, "));
set_inode_used(ino_rec, 1);
if (!no_modify)
do_warn(_("correcting\n"));
else
do_warn(_("would correct\n"));
}
if (is_inode_free(ino_rec, 2)) {
do_warn(_("realtime summary inode marked free, "));
set_inode_used(ino_rec, 2);
if (!no_modify)
do_warn(_("correcting\n"));
else
do_warn(_("would correct\n"));
}
}
}