0544ab88创建于 2025年12月4日历史提交
/**

 * fsck_debug.c

 *

 * Copyright (C) 2024 Huawei Ltd.

 *

 * This program is free software; you can redistribute it and/or modify

 * it under the terms of the GNU General Public License version 2 as

 * published by the Free Software Foundation.

 */

#include "fsck_debug.h"



void dump_sbi_info(struct f2fs_sb_info *sbi)

{

	if (sbi == NULL) {

		MSG(0, "sbi is null\n");

		return;

	}



	MSG(0, "\n");

	MSG(0, "+--------------------------------------------------------+\n");

	MSG(0, "| SBI                                                    |\n");

	MSG(0, "+--------------------------------------------------------+\n");

	MSG(0, "total_count %u\n", total_segments(sbi));

	MSG(0, "resvd_segs %u\n", reserved_segments(sbi));

	MSG(0, "overp_segs %u\n", overprov_segments(sbi));

	MSG(0, "valid_count %u\n", of_valid_block_count(sbi));

	MSG(0, "utilization %u\n", f2fs_utilization(sbi));

	MSG(0, "\n");

	hex_info_dump("f2fs_sb_info", sbi,

		sizeof(struct f2fs_sb_info));

	MSG(0, "\n");

}



#define LINE_MAX_LEN     80

#define LINE_MAX_INTS    16

#define BATCH_INTS       8

#define HEX_SHIFT_12     12

#define HEX_SHIFT_8      8

#define HEX_SHIFT_4      4

#define HEX_MASK         0x0F

#define U32_PER_SEG      64

void hex_info_dump(const char *prompts, const unsigned char *buf,

			unsigned int len)

{

	static const unsigned char hex_ascii[] = "0123456789abcdef";

	unsigned char line[LINE_MAX_LEN];

	unsigned int i, j, k, line_len;

	unsigned int rest = len;



	MSG(0, "===HEX DUMP START: %.25s, len %u===\n",

		prompts, len);

	for (i = 0; i < len; i += LINE_MAX_INTS) {

		line_len = rest > LINE_MAX_INTS ? LINE_MAX_INTS : rest;

		k = 0;

		line[k++] = hex_ascii[(i >> HEX_SHIFT_12) & HEX_MASK];

		line[k++] = hex_ascii[(i >> HEX_SHIFT_8) & HEX_MASK];

		line[k++] = hex_ascii[(i >> HEX_SHIFT_4) & HEX_MASK];

		line[k++] = hex_ascii[i & HEX_MASK];

		line[k++] = ':';

		for (j = 0; j < line_len; j++) {

			j % BATCH_INTS == 0 ? line[k++] = ' ' : 1;

			line[k++] = hex_ascii[(buf[i + j] >> HEX_SHIFT_4) & HEX_MASK];

			line[k++] = hex_ascii[(buf[i + j] & HEX_MASK)];

		}

		line[k++] = '\0';

		rest -= line_len;

		MSG(0, "%s\n", line);

	}

	MSG(0, "===HEX DUMP END===\n");

}



static void dump_one_segment(const char *bitmap, unsigned int segno)

{

	for (u32 i = 0; i < U32_PER_SEG; i++) {

		MSG(0, " %02x", *(bitmap + i + segno * U32_PER_SEG));



		if ((i + 1) % LINE_MAX_INTS == 0) {

			MSG(0, "\n");

		}

	}

}



static bool has_diff_segment(const char *sit_area_bitmap, const char *main_area_bitmap, unsigned int segno)

{

	for (u32 i = 0; i < U32_PER_SEG; i++) {

		if (*(main_area_bitmap + i + segno * U32_PER_SEG) != *(sit_area_bitmap + i + segno * U32_PER_SEG)) {

			return true;

		}

	}

	return false;

}



void dump_bitmap_diff(struct f2fs_sb_info *sbi, const char *sit_area_bitmap, const char *main_area_bitmap)

{

	struct seg_entry *se;

	unsigned int segno;

	int i;

	u32 main_segments = SM_I(sbi)->main_segments;



	if (sit_area_bitmap == NULL || main_area_bitmap == NULL) {

		return;

	}



	for (segno = 0; segno < main_segments; segno++) {

		se = get_seg_entry(sbi, segno);

		if (se->valid_blocks == 0x0) {

			continue;

		}



		if (has_diff_segment(sit_area_bitmap, main_area_bitmap, segno)) {

			MSG(0, "segno: %u vblocks: %u seg_type: %d\n", segno, se->valid_blocks, se->type);

			MSG(0, "=Dump main bitmap=\n");

			dump_one_segment(main_area_bitmap, segno);

			MSG(0, "=Dump sit bitmap=\n");

			dump_one_segment(sit_area_bitmap, segno);

			return;

		}

	}

}