errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish, int num, ext2fs_block_bitmap map, blk64_t *ret) { blk64_t b = start; int c_ratio; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); if (!map) map = fs->block_map; if (!map) return EXT2_ET_NO_BLOCK_BITMAP; if (!b) b = fs->super->s_first_data_block; if (!finish) finish = start; if (!num) num = 1; c_ratio = 1 << ext2fs_get_bitmap_granularity(map); b &= ~(c_ratio - 1); finish &= ~(c_ratio -1); do { if (b+num-1 > ext2fs_blocks_count(fs->super)) b = fs->super->s_first_data_block; if (ext2fs_fast_test_block_bitmap_range2(map, b, num)) { *ret = b; return 0; } b += c_ratio; } while (b != finish); return EXT2_ET_BLOCK_ALLOC_FAIL; }
errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs, ext2fs_block_bitmap *bitmap) { ext2fs_block_bitmap cmap, bmap; errcode_t retval; blk64_t i, b_end, c_end; int n, ratio; bmap = *bitmap; if (fs->cluster_ratio_bits == ext2fs_get_bitmap_granularity(bmap)) return 0; /* Nothing to do */ retval = ext2fs_allocate_block_bitmap(fs, "converted cluster bitmap", &cmap); if (retval) return retval; i = bmap->start; b_end = bmap->end; bmap->end = bmap->real_end; c_end = cmap->end; cmap->end = cmap->real_end; n = 0; ratio = 1 << fs->cluster_ratio_bits; while (i < bmap->real_end) { if (ext2fs_test_block_bitmap2(bmap, i)) { ext2fs_mark_block_bitmap2(cmap, i); i += ratio - n; n = 0; continue; } i++; n++; if (n >= ratio) n = 0; } bmap->end = b_end; cmap->end = c_end; ext2fs_free_block_bitmap(bmap); *bitmap = cmap; return 0; }
/* * Stupid algorithm --- we now just search forward starting from the * goal. Should put in a smarter one someday.... */ errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal, ext2fs_block_bitmap map, blk64_t *ret) { blk64_t i; int c_ratio; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); if (!map) map = fs->block_map; if (!map) return EXT2_ET_NO_BLOCK_BITMAP; if (!goal || (goal >= ext2fs_blocks_count(fs->super))) goal = fs->super->s_first_data_block; i = goal; c_ratio = 1 << ext2fs_get_bitmap_granularity(map); if (c_ratio > 1) goal &= ~EXT2FS_CLUSTER_MASK(fs); check_block_uninit(fs, map, (i - fs->super->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(fs->super)); do { if (((i - fs->super->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(fs->super)) == 0) check_block_uninit(fs, map, (i - fs->super->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(fs->super)); if (!ext2fs_fast_test_block_bitmap2(map, i)) { *ret = i; return 0; } i = (i + c_ratio) & ~(c_ratio - 1); if (i >= ext2fs_blocks_count(fs->super)) i = fs->super->s_first_data_block; } while (i != goal); return EXT2_ET_BLOCK_ALLOC_FAIL; }