/// check per FAT12 entry unsigned long long check_fat12_entry(unsigned long* fat_bitmap, unsigned long long block, unsigned long long* bfree, unsigned long long* bused, unsigned long long* DamagedClusters) { uint16_t Fat16_Entry = 0; uint16_t Fat12_Entry = 0; int rd = 0; unsigned long long i = 0; rd = read(ret, &Fat16_Entry, sizeof(Fat16_Entry)); if (rd == -1) log_mesg(2, 0, 0, fs_opt.debug, "%s: read Fat12_Entry error\n", __FILE__); Fat12_Entry = Fat16_Entry>>4; if (Fat12_Entry == 0xFFF7) { /// bad FAT12 cluster DamagedClusters++; log_mesg(2, 0, 0, fs_opt.debug, "%s: bad sec %llu\n", __FILE__, block); for (i=0; i < fat_sb.cluster_size; i++,block++) pc_clear_bit(block, fat_bitmap); } else if (Fat12_Entry == 0x0000){ /// free bfree++; for (i=0; i < fat_sb.cluster_size; i++,block++) pc_clear_bit(block, fat_bitmap); } else { bused++; for (i=0; i < fat_sb.cluster_size; i++,block++) pc_set_bit(block, fat_bitmap); } return block; }
void read_bitmap(char* device, file_system_info fs_info, unsigned long* bitmap, int pui) { uint32_t offset, total, current; uint32_t used_block = 0, free_block = 0, err_block = 0; int status = 0; int start = 0; int bit_size = 1; fs_open(device); /// init progress progress_bar prog; /// progress_bar structure defined in progress.h progress_init(&prog, start, fs_info.totalblock, fs_info.totalblock, BITMAP, bit_size); offset = logical_volume_offset(fs); total = fs->fbb->bmh.total_items + offset; // containing the volume information and the LVM information for(current = 0; current < offset; current++){ pc_set_bit(current, bitmap); used_block++; update_pui(&prog, current, current, 0); } // the logical volume for(current = offset; current < total; current++){ status = vmfs_block_get_status(fs, VMFS_BLK_FB_BUILD(current-offset,0)); if (status == -1) { err_block++; pc_clear_bit(current, bitmap); } else if (status == 1){ used_block++; pc_set_bit(current, bitmap); } else if (status == 0){ free_block++; pc_clear_bit(current, bitmap); } log_mesg(2, 0, 0, fs_opt.debug, "%s: Block 0x%8.8x status: %i\n", __FILE__, current, status); update_pui(&prog, current, current, 0); } fs_close(); update_pui(&prog, 1, 1, 1); log_mesg(0, 0, 0, fs_opt.debug, "%s: Used:%"PRIu32", Free:%"PRIu32", Status err:%"PRIu32"\n", __FILE__, used_block, free_block, err_block); }
/// readbitmap - read bitmap extern void readbitmap(char* device, image_head image_hdr, unsigned long* bitmap, int pui) { uint32_t current = 0, used_block = 0, free_block = 0, err_block = 0, total = 0, alloc = 0; int status = 0; int start = 0; int bit_size = 1; fs_open(device); /// init progress progress_bar prog; /// progress_bar structure defined in progress.h progress_init(&prog, start, image_hdr.totalblock, image_hdr.totalblock, BITMAP, bit_size); total = fs->fbb->bmh.total_items; alloc = vmfs_bitmap_allocated_items(fs->fbb); for(current = 0; current < total; current++){ status = vmfs_block_get_status(fs, VMFS_BLK_FB_BUILD(current)); if (status == -1) { err_block++; pc_clear_bit(current, bitmap); } else if (status == 1){ used_block++; pc_set_bit(current, bitmap); } else if (status == 0){ free_block++; pc_clear_bit(current, bitmap); } log_mesg(2, 0, 0, fs_opt.debug, "%s: Block 0x%8.8x status: %i\n", __FILE__, current, status); update_pui(&prog, current, current, 0); } fs_close(); update_pui(&prog, 1, 1, 1); log_mesg(0, 0, 0, fs_opt.debug, "%s: Used:%lld, Free:%lld, Status err:%lld\n", __FILE__, used_block, free_block, err_block); }
void load_image_bitmap_bytes(int* ret, cmd_opt opt, file_system_info fs_info, unsigned long* bitmap) { unsigned long long size, r_size, r_need; char buffer[16384]; unsigned long long offset = 0; unsigned long long bused = 0, bfree = 0; int i, debug = opt.debug; int err_exit = 1; char bitmagic_r[8]="00000000";/// read magic string from image size = fs_info.totalblock; while (size > 0) { r_need = size > sizeof(buffer) ? sizeof(buffer) : size; r_size = read_all(ret, buffer, r_need, &opt); if (r_size < r_need) log_mesg(0, 1, 1, debug, "Unable to read bitmap.\n"); for (i = 0; i < r_need; i++) { if (buffer[i] == 1) { pc_set_bit(offset + i, bitmap); bused++; } else { pc_clear_bit(offset + i, bitmap); bfree++; } } offset += r_need; size -= r_need; } if (debug >= 2) { if (fs_info.usedblocks != bused) { if (opt.force) err_exit = 0; else err_exit = 1; log_mesg(0, err_exit, 1, debug, "The Used Block count is different. (bitmap %llu != file system %llu)\n" "Try to use --force to skip the metadata error.\n", bused, fs_info.usedblocks); } } /// read magic string from image file and check it. if (read_all(ret, bitmagic_r, BIT_MAGIC_SIZE, &opt) != BIT_MAGIC_SIZE) log_mesg(0, 1, 1, debug, "read magic ERROR:%s\n", strerror(errno)); if (memcmp(bitmagic_r, BIT_MAGIC, BIT_MAGIC_SIZE)) log_mesg(0, 1, 1, debug, "can't find bitmagic\n"); }
/// readbitmap - read bitmap extern void readbitmap(char* device, image_head image_hdr, unsigned long* bitmap, int pui) { unsigned long long total_block, block, bused = 0, bfree = 0; int done = 0, i = 0, start = 0, bit_size = 1; unsigned char* p; fs_open(device); /// init progress progress_bar bprog; /// progress_bar structure defined in progress.h progress_init(&bprog, start, image_hdr.totalblock, image_hdr.totalblock, BITMAP, bit_size); total_block = 0; /// read group while ((i = cgread(&disk)) != 0) { log_mesg(2, 0, 0, fs_opt.debug, "%s: \ncg = %d\n", __FILE__, disk.d_lcg); log_mesg(2, 0, 0, fs_opt.debug, "%s: blocks = %i\n", __FILE__, acg.cg_ndblk); p = cg_blksfree(&acg); for (block = 0; block < acg.cg_ndblk; block++){ if (isset(p, block)) { pc_clear_bit(total_block, bitmap); bfree++; log_mesg(3, 0, 0, fs_opt.debug, "%s: bitmap is free %lli\n", __FILE__, block); } else { pc_set_bit(total_block, bitmap); bused++; log_mesg(3, 0, 0, fs_opt.debug, "%s: bitmap is used %lli\n", __FILE__, block); } total_block++; update_pui(&bprog, total_block, total_block,done); } log_mesg(1, 0, 0, fs_opt.debug, "%s: read bitmap done\n", __FILE__); } fs_close(); log_mesg(1, 0, 0, fs_opt.debug, "%s: total used = %lli, total free = %lli\n", __FILE__, bused, bfree); update_pui(&bprog, 1, 1, 1); }
void read_bitmap(char* device, file_system_info fs_info, unsigned long* bitmap, int pui) { reiserfs_bitmap_t *fs_bitmap; reiserfs_tree_t *tree; unsigned long long blk = 0; unsigned long long bused = 0, bfree = 0; int start = 0; int bit_size = 1; int done = 0; fs_open(device); tree = reiserfs_fs_tree(fs); fs_bitmap = tree->fs->bitmap; /// init progress progress_bar bprog; /// progress_bar structure defined in progress.h progress_init(&bprog, start, fs->super->s_v1.sb_block_count, fs->super->s_v1.sb_block_count, BITMAP, bit_size); for( blk = 0; blk < (unsigned long long)fs->super->s_v1.sb_block_count; blk++ ){ log_mesg(3, 0, 0, fs_opt.debug, "%s: block sb_block_count %llu\n", __FILE__, fs->super->s_v1.sb_block_count); log_mesg(3, 0, 0, fs_opt.debug, "%s: block bitmap check %llu\n", __FILE__, blk); if(reiserfs_tools_test_bit(blk, fs_bitmap->bm_map)){ bused++; pc_set_bit(blk, bitmap); }else{ bfree++; pc_clear_bit(blk, bitmap); } /// update progress update_pui(&bprog, blk, blk, done); } if(bfree != fs->super->s_v1.sb_free_blocks) log_mesg(0, 1, 1, fs_opt.debug, "%s: bitmap free count err, free:%i\n", __FILE__, bfree); fs_close(); /// update progress update_pui(&bprog, 1, 1, 1); }
/// get bitmap from image file to restore data void get_image_bitmap(int* ret, cmd_opt opt, image_head image_hdr, unsigned long* bitmap) { unsigned long long size, r_size, r_need; char buffer[16384]; unsigned long long offset = 0; unsigned long long bused = 0, bfree = 0; int i, debug = opt.debug; int err_exit = 1; size = sizeof(char)*image_hdr.totalblock; while (size > 0) { r_need = size > sizeof(buffer) ? sizeof(buffer) : size; r_size = read_all(ret, buffer, r_need, &opt); if (r_size < r_need) log_mesg(0, 1, 1, debug, "Unable to read bitmap.\n"); for (i = 0; i < r_need; i++) { if (buffer[i] == 1) { pc_set_bit(offset + i, bitmap); bused++; } else { pc_clear_bit(offset + i, bitmap); bfree++; } } offset += r_need; size -= r_need; } if (debug >= 2) { if (image_hdr.usedblocks != bused) { if (opt.force) err_exit = 0; else err_exit = 1; log_mesg(0, err_exit, 1, debug, "The Used Block count is different. (bitmap %llu != image_head %llu)\n" "Try to use --force to skip the metadata error.\n", bused, image_hdr.usedblocks); } } }
/// readbitmap - cread and heck bitmap, reference dumpe2fs extern void readbitmap(char* device, image_head image_hdr, unsigned long* bitmap, int pui){ errcode_t retval; unsigned long group; unsigned long long current_block, block; unsigned long long free, gfree; char *block_bitmap=NULL; int block_nbytes; unsigned long long blk_itr; int bg_flags = 0; int start = 0; int bit_size = 1; int B_UN_INIT = 0; int ext4_gfree_mismatch = 0; log_mesg(2, 0, 0, fs_opt.debug, "%s: readbitmap %p\n", __FILE__, bitmap); fs_open(device); retval = ext2fs_read_bitmaps(fs); /// open extfs bitmap if (retval) log_mesg(0, 1, 1, fs_opt.debug, "%s: Couldn't find valid filesystem bitmap.\n", __FILE__); block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; if (fs->block_map) block_bitmap = malloc(block_nbytes); /// initial image bitmap as 1 (all block are used) memset(bitmap, 0xFF, sizeof(unsigned long)*LONGS(image_hdr.totalblock)); free = 0; current_block = 0; blk_itr = fs->super->s_first_data_block; /// init progress progress_bar prog; /// progress_bar structure defined in progress.h progress_init(&prog, start, image_hdr.totalblock, image_hdr.totalblock, BITMAP, bit_size); /// each group for (group = 0; group < fs->group_desc_count; group++) { gfree = 0; B_UN_INIT = 0; if (block_bitmap) { ext2fs_get_block_bitmap_range(fs->block_map, blk_itr, block_nbytes << 3, block_bitmap); if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM){ #ifdef EXTFS_1_41 bg_flags = fs->group_desc[group].bg_flags; #else bg_flags = ext2fs_bg_flags(fs, group); #endif if (bg_flags&EXT2_BG_BLOCK_UNINIT){ log_mesg(1, 0, 0, fs_opt.debug, "%s: BLOCK_UNINIT for group %lu\n", __FILE__, group); B_UN_INIT = 1; } else { log_mesg(2, 0, 0, fs_opt.debug, "%s: BLOCK_INIT for group %lu\n", __FILE__, group); } } /// each block in group for (block = 0; ((block < fs->super->s_blocks_per_group) && (current_block < (image_hdr.totalblock-1))); block++) { current_block = block + blk_itr; /// check block is used or not if ((!in_use (block_bitmap, block)) || (B_UN_INIT)) { free++; gfree++; pc_clear_bit(current_block, bitmap); log_mesg(3, 0, 0, fs_opt.debug, "%s: free block %llu at group %lu init %i\n", __FILE__, current_block, group, (int)B_UN_INIT); } else { pc_set_bit(current_block, bitmap); log_mesg(3, 0, 0, fs_opt.debug, "%s: used block %llu at group %lu\n", __FILE__, current_block, group); } /// update progress update_pui(&prog, current_block, current_block, 0);//keep update } blk_itr += fs->super->s_blocks_per_group; } /// check free blocks in group #ifdef EXTFS_1_41 if (gfree != fs->group_desc[group].bg_free_blocks_count){ #else if (gfree != ext2fs_bg_free_blocks_count(fs, group)){ #endif if (!B_UN_INIT) log_mesg(0, 1, 1, fs_opt.debug, "%s: bitmap error at %lu group.\n", __FILE__, group); else ext4_gfree_mismatch = 1; } } /// check all free blocks in partition if (free != fs->super->s_free_blocks_count) { if ((fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) && (ext4_gfree_mismatch)) log_mesg(1, 0, 0, fs_opt.debug, "%s: EXT4 bitmap metadata mismatch\n", __FILE__); else log_mesg(0, 1, 1, fs_opt.debug, "%s: bitmap free count err, free:%llu\n", __FILE__, free); } fs_close(); /// update progress update_pui(&prog, 1, 1, 1);//finish } /// get extfs type static int test_extfs_type(char* device){ int ext2 = 1; int ext3 = 2; int ext4 = 3; int device_type; fs_open(device); if(fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM){ log_mesg(1, 0, 0, fs_opt.debug, "%s: test feature as EXT4\n", __FILE__); device_type = ext4; } else if (fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL){ log_mesg(1, 0, 0, fs_opt.debug, "%s: test feature as EXT3\n", __FILE__); device_type = ext3; } else { log_mesg(1, 0, 0, fs_opt.debug, "%s: test feature as EXT2\n", __FILE__); device_type = ext2; } fs_close(); return device_type; }