X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lib%2Fext2fs%2Fgen_bitmap64.c;h=fa8d7b7520be201c9d19de3ca577a44785fa4e56;hb=7270fbe7fa51cbce01a07d031f03872f314206d1;hp=80c9f7a0a62079bef8f50d012b349d572081dae8;hpb=9c79612f2186a8ee5d8a6f2c961e4e0f63df7228;p=tools%2Fe2fsprogs.git diff --git a/lib/ext2fs/gen_bitmap64.c b/lib/ext2fs/gen_bitmap64.c index 80c9f7a..fa8d7b7 100644 --- a/lib/ext2fs/gen_bitmap64.c +++ b/lib/ext2fs/gen_bitmap64.c @@ -10,6 +10,7 @@ * %End-Header% */ +#include "config.h" #include #include #if HAVE_UNISTD_H @@ -24,6 +25,9 @@ #if HAVE_SYS_TYPES_H #include #endif +#ifdef HAVE_SYS_TIME_H +#include +#endif #include "ext2_fs.h" #include "ext2fsP.h" @@ -76,6 +80,12 @@ static void warn_bitmap(ext2fs_generic_bitmap bitmap, #endif } +#ifdef BMAP_STATS_OPS +#define INC_STAT(map, name) map->stats.name +#else +#define INC_STAT(map, name) ;; +#endif + errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic, int type, __u64 start, __u64 end, @@ -85,21 +95,44 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic, { ext2fs_generic_bitmap bitmap; struct ext2_bitmap_ops *ops; + ext2_ino_t num_dirs; errcode_t retval; + if (!type) + type = EXT2FS_BMAP64_BITARRAY; + switch (type) { case EXT2FS_BMAP64_BITARRAY: ops = &ext2fs_blkmap64_bitarray; break; + case EXT2FS_BMAP64_RBTREE: + ops = &ext2fs_blkmap64_rbtree; + break; + case EXT2FS_BMAP64_AUTODIR: + retval = ext2fs_get_num_dirs(fs, &num_dirs); + if (retval || num_dirs > (fs->super->s_inodes_count / 320)) + ops = &ext2fs_blkmap64_bitarray; + else + ops = &ext2fs_blkmap64_rbtree; + break; default: return EINVAL; } - retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap), - &bitmap); + retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap), + &bitmap); if (retval) return retval; +#ifdef BMAP_STATS + if (gettimeofday(&bitmap->stats.created, + (struct timezone *) NULL) == -1) { + perror("gettimeofday"); + return 1; + } + bitmap->stats.type = type; +#endif + /* XXX factor out, repeated in copy_bmap */ bitmap->magic = magic; bitmap->fs = fs; @@ -140,6 +173,71 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic, return 0; } +#ifdef BMAP_STATS +void ext2fs_print_bmap_statistics(ext2fs_generic_bitmap bitmap) +{ + struct ext2_bmap_statistics *stats = &bitmap->stats; + float mark_seq_perc = 0.0, test_seq_perc = 0.0; + float mark_back_perc = 0.0, test_back_perc = 0.0; + double inuse; + struct timeval now; + +#ifdef BMAP_STATS_OPS + if (stats->test_count) { + test_seq_perc = ((float)stats->test_seq / + stats->test_count) * 100; + test_back_perc = ((float)stats->test_back / + stats->test_count) * 100; + } + + if (stats->mark_count) { + mark_seq_perc = ((float)stats->mark_seq / + stats->mark_count) * 100; + mark_back_perc = ((float)stats->mark_back / + stats->mark_count) * 100; + } +#endif + + if (gettimeofday(&now, (struct timezone *) NULL) == -1) { + perror("gettimeofday"); + return; + } + + inuse = (double) now.tv_sec + \ + (((double) now.tv_usec) * 0.000001); + inuse -= (double) stats->created.tv_sec + \ + (((double) stats->created.tv_usec) * 0.000001); + + fprintf(stderr, "\n[+] %s bitmap (type %d)\n", bitmap->description, + stats->type); + fprintf(stderr, "=================================================\n"); +#ifdef BMAP_STATS_OPS + fprintf(stderr, "%16llu bits long\n", + bitmap->real_end - bitmap->start); + fprintf(stderr, "%16lu copy_bmap\n%16lu resize_bmap\n", + stats->copy_count, stats->resize_count); + fprintf(stderr, "%16lu mark bmap\n%16lu unmark_bmap\n", + stats->mark_count, stats->unmark_count); + fprintf(stderr, "%16lu test_bmap\n%16lu mark_bmap_extent\n", + stats->test_count, stats->mark_ext_count); + fprintf(stderr, "%16lu unmark_bmap_extent\n" + "%16lu test_clear_bmap_extent\n", + stats->unmark_ext_count, stats->test_ext_count); + fprintf(stderr, "%16lu set_bmap_range\n%16lu set_bmap_range\n", + stats->set_range_count, stats->get_range_count); + fprintf(stderr, "%16lu clear_bmap\n%16lu contiguous bit test (%.2f%%)\n", + stats->clear_count, stats->test_seq, test_seq_perc); + fprintf(stderr, "%16lu contiguous bit mark (%.2f%%)\n" + "%16llu bits tested backwards (%.2f%%)\n", + stats->mark_seq, mark_seq_perc, + stats->test_back, test_back_perc); + fprintf(stderr, "%16llu bits marked backwards (%.2f%%)\n" + "%16.2f seconds in use\n", + stats->mark_back, mark_back_perc, inuse); +#endif /* BMAP_STATS_OPS */ +} +#endif + void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap) { if (!bmap) @@ -153,6 +251,13 @@ void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap) if (!EXT2FS_IS_64_BITMAP(bmap)) return; +#ifdef BMAP_STATS + if (getenv("E2FSPROGS_BITMAP_STATS")) { + ext2fs_print_bmap_statistics(bmap); + bmap->bitmap_ops->print_stats(bmap); + } +#endif + bmap->bitmap_ops->free_bmap(bmap); if (bmap->description) { @@ -180,11 +285,24 @@ errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src, return EINVAL; /* Allocate a new bitmap struct */ - retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap), - &new_bmap); + retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap), + &new_bmap); if (retval) return retval; + +#ifdef BMAP_STATS_OPS + src->stats.copy_count++; +#endif +#ifdef BMAP_STATS + if (gettimeofday(&new_bmap->stats.created, + (struct timezone *) NULL) == -1) { + perror("gettimeofday"); + return 1; + } + new_bmap->stats.type = src->stats.type; +#endif + /* Copy all the high-level parts over */ new_bmap->magic = src->magic; new_bmap->fs = src->fs; @@ -197,12 +315,12 @@ errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src, descr = src->description; if (descr) { - retval = ext2fs_get_mem(strlen(descr)+1, &new_descr); + retval = ext2fs_get_mem(strlen(descr)+10, &new_descr); if (retval) { ext2fs_free_mem(&new_bmap); return retval; } - strcpy(new_descr, descr); + sprintf(new_descr, "copy of %s", descr); new_bmap->description = new_descr; } @@ -232,6 +350,8 @@ errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap, if (!EXT2FS_IS_64_BITMAP(bmap)) return EINVAL; + INC_STAT(bmap, resize_count); + return bmap->bitmap_ops->resize_bmap(bmap, new_end, new_real_end); } @@ -296,8 +416,8 @@ void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap) { if (EXT2FS_IS_32_BITMAP(bitmap)) ext2fs_clear_generic_bitmap(bitmap); - - bitmap->bitmap_ops->clear_bmap (bitmap); + else + bitmap->bitmap_ops->clear_bmap (bitmap); } int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap, @@ -320,6 +440,15 @@ int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap, arg >>= bitmap->cluster_bits; +#ifdef BMAP_STATS_OPS + if (arg == bitmap->stats.last_marked + 1) + bitmap->stats.mark_seq++; + if (arg < bitmap->stats.last_marked) + bitmap->stats.mark_back++; + bitmap->stats.last_marked = arg; + bitmap->stats.mark_count++; +#endif + if ((arg < bitmap->start) || (arg > bitmap->end)) { warn_bitmap(bitmap, EXT2FS_MARK_ERROR, arg); return 0; @@ -348,6 +477,8 @@ int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap, arg >>= bitmap->cluster_bits; + INC_STAT(bitmap, unmark_count); + if ((arg < bitmap->start) || (arg > bitmap->end)) { warn_bitmap(bitmap, EXT2FS_UNMARK_ERROR, arg); return 0; @@ -376,6 +507,15 @@ int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap, arg >>= bitmap->cluster_bits; +#ifdef BMAP_STATS_OPS + bitmap->stats.test_count++; + if (arg == bitmap->stats.last_tested + 1) + bitmap->stats.test_seq++; + if (arg < bitmap->stats.last_tested) + bitmap->stats.test_back++; + bitmap->stats.last_tested = arg; +#endif + if ((arg < bitmap->start) || (arg > bitmap->end)) { warn_bitmap(bitmap, EXT2FS_TEST_ERROR, arg); return 0; @@ -392,7 +532,7 @@ errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap, return EINVAL; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((start+num) & ~0xffffffffULL) { + if ((start+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return EINVAL; @@ -404,6 +544,8 @@ errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap, if (!EXT2FS_IS_64_BITMAP(bmap)) return EINVAL; + INC_STAT(bmap, set_range_count); + return bmap->bitmap_ops->set_bmap_range(bmap, start, num, in); } @@ -415,7 +557,7 @@ errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap, return EINVAL; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((start+num) & ~0xffffffffULL) { + if ((start+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return EINVAL; @@ -427,6 +569,8 @@ errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap, if (!EXT2FS_IS_64_BITMAP(bmap)) return EINVAL; + INC_STAT(bmap, get_range_count); + return bmap->bitmap_ops->get_bmap_range(bmap, start, num, out); } @@ -486,7 +630,7 @@ int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap, bmap, block); if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((block+num) & ~0xffffffffULL) { + if ((block+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return EINVAL; @@ -498,6 +642,8 @@ int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap, if (!EXT2FS_IS_64_BITMAP(bmap)) return EINVAL; + INC_STAT(bmap, test_ext_count); + return bmap->bitmap_ops->test_clear_bmap_extent(bmap, block, num); } @@ -508,7 +654,7 @@ void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap, return; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((block+num) & ~0xffffffffULL) { + if ((block+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return; @@ -520,6 +666,8 @@ void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap, if (!EXT2FS_IS_64_BITMAP(bmap)) return; + INC_STAT(bmap, mark_ext_count); + if ((block < bmap->start) || (block+num-1 > bmap->end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, bmap->description); @@ -536,7 +684,7 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap, return; if (EXT2FS_IS_32_BITMAP(bmap)) { - if ((block+num) & ~0xffffffffULL) { + if ((block+num-1) & ~0xffffffffULL) { ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap, EXT2FS_UNMARK_ERROR, 0xffffffff); return; @@ -548,6 +696,8 @@ void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap, if (!EXT2FS_IS_64_BITMAP(bmap)) return; + INC_STAT(bmap, unmark_ext_count); + if ((block < bmap->start) || (block+num-1 > bmap->end)) { ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block, bmap->description);