void read_bitmap(char* device, file_system_info fs_info, unsigned long* bitmap, int pui) { off_t a = 0, b = 0; off_t block = 0;; int start = 0; int bit_size = 1; pc_init_bitmap(bitmap, 0x00, fs_info.totalblock); 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); pc_init_bitmap(bitmap, 0x00, fs_info.totalblock); while (exfat_find_used_sectors(&ef, &a, &b) == 0) { printf("block %" PRId64 " %" PRId64 " \n", a, b); for (block = a; block <= b; block++) { pc_set_bit((uint64_t)block, bitmap); log_mesg(3, 0, 0, fs_opt.debug, "%s: used block %" PRId64 " \n", __FILE__, block); /// update progress update_pui(&prog, block, block, 0); } } fs_close(); /// update progress update_pui(&prog, 1, 1, 1); }
/// 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); }
extern void readbitmap(char* device, image_head image_hdr, unsigned long* bitmap, int pui){ unsigned long zones = get_nzones(); unsigned long imaps = get_nimaps(); unsigned long zmaps = get_nzmaps(); char * inode_map; char * zone_map; ssize_t rc; unsigned long test_block = 0, test_zone = 0; fs_open(device); unsigned long block_size = get_block_size(); if (fs_version == 3){ if (lseek(dev, block_size*2, SEEK_SET) != 8192) log_mesg(0, 1, 1, fs_opt.debug, "%s: seek failed", __FILE__); } inode_map = malloc(imaps * block_size); if (!inode_map) log_mesg(0, 1, 1, fs_opt.debug, "%s: Unable to allocate buffer for inode map", __FILE__); zone_map = malloc(zmaps * block_size); if (!inode_map) log_mesg(0, 1, 1, fs_opt.debug, "%s: Unable to allocate buffer for zone map", __FILE__); memset(inode_map,0,sizeof(inode_map)); memset(zone_map,0,sizeof(zone_map)); memset(bitmap,0,sizeof(unsigned long)*LONGS(image_hdr.totalblock)); rc = read(dev, inode_map, imaps * block_size); if (rc < 0 || imaps * block_size != (size_t) rc) log_mesg(0, 1, 1, fs_opt.debug, "%s: Unable to read inode map", __FILE__); rc = read(dev, zone_map, zmaps * block_size); if (rc < 0 || zmaps * block_size != (size_t) rc) log_mesg(0, 1, 1, fs_opt.debug, "%s: Unable to read zone map", __FILE__); log_mesg(0, 0, 0, fs_opt.debug, "%s: %ld blocks\n", __FILE__, zones); log_mesg(0, 0, 0, fs_opt.debug, "%s: log2 block/zone: %lu\n", __FILE__, get_zone_size()); log_mesg(0, 0, 0, fs_opt.debug, "%s: Zonesize=%d\n", __FILE__,block_size<<get_zone_size()); log_mesg(0, 0, 0, fs_opt.debug, "%s: Maxsize=%ld\n", __FILE__, get_max_size()); for (test_block = 0; test_block < zones; test_block++){ test_zone = test_block - get_first_zone()+1; if ((test_zone < 0) || (test_zone > zones+get_first_zone())) test_zone = 0; if(isset(zone_map,test_zone)){ log_mesg(3, 0, 0, fs_opt.debug, "%s: test_block %lu in use\n", __FILE__, test_block); pc_set_bit(test_block, bitmap); }else{ log_mesg(3, 0, 0, fs_opt.debug, "%s: test_block %lu not use\n", __FILE__, test_block); } } fs_close(); }
/// mark reserved sectors as used static unsigned long long mark_reserved_sectors(unsigned long* fat_bitmap, unsigned long long block) { unsigned long long i = 0; unsigned long long j = 0; unsigned long long sec_per_fat = 0; unsigned long long root_sec = 0; sec_per_fat = get_sec_per_fat(); root_sec = get_root_sec(); /// A) the reserved sectors are used for (i=0; i < fat_sb.reserved; i++,block++) pc_set_bit(block, fat_bitmap); /// B) the FAT tables are on used sectors for (j=0; j < fat_sb.fats; j++) for (i=0; i < sec_per_fat ; i++,block++) pc_set_bit(block, fat_bitmap); /// C) The rootdirectory is on used sectors if (root_sec > 0) /// no rootdir sectors on FAT32 for (i=0; i < root_sec; i++,block++) pc_set_bit(block, fat_bitmap); return block; }
static void set_bitmap(unsigned long* bitmap, uint64_t pos, int length) { uint64_t pos_block; uint64_t block_count; uint64_t block; pos_block = pos/source_blocksize; block_count = length/source_blocksize; for (block = pos_block; block < pos_block+block_count; block++){ pc_set_bit(block, bitmap); log_mesg(3, 0, 0, fs_opt.debug, "block %i is used\n", 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); }
///set useb block static void set_bitmap(unsigned long* bitmap, uint64_t segm, uint64_t count){ uint64_t block; uint64_t pos_block; uint64_t block_end; log_mesg(3, 0, 0, fs_opt.debug, "%s: segment: %llu count %llu\n", __FILE__, segm, count); if (segm*blocks_per_segment + count > total_block) { log_mesg(1, 0, 0, fs_opt.debug, "%s: block(%llu) larger than total blocks(%llu), skip it.\n", __FILE__, segm, total_block); return; } pos_block = segm*blocks_per_segment; block_end = (segm+1)*blocks_per_segment; log_mesg(3, 0, 0, fs_opt.debug, "%s: block offset: %llu block count: %llu\n",__FILE__, pos_block, block_end); for(block = pos_block; block < block_end; block++){ log_mesg(3, 0, 0, fs_opt.debug, "%s: block %i is used\n",__FILE__, block); pc_set_bit(block, bitmap); } }
/// 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 - 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); }
/// get_used_block - get FAT used blocks static unsigned long long get_used_block() { unsigned long long i = 0; int fat_stat = 0; unsigned long long block = 0, bfree = 0, bused = 0, DamagedClusters = 0; unsigned long long cluster_count = 0, total_sector = 0; unsigned long long real_back_block= 0; int FatReservedBytes = 0; unsigned long *fat_bitmap; log_mesg(2, 0, 0, fs_opt.debug, "%s: get_used_block start\n", __FILE__); total_sector = get_total_sector(); cluster_count = get_cluster_count(); fat_bitmap = (unsigned long *)calloc(sizeof(unsigned long), LONGS(total_sector)); if (fat_bitmap == NULL) log_mesg(2, 1, 1, fs_opt.debug, "%s: bitmapalloc error\n", __FILE__); memset(fat_bitmap, 0xFF, sizeof(unsigned long)*LONGS(total_sector)); /// A) B) C) block = mark_reserved_sectors(fat_bitmap, block); /// D) The clusters FatReservedBytes = fat_sb.sector_size * fat_sb.reserved; /// The first fat will be seek lseek(ret, FatReservedBytes, SEEK_SET); /// The second fat is used to check FAT status fat_stat = check_fat_status(); if (fat_stat == 1) log_mesg(0, 1, 1, fs_opt.debug, "%s: Filesystem isn't in valid state. May be it is not cleanly unmounted.\n\n", __FILE__); else if (fat_stat == 2) log_mesg(0, 1, 1, fs_opt.debug, "%s: I/O error! %X\n", __FILE__); for (i=0; i < cluster_count; i++){ /// If FAT16 if(FS == FAT_16){ block = check_fat16_entry(fat_bitmap, block, &bfree, &bused, &DamagedClusters); } else if (FS == FAT_32){ /// FAT32 block = check_fat32_entry(fat_bitmap, block, &bfree, &bused, &DamagedClusters); } else if (FS == FAT_12){ /// FAT12 block = check_fat12_entry(fat_bitmap, block, &bfree, &bused, &DamagedClusters); } else log_mesg(2, 0, 0, fs_opt.debug, "%s: error fs\n", __FILE__); } while(block < total_sector){ pc_set_bit(block, fat_bitmap); block++; } for (block = 0; block < total_sector; block++) { if (pc_test_bit(block, fat_bitmap)) { real_back_block++; } } free(fat_bitmap); log_mesg(2, 0, 0, fs_opt.debug, "%s: get_used_block down\n", __FILE__); return real_back_block; }
/// 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; }