* e2fsck can request an encoding which is optimized for that.
*/
-static void warn_bitmap(ext2fs_generic_bitmap bitmap,
+static void warn_bitmap(ext2fs_generic_bitmap_64 bitmap,
int code, __u64 arg)
{
#ifndef OMIT_COM_ERR
if (bitmap->description)
com_err(0, bitmap->base_error_code+code,
- "#%llu for %s", arg, bitmap->description);
+ "#%llu for %s", (unsigned long long) arg,
+ bitmap->description);
else
- com_err(0, bitmap->base_error_code + code, "#%llu", arg);
+ com_err(0, bitmap->base_error_code + code, "#%llu",
+ (unsigned long long) arg);
#endif
}
const char *descr,
ext2fs_generic_bitmap *ret)
{
- ext2fs_generic_bitmap bitmap;
+ ext2fs_generic_bitmap_64 bitmap;
struct ext2_bitmap_ops *ops;
ext2_ino_t num_dirs;
errcode_t retval;
return EINVAL;
}
- retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap),
+ retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap_64),
&bitmap);
if (retval)
return retval;
if (gettimeofday(&bitmap->stats.created,
(struct timezone *) NULL) == -1) {
perror("gettimeofday");
+ ext2fs_free_mem(&bitmap);
return 1;
}
bitmap->stats.type = type;
return retval;
}
- *ret = bitmap;
+ *ret = (ext2fs_generic_bitmap) bitmap;
return 0;
}
#ifdef ENABLE_BMAP_STATS
-void ext2fs_print_bmap_statistics(ext2fs_generic_bitmap bitmap)
+static void ext2fs_print_bmap_statistics(ext2fs_generic_bitmap_64 bitmap)
{
struct ext2_bmap_statistics *stats = &bitmap->stats;
#ifdef ENABLE_BMAP_STATS_OPS
}
#endif
-void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap)
+void ext2fs_free_generic_bmap(ext2fs_generic_bitmap gen_bmap)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+
if (!bmap)
return;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- ext2fs_free_generic_bitmap(bmap);
+ ext2fs_free_generic_bitmap(gen_bmap);
return;
}
ext2fs_free_mem(&bmap);
}
-errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
+errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap gen_src,
ext2fs_generic_bitmap *dest)
{
+ ext2fs_generic_bitmap_64 src = (ext2fs_generic_bitmap_64) gen_src;
char *descr, *new_descr;
- ext2fs_generic_bitmap new_bmap;
+ ext2fs_generic_bitmap_64 new_bmap;
errcode_t retval;
if (!src)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(src))
- return ext2fs_copy_generic_bitmap(src, dest);
+ return ext2fs_copy_generic_bitmap(gen_src, dest);
if (!EXT2FS_IS_64_BITMAP(src))
return EINVAL;
/* Allocate a new bitmap struct */
- retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap),
+ retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap_64),
&new_bmap);
if (retval)
return retval;
if (gettimeofday(&new_bmap->stats.created,
(struct timezone *) NULL) == -1) {
perror("gettimeofday");
+ ext2fs_free_mem(&new_bmap);
return 1;
}
new_bmap->stats.type = src->stats.type;
return retval;
}
- *dest = new_bmap;
+ *dest = (ext2fs_generic_bitmap) new_bmap;
return 0;
}
-errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap gen_bmap,
__u64 new_end,
__u64 new_real_end)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+
if (!bmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bmap))
- return ext2fs_resize_generic_bitmap(bmap->magic, new_end,
- new_real_end, bmap);
+ return ext2fs_resize_generic_bitmap(gen_bmap->magic, new_end,
+ new_real_end, gen_bmap);
if (!EXT2FS_IS_64_BITMAP(bmap))
return EINVAL;
return bmap->bitmap_ops->resize_bmap(bmap, new_end, new_real_end);
}
-errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
+errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap gen_bitmap,
errcode_t neq,
__u64 end, __u64 *oend)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return EINVAL;
ext2_ino_t tmp_oend;
int retval;
- retval = ext2fs_fudge_generic_bitmap_end(bitmap, bitmap->magic,
+ retval = ext2fs_fudge_generic_bitmap_end(gen_bitmap,
+ bitmap->magic,
neq, end, &tmp_oend);
if (oend)
*oend = tmp_oend;
return 0;
}
-__u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap bitmap)
+__u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap gen_bitmap)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bitmap))
- return ext2fs_get_generic_bitmap_start(bitmap);
+ return ext2fs_get_generic_bitmap_start(gen_bitmap);
if (!EXT2FS_IS_64_BITMAP(bitmap))
return EINVAL;
return bitmap->start;
}
-__u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap bitmap)
+__u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap gen_bitmap)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bitmap))
- return ext2fs_get_generic_bitmap_end(bitmap);
+ return ext2fs_get_generic_bitmap_end(gen_bitmap);
if (!EXT2FS_IS_64_BITMAP(bitmap))
return EINVAL;
return bitmap->end;
}
-void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap)
+void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap gen_bitmap)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (EXT2FS_IS_32_BITMAP(bitmap))
- ext2fs_clear_generic_bitmap(bitmap);
+ ext2fs_clear_generic_bitmap(gen_bitmap);
else
- bitmap->bitmap_ops->clear_bmap (bitmap);
+ bitmap->bitmap_ops->clear_bmap(bitmap);
}
-int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
+int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap gen_bitmap,
__u64 arg)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return 0;
if (EXT2FS_IS_32_BITMAP(bitmap)) {
if (arg & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bitmap,
+ ext2fs_warn_bitmap2(gen_bitmap,
EXT2FS_MARK_ERROR, 0xffffffff);
return 0;
}
- return ext2fs_mark_generic_bitmap(bitmap, arg);
+ return ext2fs_mark_generic_bitmap(gen_bitmap, arg);
}
if (!EXT2FS_IS_64_BITMAP(bitmap))
return bitmap->bitmap_ops->mark_bmap(bitmap, arg);
}
-int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
+int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap gen_bitmap,
__u64 arg)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
if (!bitmap)
return 0;
if (EXT2FS_IS_32_BITMAP(bitmap)) {
if (arg & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR,
+ ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_UNMARK_ERROR,
0xffffffff);
return 0;
}
- return ext2fs_unmark_generic_bitmap(bitmap, arg);
+ return ext2fs_unmark_generic_bitmap(gen_bitmap, arg);
}
if (!EXT2FS_IS_64_BITMAP(bitmap))
return bitmap->bitmap_ops->unmark_bmap(bitmap, arg);
}
-int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
+int ext2fs_test_generic_bmap(ext2fs_generic_bitmap gen_bitmap,
__u64 arg)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
if (!bitmap)
return 0;
if (EXT2FS_IS_32_BITMAP(bitmap)) {
if (arg & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR,
+ ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR,
0xffffffff);
return 0;
}
- return ext2fs_test_generic_bitmap(bitmap, arg);
+ return ext2fs_test_generic_bitmap(gen_bitmap, arg);
}
if (!EXT2FS_IS_64_BITMAP(bitmap))
return bitmap->bitmap_ops->test_bmap(bitmap, arg);
}
-errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap gen_bmap,
__u64 start, unsigned int num,
void *in)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+
if (!bmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bmap)) {
if ((start+num-1) & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR,
+ ext2fs_warn_bitmap2(gen_bmap, EXT2FS_UNMARK_ERROR,
0xffffffff);
return EINVAL;
}
- return ext2fs_set_generic_bitmap_range(bmap, bmap->magic,
+ return ext2fs_set_generic_bitmap_range(gen_bmap, bmap->magic,
start, num, in);
}
return bmap->bitmap_ops->set_bmap_range(bmap, start, num, in);
}
-errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap gen_bmap,
__u64 start, unsigned int num,
void *out)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+
if (!bmap)
return EINVAL;
if (EXT2FS_IS_32_BITMAP(bmap)) {
if ((start+num-1) & ~0xffffffffULL) {
- ext2fs_warn_bitmap2(bmap,
+ ext2fs_warn_bitmap2(gen_bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return EINVAL;
}
- return ext2fs_get_generic_bitmap_range(bmap, bmap->magic,
+ return ext2fs_get_generic_bitmap_range(gen_bmap, bmap->magic,
start, num, out);
}
}
errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
- ext2fs_generic_bitmap bm1,
- ext2fs_generic_bitmap bm2)
+ ext2fs_generic_bitmap gen_bm1,
+ ext2fs_generic_bitmap gen_bm2)
{
+ ext2fs_generic_bitmap_64 bm1 = (ext2fs_generic_bitmap_64) gen_bm1;
+ ext2fs_generic_bitmap_64 bm2 = (ext2fs_generic_bitmap_64) gen_bm2;
blk64_t i;
if (!bm1 || !bm2)
/* Now we know both bitmaps have the same magic */
if (EXT2FS_IS_32_BITMAP(bm1))
- return ext2fs_compare_generic_bitmap(bm1->magic, neq, bm1, bm2);
+ return ext2fs_compare_generic_bitmap(bm1->magic, neq,
+ gen_bm1, gen_bm2);
if (!EXT2FS_IS_64_BITMAP(bm1))
return EINVAL;
return neq;
for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
- if (ext2fs_test_generic_bmap(bm1, i) !=
- ext2fs_test_generic_bmap(bm2, i))
+ if (ext2fs_test_generic_bmap(gen_bm1, i) !=
+ ext2fs_test_generic_bmap(gen_bm2, i))
return neq;
return 0;
}
-void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap)
+void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap gen_bmap)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
__u64 start, num;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- ext2fs_set_generic_bitmap_padding(bmap);
+ ext2fs_set_generic_bitmap_padding(gen_bmap);
return;
}
/* XXX ought to warn on error */
}
-int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap,
+int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap gen_bmap,
blk64_t block, unsigned int num)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
__u64 end = block + num;
if (!bmap)
bmap, block);
if (EXT2FS_IS_32_BITMAP(bmap)) {
- if ((block+num-1) & ~0xffffffffULL) {
+ if ((block & ~0xffffffffULL) ||
+ ((block+num-1) & ~0xffffffffULL)) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return EINVAL;
/* convert to clusters if necessary */
block >>= bmap->cluster_bits;
- end += (1 << bmap->cluster_bits) - 1;
+ end += (1ULL << bmap->cluster_bits) - 1;
end >>= bmap->cluster_bits;
num = end - block;
- if ((block < bmap->start) || (block+num-1 > bmap->end)) {
+ if ((block < bmap->start) || (block > bmap->end) ||
+ (block+num-1 > bmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, block,
bmap->description);
return EINVAL;
return bmap->bitmap_ops->test_clear_bmap_extent(bmap, block, num);
}
-void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap,
+void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap gen_bmap,
blk64_t block, unsigned int num)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
__u64 end = block + num;
if (!bmap)
return;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- if ((block+num-1) & ~0xffffffffULL) {
+ if ((block & ~0xffffffffULL) ||
+ ((block+num-1) & ~0xffffffffULL)) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return;
/* convert to clusters if necessary */
block >>= bmap->cluster_bits;
- end += (1 << bmap->cluster_bits) - 1;
+ end += (1ULL << bmap->cluster_bits) - 1;
end >>= bmap->cluster_bits;
num = end - block;
- if ((block < bmap->start) || (block+num-1 > bmap->end)) {
+ if ((block < bmap->start) || (block > bmap->end) ||
+ (block+num-1 > bmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
bmap->description);
return;
bmap->bitmap_ops->mark_bmap_extent(bmap, block, num);
}
-void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap,
+void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap gen_bmap,
blk64_t block, unsigned int num)
{
+ ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) gen_bmap;
__u64 end = block + num;
if (!bmap)
return;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- if ((block+num-1) & ~0xffffffffULL) {
+ if ((block & ~0xffffffffULL) ||
+ ((block+num-1) & ~0xffffffffULL)) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return;
/* convert to clusters if necessary */
block >>= bmap->cluster_bits;
- end += (1 << bmap->cluster_bits) - 1;
+ end += (1ULL << bmap->cluster_bits) - 1;
end >>= bmap->cluster_bits;
num = end - block;
- if ((block < bmap->start) || (block+num-1 > bmap->end)) {
+ if ((block < bmap->start) || (block > bmap->end) ||
+ (block+num-1 > bmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
bmap->description);
return;
bmap->bitmap_ops->unmark_bmap_extent(bmap, block, num);
}
-void ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func)
+void ext2fs_warn_bitmap32(ext2fs_generic_bitmap gen_bitmap, const char *func)
{
+ ext2fs_generic_bitmap_64 bitmap = (ext2fs_generic_bitmap_64) gen_bitmap;
+
#ifndef OMIT_COM_ERR
if (bitmap && bitmap->description)
com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
ext2fs_block_bitmap *bitmap)
{
- ext2fs_block_bitmap cmap, bmap;
+ ext2fs_generic_bitmap_64 bmap, cmap;
+ ext2fs_block_bitmap gen_bmap = *bitmap, gen_cmap;
errcode_t retval;
- blk64_t i, b_end, c_end;
- int n, ratio;
+ blk64_t i, next, b_end, c_end;
- bmap = *bitmap;
-
- if (fs->cluster_ratio_bits == ext2fs_get_bitmap_granularity(bmap))
+ bmap = (ext2fs_generic_bitmap_64) gen_bmap;
+ if (fs->cluster_ratio_bits == ext2fs_get_bitmap_granularity(gen_bmap))
return 0; /* Nothing to do */
retval = ext2fs_allocate_block_bitmap(fs, "converted cluster bitmap",
- &cmap);
+ &gen_cmap);
if (retval)
return retval;
+ cmap = (ext2fs_generic_bitmap_64) gen_cmap;
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;
+ retval = ext2fs_find_first_set_block_bitmap2(gen_bmap,
+ i, bmap->real_end, &next);
+ if (retval)
+ break;
+ ext2fs_mark_block_bitmap2(gen_cmap, next);
+ i = EXT2FS_C2B(fs, EXT2FS_B2C(fs, next) + 1);
}
bmap->end = b_end;
cmap->end = c_end;
- ext2fs_free_block_bitmap(bmap);
- *bitmap = cmap;
+ ext2fs_free_block_bitmap(gen_bmap);
+ *bitmap = (ext2fs_block_bitmap) cmap;
return 0;
}
errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
__u64 start, __u64 end, __u64 *out)
{
- int b;
+ ext2fs_generic_bitmap_64 bmap64 = (ext2fs_generic_bitmap_64) bitmap;
+ __u64 cstart, cend, cout;
+ errcode_t retval;
if (!bitmap)
return EINVAL;
- if (EXT2FS_IS_64_BITMAP(bitmap) && bitmap->bitmap_ops->find_first_zero)
- return bitmap->bitmap_ops->find_first_zero(bitmap, start,
- end, out);
-
if (EXT2FS_IS_32_BITMAP(bitmap)) {
blk_t blk = 0;
- errcode_t retval;
if (((start) & ~0xffffffffULL) ||
((end) & ~0xffffffffULL)) {
if (!EXT2FS_IS_64_BITMAP(bitmap))
return EINVAL;
- start >>= bitmap->cluster_bits;
- end >>= bitmap->cluster_bits;
+ cstart = start >> bmap64->cluster_bits;
+ cend = end >> bmap64->cluster_bits;
- if (start < bitmap->start || end > bitmap->end || start > end) {
- warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
+ if (cstart < bmap64->start || cend > bmap64->end || start > end) {
+ warn_bitmap(bmap64, EXT2FS_TEST_ERROR, start);
return EINVAL;
}
- while (start <= end) {
- b = bitmap->bitmap_ops->test_bmap(bitmap, start);
- if (!b) {
- *out = start << bitmap->cluster_bits;
- return 0;
+ if (bmap64->bitmap_ops->find_first_zero) {
+ retval = bmap64->bitmap_ops->find_first_zero(bmap64, cstart,
+ cend, &cout);
+ if (retval)
+ return retval;
+ found:
+ cout <<= bmap64->cluster_bits;
+ *out = (cout >= start) ? cout : start;
+ return 0;
+ }
+
+ for (cout = cstart; cout <= cend; cout++)
+ if (!bmap64->bitmap_ops->test_bmap(bmap64, cout))
+ goto found;
+
+ return ENOENT;
+}
+
+errcode_t ext2fs_find_first_set_generic_bmap(ext2fs_generic_bitmap bitmap,
+ __u64 start, __u64 end, __u64 *out)
+{
+ ext2fs_generic_bitmap_64 bmap64 = (ext2fs_generic_bitmap_64) bitmap;
+ __u64 cstart, cend, cout;
+ errcode_t retval;
+
+ if (!bitmap)
+ return EINVAL;
+
+ if (EXT2FS_IS_32_BITMAP(bitmap)) {
+ blk_t blk = 0;
+
+ if (((start) & ~0xffffffffULL) ||
+ ((end) & ~0xffffffffULL)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
+ return EINVAL;
}
- start++;
+
+ retval = ext2fs_find_first_set_generic_bitmap(bitmap, start,
+ end, &blk);
+ if (retval == 0)
+ *out = blk;
+ return retval;
}
+ if (!EXT2FS_IS_64_BITMAP(bitmap))
+ return EINVAL;
+
+ cstart = start >> bmap64->cluster_bits;
+ cend = end >> bmap64->cluster_bits;
+
+ if (cstart < bmap64->start || cend > bmap64->end || start > end) {
+ warn_bitmap(bmap64, EXT2FS_TEST_ERROR, start);
+ return EINVAL;
+ }
+
+ if (bmap64->bitmap_ops->find_first_set) {
+ retval = bmap64->bitmap_ops->find_first_set(bmap64, cstart,
+ cend, &cout);
+ if (retval)
+ return retval;
+ found:
+ cout <<= bmap64->cluster_bits;
+ *out = (cout >= start) ? cout : start;
+ return 0;
+ }
+
+ for (cout = cstart; cout <= cend; cout++)
+ if (bmap64->bitmap_ops->test_bmap(bmap64, cout))
+ goto found;
+
return ENOENT;
}
+
+errcode_t ext2fs_count_used_clusters(ext2_filsys fs, blk64_t start,
+ blk64_t end, blk64_t *out)
+{
+ blk64_t next;
+ blk64_t tot_set = 0;
+ errcode_t retval = 0;
+
+ while (start < end) {
+ retval = ext2fs_find_first_set_block_bitmap2(fs->block_map,
+ start, end, &next);
+ if (retval) {
+ if (retval == ENOENT)
+ retval = 0;
+ break;
+ }
+ start = next;
+
+ retval = ext2fs_find_first_zero_block_bitmap2(fs->block_map,
+ start, end, &next);
+ if (retval == 0) {
+ tot_set += next - start;
+ start = next + 1;
+ } else if (retval == ENOENT) {
+ retval = 0;
+ tot_set += end - start + 1;
+ break;
+ } else
+ break;
+ }
+
+ if (!retval)
+ *out = EXT2FS_NUM_B2C(fs, tot_set);
+ return retval;
+}