xfs_repair流程分析(一)

公众号:
xfs_repair流程分析(一)_第1张图片
整体流程请看:xfs_repair在做什么 https://blog.csdn.net/Angel_94/article/details/88200369
源码:xfsprogs-4.19.0

本文分析xfs_repair流程第一步

步骤1、获取并检查超块信息

如果没有找到超块数据,就结束
入口:

/* ARGSUSED */
void
phase1(xfs_mount_t *mp)
{
	xfs_sb_t		*sb;
	char			*ag_bp;
	int			rval;

	do_log(_("Phase 1 - find and verify superblock...\n"));

	primary_sb_modified = 0;
	need_root_inode = 0;
	need_root_dotdot = 0;
	need_rbmino = 0;
	need_rsumino = 0;
	lost_quotas = 0;

	/*
	 * get AG 0 into ag header buf
	 */
	ag_bp = alloc_ag_buf(MAX_SECTSIZE);
	sb = (xfs_sb_t *) ag_bp;

	rval = get_sb(sb, 0LL, MAX_SECTSIZE, 0);/*获取第一个超级块*/
	if (rval == XR_EOF)
		do_error(_("error reading primary superblock\n"));

	/*
	 * is this really an sb, verify internal consistency
	 */
	if (rval != XR_OK)  {
		do_warn(_("bad primary superblock - %s !!!\n"),
			err_string(rval));
		if (!find_secondary_sb(sb))/*尝试从备用的几个超级块中寻找可用的超级块*/
			no_sb();
		primary_sb_modified = 1;/*主超级块数据需要修正*/
	} else if ((rval = verify_set_primary_sb(sb, 0,
					&primary_sb_modified)) != XR_OK)  {/*核对主超级块信息,与第二个备用超级块进行对比*/
		do_warn(_("couldn't verify primary superblock - %s !!!\n"),
			err_string(rval));
		if (!find_secondary_sb(sb))/*尝试从备用的几个超级块中寻找可用的超级块*/
			no_sb();
		primary_sb_modified = 1;
	}

	/*
	 * Check bad_features2 and make sure features2 the same as
	 * bad_features (ORing the two together). Leave bad_features2
	 * set so older kernels can still use it and not mount unsupported
	 * filesystems when it reads bad_features2.
	 */
	if (sb->sb_bad_features2 != 0 &&
			sb->sb_bad_features2 != sb->sb_features2) {
		sb->sb_features2 |= sb->sb_bad_features2;
		sb->sb_bad_features2 = sb->sb_features2;
		primary_sb_modified = 1;
		do_warn(_("superblock has a features2 mismatch, correcting\n"));
	}

	/*
	 * apply any version changes or conversions after the primary
	 * superblock has been verified or repaired
	 *
	 * Send output to stdout as do_log and everything else in repair
	 * is sent to stderr and there is no "quiet" option. xfs_admin
	 * will filter stderr but not stdout. This situation must be improved.
	 */
	 /*
	 懒惰计数模式
	 若super block中的XFS_SB_VERSION2_LAZYSBCOUNTBIT标记被置位,则仅在umount或shutdown更新disk对应内容。
	 */
	if (convert_lazy_count) {
		if (lazy_count && !xfs_sb_version_haslazysbcount(sb)) {
			sb->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
			sb->sb_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT;
			sb->sb_bad_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT;
			primary_sb_modified = 1;
			printf(_("Enabling lazy-counters\n"));
		} else if (!lazy_count && xfs_sb_version_haslazysbcount(sb)) {
			if (XFS_SB_VERSION_NUM(sb) == XFS_SB_VERSION_5) {
				printf(
_("Cannot disable lazy-counters on V5 fs\n"));
				exit(1);
			}
			sb->sb_features2 &= ~XFS_SB_VERSION2_LAZYSBCOUNTBIT;
			sb->sb_bad_features2 &= ~XFS_SB_VERSION2_LAZYSBCOUNTBIT;
			printf(_("Disabling lazy-counters\n"));
			primary_sb_modified = 1;
		} else {
			printf(_("Lazy-counters are already %s\n"),
				lazy_count ? _("enabled") : _("disabled"));
			exit(0); /* no conversion required, exit */
		}
	}

	/* shared_vn should be zero */
	/* xfs共享版本号(共享只读系统)*/
	if (sb->sb_shared_vn) {
		do_warn(_("resetting shared_vn to zero\n"));
		sb->sb_shared_vn = 0;
		primary_sb_modified = 1;
	}

	if (primary_sb_modified)  {
		if (!no_modify)  {
			do_warn(_("writing modified primary superblock\n"));
			write_primary_sb(sb, sb->sb_sectsize);/*写入首个超级块*/
		} else  {
			do_warn(_("would write modified primary superblock\n"));
		}
	}

	/*
	 * misc. global var initialization
	 */
	sb_ifree = sb_icount = sb_fdblocks = sb_frextents = 0;

	free(sb);
}

步骤1-2中间的操作

步骤1结束后,并不知直接进入步骤2,需要进行一些处理逻辑

步骤1修复了首个超级块后,主流程会再次获取超级块信息,get_sb(&psb, 0, XFS_MAX_SECTORSIZE, 0);,然后libxfs_mount(&xfs_m, &psb, x.ddev, x.logdev, x.rtdev, 0);,挂载到内存mp中。后续的操作需要通过mp指针去进行操作。

然后进行一些变量的计算,内存的申请动作,为后边的步骤做准备。

你可能感兴趣的:(XFS)