mkdosfs 标记磁盘坏块
static void check_blocks(void)
{
int try, got;
int i;
static char blkbuf[BLOCK_SIZE * TEST_BUFFER_BLOCKS];
printf("[BLOCK_SIZE = %d, TEST_BUFFER_BLOCKS = %d]\n",BLOCK_SIZE , TEST_BUFFER_BLOCKS);
printf("start_data_block = %d,SECTORS_PER_BLOCK = %d\n",start_data_block,SECTORS_PER_BLOCK);
//[BLOCK_SIZE = 1024, TEST_BUFFER_BLOCKS = 16]
//start_data_block = 7992,SECTORS_PER_BLOCK = 2
if (verbose) {
printf("Searching for bad blocks ");
fflush(stdout);
}
currently_testing = 0;
if (verbose) {
signal(SIGALRM, alarm_intr);
alarm(5);
}
try = TEST_BUFFER_BLOCKS;
while (currently_testing < blocks) {
if (currently_testing + try > blocks)
try = blocks - currently_testing;
got = do_check(blkbuf, try, currently_testing);
currently_testing += got;
if (got == try) { //try=16块一起读,读出来也是16块,说明没有坏块
try = TEST_BUFFER_BLOCKS;
continue;
} else //读出来不够try != 16块,说明读错误,存在坏块。
try = 1; //分成一块一块地检
if (currently_testing < start_data_block)
die("bad blocks before data-area: cannot make fs");
for (i = 0; i < SECTORS_PER_BLOCK; i++) /* Mark all of the sectors in the block as bad */ //分成一个一个扇区
mark_sector_bad(currently_testing * SECTORS_PER_BLOCK + i);
badblocks++;
currently_testing++;
}
if (verbose)
printf("\n");
if (badblocks)
printf("%d bad block%s\n", badblocks, (badblocks > 1) ? "s" : "");
}
static long do_check(char *buffer, int try, off_t current_block)
{
long got;
if (llseek(dev, current_block * BLOCK_SIZE, SEEK_SET) /* Seek to the correct location */
!=current_block * BLOCK_SIZE)
die("seek failed during testing for blocks");
got = read(dev, buffer, try * BLOCK_SIZE); /* Try reading! */
if (got < 0)
got = 0;
if (got & (BLOCK_SIZE - 1))
printf("Unexpected values in do_check: probably bugs\n");
got /= BLOCK_SIZE;
return got;
}
#define mark_sector_bad( sector ) mark_FAT_sector( sector, FAT_BAD )
static void mark_FAT_sector(int sector, unsigned int value)
{
int cluster;
cluster = (sector - start_data_sector) / (int)(bs.cluster_size) /
(sector_size / HARD_SECTOR_SIZE);
if (cluster < 0)
die("Invalid cluster number in mark_FAT_sector: probably bug!");
mark_FAT_cluster(cluster, value); //扇区所在簇进行标记(标记以簇为单位),1簇=4块=8扇区
}
static void mark_FAT_cluster(int cluster, unsigned int value)
{
switch (size_fat) {
case 12:
value &= 0x0fff;
if (((cluster * 3) & 0x1) == 0) {
fat[3 * cluster / 2] = (unsigned char)(value & 0x00ff);
fat[(3 * cluster / 2) + 1] =
(unsigned char)((fat[(3 * cluster / 2) + 1] & 0x00f0)
| ((value & 0x0f00) >> 8));
} else {
fat[3 * cluster / 2] =
(unsigned char)((fat[3 * cluster / 2] & 0x000f) |
((value & 0x000f) << 4));
fat[(3 * cluster / 2) + 1] = (unsigned char)((value & 0x0ff0) >> 4);
}
break;
case 16:
value &= 0xffff;
fat[2 * cluster] = (unsigned char)(value & 0x00ff);
fat[(2 * cluster) + 1] = (unsigned char)(value >> 8);
break;
case 32:
value &= 0xfffffff;
fat[4 * cluster] = (unsigned char)(value & 0x000000ff);
fat[(4 * cluster) + 1] = (unsigned char)((value & 0x0000ff00) >> 8);
fat[(4 * cluster) + 2] = (unsigned char)((value & 0x00ff0000) >> 16);
fat[(4 * cluster) + 3] = (unsigned char)((value & 0xff000000) >> 24);
break;
default:
die("Bad FAT size (not 12, 16, or 32)");
}
}