* Copyright (C) 2001 Theodore Ts'o.
*
* %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
* %End-Header%
*/
+#include "config.h"
#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
#include "ext2_fs.h"
#include "ext2fsP.h"
-struct ext2fs_struct_generic_bitmap {
+struct ext2fs_struct_generic_bitmap_32 {
errcode_t magic;
ext2_filsys fs;
__u32 start, end;
__u32 reserved[7];
};
+typedef struct ext2fs_struct_generic_bitmap_32 *ext2fs_generic_bitmap_32;
+
+#define EXT2FS_IS_32_BITMAP(bmap) \
+ (((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
+ ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
+ ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP))
+
+#define EXT2FS_IS_64_BITMAP(bmap) \
+ (((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP64) || \
+ ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP64) || \
+ ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP64))
+
/*
* Used by previously inlined function, so we have to export this and
* not change the function signature
*/
-void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+void ext2fs_warn_bitmap2(ext2fs_generic_bitmap gen_bitmap,
int code, unsigned long arg)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
#ifndef OMIT_COM_ERR
if (bitmap->description)
com_err(0, bitmap->base_error_code+code,
const char *descr, char *init_map,
ext2fs_generic_bitmap *ret)
{
- ext2fs_generic_bitmap bitmap;
+ ext2fs_generic_bitmap_32 bitmap;
errcode_t retval;
size_t size;
- retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap),
+ retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap_32),
&bitmap);
if (retval)
return retval;
memcpy(bitmap->bitmap, init_map, size);
else
memset(bitmap->bitmap, 0, size);
- *ret = bitmap;
+ *ret = (ext2fs_generic_bitmap) bitmap;
return 0;
}
start, end, real_end, descr, 0, ret);
}
-errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,
+errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap gen_src,
ext2fs_generic_bitmap *dest)
{
+ ext2fs_generic_bitmap_32 src = (ext2fs_generic_bitmap_32) gen_src;
+
return (ext2fs_make_generic_bitmap(src->magic, src->fs,
src->start, src->end,
src->real_end,
dest));
}
-void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
+void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap gen_bitmap)
{
- if (check_magic(bitmap))
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
+ if (check_magic(gen_bitmap))
return;
bitmap->magic = 0;
int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
blk_t bitno)
{
- if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
+ if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+ if (EXT2FS_IS_64_BITMAP(bitmap)) {
+ ext2fs_warn_bitmap32(bitmap, __func__);
+ return ext2fs_test_generic_bmap(bitmap, bitno);
+ }
+#ifndef OMIT_COM_ERR
+ com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+ "test_bitmap(%lu)", (unsigned long) bitno);
+#endif
+ return 0;
+ }
+
+ if ((bitno < bitmap32->start) || (bitno > bitmap32->end)) {
ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
return 0;
}
- return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
+ return ext2fs_test_bit(bitno - bitmap32->start, bitmap32->bitmap);
}
int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
__u32 bitno)
{
- if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
+ if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+ if (EXT2FS_IS_64_BITMAP(bitmap)) {
+ ext2fs_warn_bitmap32(bitmap, __func__);
+ return ext2fs_mark_generic_bmap(bitmap, bitno);
+ }
+#ifndef OMIT_COM_ERR
+ com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+ "mark_bitmap(%lu)", (unsigned long) bitno);
+#endif
+ return 0;
+ }
+
+ if ((bitno < bitmap32->start) || (bitno > bitmap32->end)) {
ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
return 0;
}
- return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
+ return ext2fs_set_bit(bitno - bitmap32->start, bitmap32->bitmap);
}
int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
blk_t bitno)
{
- if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
+ if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+ if (EXT2FS_IS_64_BITMAP(bitmap)) {
+ ext2fs_warn_bitmap32(bitmap, __func__);
+ return ext2fs_unmark_generic_bmap(bitmap, bitno);
+ }
+#ifndef OMIT_COM_ERR
+ com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+ "mark_bitmap(%lu)", (unsigned long) bitno);
+#endif
+ return 0;
+ }
+
+ if ((bitno < bitmap32->start) || (bitno > bitmap32->end)) {
ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
return 0;
}
- return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
+ return ext2fs_clear_bit(bitno - bitmap32->start, bitmap32->bitmap);
}
__u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)
{
- return bitmap->start;
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
+ if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+ if (EXT2FS_IS_64_BITMAP(bitmap)) {
+ ext2fs_warn_bitmap32(bitmap, __func__);
+ return ext2fs_get_generic_bmap_start(bitmap);
+ }
+#ifndef OMIT_COM_ERR
+ com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+ "get_bitmap_start");
+#endif
+ return 0;
+ }
+
+ return bitmap32->start;
}
__u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)
{
- return bitmap->end;
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
+ if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+ if (EXT2FS_IS_64_BITMAP(bitmap)) {
+ ext2fs_warn_bitmap32(bitmap, __func__);
+ return ext2fs_get_generic_bmap_end(bitmap);
+ }
+#ifndef OMIT_COM_ERR
+ com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+ "get_bitmap_end");
+#endif
+ return 0;
+ }
+ return bitmap32->end;
}
void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)
{
- if (check_magic(bitmap))
+ ext2fs_generic_bitmap_32 bitmap32 = (ext2fs_generic_bitmap_32) bitmap;
+
+ if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+ if (EXT2FS_IS_64_BITMAP(bitmap)) {
+ ext2fs_warn_bitmap32(bitmap, __func__);
+ ext2fs_clear_generic_bmap(bitmap);
+ return;
+ }
+#ifndef OMIT_COM_ERR
+ com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+ "clear_generic_bitmap");
+#endif
return;
+ }
- memset(bitmap->bitmap, 0,
- (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
+ memset(bitmap32->bitmap, 0,
+ (size_t) (((bitmap32->real_end - bitmap32->start) / 8) + 1));
}
-errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
+errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap gen_bitmap,
errcode_t magic, errcode_t neq,
ext2_ino_t end, ext2_ino_t *oend)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
EXT2_CHECK_MAGIC(bitmap, magic);
if (end > bitmap->real_end)
errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
__u32 new_end, __u32 new_real_end,
- ext2fs_generic_bitmap bmap)
+ ext2fs_generic_bitmap gen_bmap)
{
+ ext2fs_generic_bitmap_32 bmap = (ext2fs_generic_bitmap_32) gen_bmap;
errcode_t retval;
size_t size, new_size;
__u32 bitno;
}
errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
- ext2fs_generic_bitmap bm1,
- ext2fs_generic_bitmap bm2)
+ ext2fs_generic_bitmap gen_bm1,
+ ext2fs_generic_bitmap gen_bm2)
{
+ ext2fs_generic_bitmap_32 bm1 = (ext2fs_generic_bitmap_32) gen_bm1;
+ ext2fs_generic_bitmap_32 bm2 = (ext2fs_generic_bitmap_32) gen_bm2;
blk_t i;
if (!bm1 || bm1->magic != magic)
return neq;
for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
- if (ext2fs_fast_test_block_bitmap(bm1, i) !=
- ext2fs_fast_test_block_bitmap(bm2, i))
+ if (ext2fs_fast_test_block_bitmap(gen_bm1, i) !=
+ ext2fs_fast_test_block_bitmap(gen_bm2, i))
return neq;
return 0;
}
-void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map)
+void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap gen_map)
{
+ ext2fs_generic_bitmap_32 map = (ext2fs_generic_bitmap_32) gen_map;
__u32 i, j;
/* Protect loop from wrap-around if map->real_end is maxed */
ext2fs_set_bit(j, map->bitmap);
}
-errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap gen_bmap,
errcode_t magic,
__u32 start, __u32 num,
void *out)
{
+ ext2fs_generic_bitmap_32 bmap = (ext2fs_generic_bitmap_32) gen_bmap;
+
if (!bmap || (bmap->magic != magic))
return magic;
return 0;
}
-errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap,
+errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap gen_bmap,
errcode_t magic,
__u32 start, __u32 num,
void *in)
{
+ ext2fs_generic_bitmap_32 bmap = (ext2fs_generic_bitmap_32) gen_bmap;
+
if (!bmap || (bmap->magic != magic))
return magic;
/*
* Return true if all of the bits in a specified range are clear
*/
-static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap bitmap,
+static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap gen_bitmap,
unsigned int start,
unsigned int len)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
size_t start_byte, len_byte = len >> 3;
unsigned int start_bit, len_bit = len % 8;
int first_bit = 0;
return ext2fs_mem_is_zero(ADDR + start_byte, len_byte);
}
-int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap gen_bitmap,
+ __u32 start, __u32 end,
+ __u32 *out)
+{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+ blk_t b;
+
+ if (start < bitmap->start || end > bitmap->end || start > end) {
+ ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR, start);
+ return EINVAL;
+ }
+
+ while (start <= end) {
+ b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap);
+ if (!b) {
+ *out = start;
+ return 0;
+ }
+ start++;
+ }
+
+ return ENOENT;
+}
+
+errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap gen_bitmap,
+ __u32 start, __u32 end,
+ __u32 *out)
+{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+ blk_t b;
+
+ if (start < bitmap->start || end > bitmap->end || start > end) {
+ ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR, start);
+ return EINVAL;
+ }
+
+ while (start <= end) {
+ b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap);
+ if (b) {
+ *out = start;
+ return 0;
+ }
+ start++;
+ }
+
+ return ENOENT;
+}
+
+int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap gen_bitmap,
blk_t block, int num)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
- if ((block < bitmap->start) || (block+num-1 > bitmap->real_end)) {
+ if ((block < bitmap->start) || (block > bitmap->real_end) ||
+ (block+num-1 > bitmap->real_end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
block, bitmap->description);
return 0;
bitmap, block, num);
}
-int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
- ino_t inode, int num)
+int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap gen_bitmap,
+ ext2_ino_t inode, int num)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
+
EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
- if ((inode < bitmap->start) || (inode+num-1 > bitmap->real_end)) {
+ if ((inode < bitmap->start) || (inode > bitmap->real_end) ||
+ (inode+num-1 > bitmap->real_end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
inode, bitmap->description);
return 0;
bitmap, inode, num);
}
-void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap gen_bitmap,
blk_t block, int num)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
int i;
- if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ if ((block < bitmap->start) || (block > bitmap->end) ||
+ (block+num-1 > bitmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
bitmap->description);
return;
ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
}
-void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
- blk_t block, int num)
+void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap gen_bitmap,
+ blk_t block, int num)
{
+ ext2fs_generic_bitmap_32 bitmap = (ext2fs_generic_bitmap_32) gen_bitmap;
int i;
- if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ if ((block < bitmap->start) || (block > bitmap->end) ||
+ (block+num-1 > bitmap->end)) {
ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
bitmap->description);
return;
ext2fs_fast_clear_bit(block + i - bitmap->start,
bitmap->bitmap);
}
+