[ext2fs] initial ext2fs support

This commit is contained in:
Pete Batard 2019-04-12 21:32:40 +01:00
parent f4d70345af
commit cda716c1ff
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
87 changed files with 29093 additions and 130 deletions

View file

@ -1,36 +1,19 @@
/*
* badblocks.c - Bad blocks checker
* badblocks.c - Bad blocks checker
*
* Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* Copyright 1995, 1996, 1997, 1998, 1999 by Theodore Ts'o
* Copyright 1999 by David Beattie
* Copyright 2011-2018 by Pete Batard
* Copyright 1992-1994 Remy Card <card@masi.ibp.fr>
* Copyright 1995-1999 Theodore Ts'o
* Copyright 1999 David Beattie
* Copyright 2011-2019 Pete Batard <pete@akeo.ie>
*
* This file is based on the minix file system programs fsck and mkfs
* written and copyrighted by Linus Torvalds <Linus.Torvalds@cs.helsinki.fi>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
* This file may be redistributed under the terms of the GNU Public License.
* %End-Header%
*/
/*
* History:
* 93/05/26 - Creation from e2fsck
* 94/02/27 - Made a separate bad blocks checker
* 99/06/30...99/07/26 - Added non-destructive write-testing,
* configurable blocks-at-once parameter,
* loading of badblocks list to avoid testing
* blocks known to be bad, multiple passes to
* make sure that no new blocks are added to the
* list. (Work done by David Beattie)
* 11/12/04 - Windows/Rufus integration (Pete Batard)
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -84,16 +67,16 @@ static errcode_t make_u64_list(int size, int num, uint64_t *list, bb_u64_list *r
bb->magic = BB_ET_MAGIC_BADBLOCKS_LIST;
bb->size = size ? size : 10;
bb->num = num;
bb->list = malloc(sizeof(blk_t) * bb->size);
bb->list = malloc(sizeof(blk64_t) * bb->size);
if (bb->list == NULL) {
free(bb);
bb = NULL;
return BB_ET_NO_MEMORY;
}
if (list)
memcpy(bb->list, list, bb->size * sizeof(blk_t));
memcpy(bb->list, list, bb->size * sizeof(blk64_t));
else
memset(bb->list, 0, bb->size * sizeof(blk_t));
memset(bb->list, 0, bb->size * sizeof(blk64_t));
*ret = bb;
return 0;
}
@ -155,7 +138,7 @@ static errcode_t bb_u64_list_add(bb_u64_list bb, uint64_t blk)
return 0;
}
static errcode_t bb_badblocks_list_add(bb_badblocks_list bb, blk_t blk)
static errcode_t bb_badblocks_list_add(bb_badblocks_list bb, blk64_t blk)
{
return bb_u64_list_add((bb_u64_list) bb, blk);
}
@ -164,7 +147,7 @@ static errcode_t bb_badblocks_list_add(bb_badblocks_list bb, blk_t blk)
* This procedure finds a particular block is on a badblocks
* list.
*/
static int bb_u64_list_find(bb_u64_list bb, uint64_t blk)
static int bb_u64_list_find(bb_u64_list bb, blk64_t blk)
{
int low, high, mid;
@ -199,7 +182,7 @@ static int bb_u64_list_find(bb_u64_list bb, uint64_t blk)
* This procedure tests to see if a particular block is on a badblocks
* list.
*/
static int bb_u64_list_test(bb_u64_list bb, uint64_t blk)
static int bb_u64_list_test(bb_u64_list bb, blk64_t blk)
{
if (bb_u64_list_find(bb, blk) < 0)
return 0;
@ -207,12 +190,12 @@ static int bb_u64_list_test(bb_u64_list bb, uint64_t blk)
return 1;
}
static int bb_badblocks_list_test(bb_badblocks_list bb, blk_t blk)
static int bb_badblocks_list_test(bb_badblocks_list bb, blk64_t blk)
{
return bb_u64_list_test((bb_u64_list) bb, blk);
}
static int bb_u64_list_iterate(bb_u64_iterate iter, uint64_t *blk)
static int bb_u64_list_iterate(bb_u64_iterate iter, blk64_t *blk)
{
bb_u64_list bb;
@ -232,7 +215,7 @@ static int bb_u64_list_iterate(bb_u64_iterate iter, uint64_t *blk)
return 0;
}
static int bb_badblocks_list_iterate(bb_badblocks_iterate iter, blk_t *blk)
static int bb_badblocks_list_iterate(bb_badblocks_iterate iter, blk64_t *blk)
{
return bb_u64_list_iterate((bb_u64_iterate) iter, blk);
}
@ -247,13 +230,13 @@ static int cur_pattern, nr_pattern;
static int cur_op;
/* Abort test if more than this number of bad blocks has been encountered */
static unsigned int max_bb = BB_BAD_BLOCKS_THRESHOLD;
static blk_t currently_testing = 0;
static blk_t num_blocks = 0;
static blk64_t currently_testing = 0;
static blk64_t num_blocks = 0;
static uint32_t num_read_errors = 0;
static uint32_t num_write_errors = 0;
static uint32_t num_corruption_errors = 0;
static bb_badblocks_list bb_list = NULL;
static blk_t next_bad = 0;
static blk64_t next_bad = 0;
static bb_badblocks_iterate bb_iter = NULL;
static __inline void *allocate_buffer(size_t size) {
@ -268,7 +251,7 @@ static __inline void free_buffer(void* p) {
* This routine reports a new bad block. If the bad block has already
* been seen before, then it returns 0; otherwise it returns 1.
*/
static int bb_output (blk_t bad, enum error_types error_type)
static int bb_output (blk64_t bad, enum error_types error_type)
{
errcode_t error_code;
@ -381,8 +364,8 @@ static void pattern_fill(unsigned char *buffer, unsigned int pattern,
* Perform a read of a sequence of blocks; return the number of blocks
* successfully sequentially read.
*/
static int64_t do_read (HANDLE hDrive, unsigned char * buffer, uint64_t tryout, uint64_t block_size,
blk_t current_block)
static int64_t do_read (HANDLE hDrive, unsigned char * buffer, uint64_t tryout,
uint64_t block_size, blk64_t current_block)
{
int64_t got;
@ -403,8 +386,8 @@ static int64_t do_read (HANDLE hDrive, unsigned char * buffer, uint64_t tryout,
* Perform a write of a sequence of blocks; return the number of blocks
* successfully sequentially written.
*/
static int64_t do_write(HANDLE hDrive, unsigned char * buffer, uint64_t tryout, uint64_t block_size,
blk_t current_block)
static int64_t do_write(HANDLE hDrive, unsigned char * buffer, uint64_t tryout,
uint64_t block_size, blk64_t current_block)
{
int64_t got;
@ -421,15 +404,15 @@ static int64_t do_write(HANDLE hDrive, unsigned char * buffer, uint64_t tryout,
return got;
}
static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size, blk_t first_block,
size_t blocks_at_once, int pattern_type, int nb_passes)
static unsigned int test_rw(HANDLE hDrive, blk64_t last_block, size_t block_size, blk64_t first_block,
size_t blocks_at_once, int pattern_type, int nb_passes)
{
const unsigned int pattern[BADLOCKS_PATTERN_TYPES][BADBLOCK_PATTERN_COUNT] =
{ BADBLOCK_PATTERN_SLC, BADCLOCK_PATTERN_MLC, BADBLOCK_PATTERN_TLC };
unsigned char *buffer = NULL, *read_buffer;
int i, pat_idx;
unsigned int bb_count = 0;
blk_t got, tryout, recover_block = ~0, *blk_id;
blk64_t got, tryout, recover_block = ~0, *blk_id;
size_t id_offset = 0;
if ((pattern_type < 0) || (pattern_type >= BADLOCKS_PATTERN_TYPES)) {
@ -463,7 +446,7 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size,
goto out;
if (detect_fakes && (pat_idx == 0)) {
srand((unsigned int)GetTickCount64());
id_offset = rand() * (block_size - sizeof(blk_t)) / RAND_MAX;
id_offset = rand() * (block_size - sizeof(blk64_t)) / RAND_MAX;
uprintf("%sUsing offset %d for fake device check\n", bb_prefix, id_offset);
}
// coverity[dont_call]
@ -492,8 +475,8 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size,
/* Add the block number at a fixed (random) offset during each pass to
allow for the detection of 'fake' media (eg. 2GB USB masquerading as 16GB) */
for (i=0; i<(int)blocks_at_once; i++) {
blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size);
*blk_id = (blk_t)(currently_testing + i);
blk_id = (blk64_t*)(intptr_t)(buffer + id_offset+ i*block_size);
*blk_id = (blk64_t)(currently_testing + i);
}
}
got = do_write(hDrive, buffer, tryout, block_size, currently_testing);
@ -538,8 +521,8 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size,
tryout = last_block - currently_testing;
if (detect_fakes && (pat_idx == 0)) {
for (i=0; i<(int)blocks_at_once; i++) {
blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size);
*blk_id = (blk_t)(currently_testing + i);
blk_id = (blk64_t*)(intptr_t)(buffer + id_offset+ i*block_size);
*blk_id = (blk64_t)(currently_testing + i);
}
}
got = do_read(hDrive, read_buffer, tryout, block_size,
@ -575,10 +558,10 @@ out:
}
BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int nb_passes,
int flash_type, badblocks_report *report, FILE* fd)
int flash_type, badblocks_report *report, FILE* fd)
{
errcode_t error_code;
blk_t last_block = disk_size / BADBLOCK_BLOCK_SIZE;
blk64_t last_block = disk_size / BADBLOCK_BLOCK_SIZE;
if (report == NULL) return FALSE;
num_read_errors = 0;