static void do_test_seq(badblocks_list bb, blk_t *vec) { int i, match; for (i = 0; vec[i]; i += 2) { switch (vec[i+1]) { case ADD_BLK: ext2fs_badblocks_list_add(bb, vec[i]); match = ext2fs_badblocks_list_test(bb, vec[i]); printf("Adding block %d --- now %s\n", vec[i], match ? "present" : "absent"); if (!match) { printf("FAILURE!\n"); test_fail++; } break; case DEL_BLK: ext2fs_badblocks_list_del(bb, vec[i]); match = ext2fs_badblocks_list_test(bb, vec[i]); printf("Removing block %d --- now %s\n", vec[i], ext2fs_badblocks_list_test(bb, vec[i]) ? "present" : "absent"); if (match) { printf("FAILURE!\n"); test_fail++; } break; } } }
/* * 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) { errcode_t errcode; if (ext2fs_badblocks_list_test(bb_list, bad)) return 0; fprintf(out, "%lu\n", (unsigned long) bad); fflush(out); errcode = ext2fs_badblocks_list_add (bb_list, bad); if (errcode) { com_err (program_name, errcode, "adding to in-memory bad block list"); exit (1); } /* kludge: increment the iteration through the bb_list if an element was just added before the current iteration position. This should not cause next_bad to change. */ if (bb_iter && bad < next_bad) ext2fs_badblocks_list_iterate (bb_iter, &next_bad); if (error_type == READ_ERROR) { num_read_errors++; } else if (error_type == WRITE_ERROR) { num_write_errors++; } else if (error_type == CORRUPTION_ERROR) { num_corruption_errors++; } return 1; }
static int mark_bad_block(ext2_filsys fs, blk_t *block_nr, e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), blk_t ref_block EXT2FS_ATTR((unused)), int ref_offset EXT2FS_ATTR((unused)), void *priv_data) { struct read_bb_record *rb = (struct read_bb_record *) priv_data; if (blockcnt < 0) return 0; if ((*block_nr < fs->super->s_first_data_block) || (*block_nr >= fs->super->s_blocks_count)) return 0; /* Ignore illegal blocks */ rb->err = ext2fs_badblocks_list_add(rb->bb_list, *block_nr); if (rb->err) return BLOCK_ABORT; return 0; }
/* * Reads a list of bad blocks from a FILE * */ errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f, ext2_badblocks_list *bb_list, void *priv_data, void (*invalid)(ext2_filsys fs, blk_t blk, char *badstr, void *priv_data)) { errcode_t retval; blk_t blockno; int count; char buf[128]; if (fs) EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); if (!*bb_list) { retval = ext2fs_badblocks_list_create(bb_list, 10); if (retval) return retval; } while (!feof (f)) { if (fgets(buf, sizeof(buf), f) == NULL) break; count = sscanf(buf, "%u", &blockno); if (count <= 0) continue; if (fs && ((blockno < fs->super->s_first_data_block) || (blockno >= ext2fs_blocks_count(fs->super)))) { if (invalid) (invalid)(fs, blockno, buf, priv_data); continue; } retval = ext2fs_badblocks_list_add(*bb_list, blockno); if (retval) return retval; } return 0; }
/* * 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 (unsigned long bad) { errcode_t errcode; if (ext2fs_badblocks_list_test(bb_list, bad)) return 0; fprintf (out, "%lu\n", bad); errcode = ext2fs_badblocks_list_add (bb_list, bad); if (errcode) { com_err (program_name, errcode, "adding to in-memory bad block list"); exit (1); } /* kludge: increment the iteration through the bb_list if an element was just added before the current iteration position. This should not cause next_bad to change. */ if (bb_iter && bad < next_bad) ext2fs_badblocks_list_iterate (bb_iter, &next_bad); return 1; }
static errcode_t create_test_list(blk_t *vec, badblocks_list *ret) { errcode_t retval; badblocks_list bb; int i; retval = ext2fs_badblocks_list_create(&bb, 5); if (retval) { com_err("create_test_list", retval, "while creating list"); return retval; } for (i=0; vec[i]; i++) { retval = ext2fs_badblocks_list_add(bb, vec[i]); if (retval) { com_err("create_test_list", retval, "while adding test vector %d", i); ext2fs_badblocks_list_free(bb); return retval; } } *ret = bb; return 0; }
errcode_t badblocks_list_add(badblocks_list bb, blk_t blk) { return ext2fs_badblocks_list_add(bb, blk); }
/* * Setup the variables for doing the inode scan test. */ static void setup(void) { errcode_t retval; int i; struct ext2_super_block param; initialize_ext2_error_table(); memset(¶m, 0, sizeof(param)); param.s_blocks_count = 12000; test_io_cb_read_blk = test_read_blk; retval = ext2fs_initialize("test fs", 0, ¶m, test_io_manager, &test_fs); if (retval) { com_err("setup", retval, "While initializing filesystem"); exit(1); } retval = ext2fs_allocate_tables(test_fs); if (retval) { com_err("setup", retval, "While allocating tables for test filesystem"); exit(1); } retval = ext2fs_allocate_block_bitmap(test_fs, "bad block map", &bad_block_map); if (retval) { com_err("setup", retval, "While allocating bad_block bitmap"); exit(1); } retval = ext2fs_allocate_block_bitmap(test_fs, "touched map", &touched_map); if (retval) { com_err("setup", retval, "While allocating touched block bitmap"); exit(1); } retval = ext2fs_allocate_inode_bitmap(test_fs, "bad inode map", &bad_inode_map); if (retval) { com_err("setup", retval, "While allocating bad inode bitmap"); exit(1); } retval = ext2fs_badblocks_list_create(&test_badblocks, 5); if (retval) { com_err("setup", retval, "while creating badblocks list"); exit(1); } for (i=0; test_vec[i]; i++) { retval = ext2fs_badblocks_list_add(test_badblocks, test_vec[i]); if (retval) { com_err("setup", retval, "while adding test vector %d", i); exit(1); } ext2fs_mark_block_bitmap(bad_block_map, test_vec[i]); } test_fs->badblocks = test_badblocks; }