[1/5] libext2fs: revamp bitmap types to fix LTO warnings

Message ID 20180809024219.15696-1-tytso@mit.edu
State Accepted
Headers show
Series
  • [1/5] libext2fs: revamp bitmap types to fix LTO warnings
Related show

Commit Message

Theodore Y. Ts'o Aug. 9, 2018, 2:42 a.m.
We play games with pointers to incomplete types to handle subclassing
using the C language, use the first four bytes (the magic number)
field to disambiguate between different subclasses.  The way we were
doing it before, we relied defining the structure differently
depending on the C file implementing different backend subclasses.

This triggers LTO warnings, since it appears (and in fact, we are)
using functions defined with different types than how they were
defined by calling C file.

Fix the LTO warnings by using an explicit base bitmap structure, and
then casting it to the 32-bit or 64-bit variant as needed.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 lib/ext2fs/bitmaps.c      |   6 +-
 lib/ext2fs/blkmap64_ba.c  |  38 ++++----
 lib/ext2fs/blkmap64_rb.c  |  38 ++++----
 lib/ext2fs/bmap64.h       |  38 ++++----
 lib/ext2fs/ext2fs.h       |  11 ++-
 lib/ext2fs/gen_bitmap.c   | 113 +++++++++++++++--------
 lib/ext2fs/gen_bitmap64.c | 185 ++++++++++++++++++++++----------------
 7 files changed, 256 insertions(+), 173 deletions(-)

Patch

diff --git a/lib/ext2fs/bitmaps.c b/lib/ext2fs/bitmaps.c
index 840219172..e25db2c66 100644
--- a/lib/ext2fs/bitmaps.c
+++ b/lib/ext2fs/bitmaps.c
@@ -125,6 +125,7 @@  errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs,
 {
 	__u64			start, end, real_end;
 	ext2fs_generic_bitmap	bmap;
+	ext2fs_generic_bitmap_64 bmap64;
 	errcode_t		retval;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -147,14 +148,15 @@  errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs,
 					   end, real_end, descr, &bmap);
 	if (retval)
 		return retval;
-	bmap->cluster_bits = 0;
+	bmap64 = (ext2fs_generic_bitmap_64) bmap;
+	bmap64->cluster_bits = 0;
 	*ret = bmap;
 	return 0;
 }
 
 int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap)
 {
-	ext2fs_generic_bitmap bmap = bitmap;
+	ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) bitmap;
 
 	if (!EXT2FS_IS_64_BITMAP(bmap))
 		return 0;
diff --git a/lib/ext2fs/blkmap64_ba.c b/lib/ext2fs/blkmap64_ba.c
index 3707a61eb..85cb38d26 100644
--- a/lib/ext2fs/blkmap64_ba.c
+++ b/lib/ext2fs/blkmap64_ba.c
@@ -40,7 +40,7 @@  struct ext2fs_ba_private_struct {
 
 typedef struct ext2fs_ba_private_struct *ext2fs_ba_private;
 
-static errcode_t ba_alloc_private_data (ext2fs_generic_bitmap bitmap)
+static errcode_t ba_alloc_private_data (ext2fs_generic_bitmap_64 bitmap)
 {
 	ext2fs_ba_private bp;
 	errcode_t	retval;
@@ -69,7 +69,7 @@  static errcode_t ba_alloc_private_data (ext2fs_generic_bitmap bitmap)
 }
 
 static errcode_t ba_new_bmap(ext2_filsys fs EXT2FS_ATTR((unused)),
-			     ext2fs_generic_bitmap bitmap)
+			     ext2fs_generic_bitmap_64 bitmap)
 {
 	ext2fs_ba_private bp;
 	errcode_t	retval;
@@ -86,7 +86,7 @@  static errcode_t ba_new_bmap(ext2_filsys fs EXT2FS_ATTR((unused)),
 	return 0;
 }
 
-static void ba_free_bmap(ext2fs_generic_bitmap bitmap)
+static void ba_free_bmap(ext2fs_generic_bitmap_64 bitmap)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
 
@@ -101,8 +101,8 @@  static void ba_free_bmap(ext2fs_generic_bitmap bitmap)
 	bp = 0;
 }
 
-static errcode_t ba_copy_bmap(ext2fs_generic_bitmap src,
-			      ext2fs_generic_bitmap dest)
+static errcode_t ba_copy_bmap(ext2fs_generic_bitmap_64 src,
+			      ext2fs_generic_bitmap_64 dest)
 {
 	ext2fs_ba_private src_bp = (ext2fs_ba_private) src->private;
 	ext2fs_ba_private dest_bp;
@@ -121,7 +121,7 @@  static errcode_t ba_copy_bmap(ext2fs_generic_bitmap src,
 	return 0;
 }
 
-static errcode_t ba_resize_bmap(ext2fs_generic_bitmap bmap,
+static errcode_t ba_resize_bmap(ext2fs_generic_bitmap_64 bmap,
 				__u64 new_end, __u64 new_real_end)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bmap->private;
@@ -162,7 +162,7 @@  static errcode_t ba_resize_bmap(ext2fs_generic_bitmap bmap,
 
 }
 
-static int ba_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int ba_mark_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
 	blk64_t bitno = (blk64_t) arg;
@@ -170,7 +170,7 @@  static int ba_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
 	return ext2fs_set_bit64(bitno - bitmap->start, bp->bitarray);
 }
 
-static int ba_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int ba_unmark_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
 	blk64_t bitno = (blk64_t) arg;
@@ -178,7 +178,7 @@  static int ba_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
 	return ext2fs_clear_bit64(bitno - bitmap->start, bp->bitarray);
 }
 
-static int ba_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int ba_test_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
 	blk64_t bitno = (blk64_t) arg;
@@ -186,7 +186,7 @@  static int ba_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
 	return ext2fs_test_bit64(bitno - bitmap->start, bp->bitarray);
 }
 
-static void ba_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+static void ba_mark_bmap_extent(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
 				unsigned int num)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -197,7 +197,7 @@  static void ba_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
 		ext2fs_fast_set_bit64(bitno + i - bitmap->start, bp->bitarray);
 }
 
-static void ba_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+static void ba_unmark_bmap_extent(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
 				  unsigned int num)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -208,7 +208,7 @@  static void ba_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
 		ext2fs_fast_clear_bit64(bitno + i - bitmap->start, bp->bitarray);
 }
 
-static int ba_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
+static int ba_test_clear_bmap_extent(ext2fs_generic_bitmap_64 bitmap,
 				     __u64 start, unsigned int len)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -282,7 +282,7 @@  static int ba_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
 }
 
 
-static errcode_t ba_set_bmap_range(ext2fs_generic_bitmap bitmap,
+static errcode_t ba_set_bmap_range(ext2fs_generic_bitmap_64 bitmap,
 				     __u64 start, size_t num, void *in)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -292,7 +292,7 @@  static errcode_t ba_set_bmap_range(ext2fs_generic_bitmap bitmap,
 	return 0;
 }
 
-static errcode_t ba_get_bmap_range(ext2fs_generic_bitmap bitmap,
+static errcode_t ba_get_bmap_range(ext2fs_generic_bitmap_64 bitmap,
 				     __u64 start, size_t num, void *out)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
@@ -302,7 +302,7 @@  static errcode_t ba_get_bmap_range(ext2fs_generic_bitmap bitmap,
 	return 0;
 }
 
-static void ba_clear_bmap(ext2fs_generic_bitmap bitmap)
+static void ba_clear_bmap(ext2fs_generic_bitmap_64 bitmap)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
 
@@ -311,20 +311,20 @@  static void ba_clear_bmap(ext2fs_generic_bitmap bitmap)
 }
 
 #ifdef ENABLE_BMAP_STATS
-static void ba_print_stats(ext2fs_generic_bitmap bitmap)
+static void ba_print_stats(ext2fs_generic_bitmap_64 bitmap)
 {
 	fprintf(stderr, "%16llu Bytes used by bitarray\n",
 		((bitmap->real_end - bitmap->start) >> 3) + 1 +
 		sizeof(struct ext2fs_ba_private_struct));
 }
 #else
-static void ba_print_stats(ext2fs_generic_bitmap bitmap EXT2FS_ATTR((unused)))
+static void ba_print_stats(ext2fs_generic_bitmap_64 bitmap EXT2FS_ATTR((unused)))
 {
 }
 #endif
 
 /* Find the first zero bit between start and end, inclusive. */
-static errcode_t ba_find_first_zero(ext2fs_generic_bitmap bitmap,
+static errcode_t ba_find_first_zero(ext2fs_generic_bitmap_64 bitmap,
 				    __u64 start, __u64 end, __u64 *out)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private)bitmap->private;
@@ -398,7 +398,7 @@  static errcode_t ba_find_first_zero(ext2fs_generic_bitmap bitmap,
 }
 
 /* Find the first one bit between start and end, inclusive. */
-static errcode_t ba_find_first_set(ext2fs_generic_bitmap bitmap,
+static errcode_t ba_find_first_set(ext2fs_generic_bitmap_64 bitmap,
 				    __u64 start, __u64 end, __u64 *out)
 {
 	ext2fs_ba_private bp = (ext2fs_ba_private)bitmap->private;
diff --git a/lib/ext2fs/blkmap64_rb.c b/lib/ext2fs/blkmap64_rb.c
index 4cbfb1ed3..1fd552745 100644
--- a/lib/ext2fs/blkmap64_rb.c
+++ b/lib/ext2fs/blkmap64_rb.c
@@ -177,7 +177,7 @@  static void rb_free_extent(struct ext2fs_rb_private *bp,
 	ext2fs_free_mem(&ext);
 }
 
-static errcode_t rb_alloc_private_data (ext2fs_generic_bitmap bitmap)
+static errcode_t rb_alloc_private_data (ext2fs_generic_bitmap_64 bitmap)
 {
 	struct ext2fs_rb_private *bp;
 	errcode_t	retval;
@@ -201,7 +201,7 @@  static errcode_t rb_alloc_private_data (ext2fs_generic_bitmap bitmap)
 }
 
 static errcode_t rb_new_bmap(ext2_filsys fs EXT2FS_ATTR((unused)),
-			     ext2fs_generic_bitmap bitmap)
+			     ext2fs_generic_bitmap_64 bitmap)
 {
 	errcode_t	retval;
 
@@ -225,7 +225,7 @@  static void rb_free_tree(struct rb_root *root)
 	}
 }
 
-static void rb_free_bmap(ext2fs_generic_bitmap bitmap)
+static void rb_free_bmap(ext2fs_generic_bitmap_64 bitmap)
 {
 	struct ext2fs_rb_private *bp;
 
@@ -236,8 +236,8 @@  static void rb_free_bmap(ext2fs_generic_bitmap bitmap)
 	bp = 0;
 }
 
-static errcode_t rb_copy_bmap(ext2fs_generic_bitmap src,
-			      ext2fs_generic_bitmap dest)
+static errcode_t rb_copy_bmap(ext2fs_generic_bitmap_64 src,
+			      ext2fs_generic_bitmap_64 dest)
 {
 	struct ext2fs_rb_private *src_bp, *dest_bp;
 	struct bmap_rb_extent *src_ext, *dest_ext;
@@ -302,7 +302,7 @@  static void rb_truncate(__u64 new_max, struct rb_root *root)
 	}
 }
 
-static errcode_t rb_resize_bmap(ext2fs_generic_bitmap bmap,
+static errcode_t rb_resize_bmap(ext2fs_generic_bitmap_64 bmap,
 				__u64 new_end, __u64 new_real_end)
 {
 	struct ext2fs_rb_private *bp;
@@ -575,7 +575,7 @@  static int rb_remove_extent(__u64 start, __u64 count,
 	return retval;
 }
 
-static int rb_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int rb_mark_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
 {
 	struct ext2fs_rb_private *bp;
 	int retval;
@@ -588,7 +588,7 @@  static int rb_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
 	return retval;
 }
 
-static int rb_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int rb_unmark_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
 {
 	struct ext2fs_rb_private *bp;
 	int retval;
@@ -603,7 +603,7 @@  static int rb_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
 }
 
 inline
-static int rb_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+static int rb_test_bmap(ext2fs_generic_bitmap_64 bitmap, __u64 arg)
 {
 	struct ext2fs_rb_private *bp;
 
@@ -613,7 +613,7 @@  static int rb_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
 	return rb_test_bit(bp, arg);
 }
 
-static void rb_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+static void rb_mark_bmap_extent(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
 				unsigned int num)
 {
 	struct ext2fs_rb_private *bp;
@@ -625,7 +625,7 @@  static void rb_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
 	check_tree(&bp->root, __func__);
 }
 
-static void rb_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+static void rb_unmark_bmap_extent(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
 				  unsigned int num)
 {
 	struct ext2fs_rb_private *bp;
@@ -637,7 +637,7 @@  static void rb_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
 	check_tree(&bp->root, __func__);
 }
 
-static int rb_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
+static int rb_test_clear_bmap_extent(ext2fs_generic_bitmap_64 bitmap,
 				     __u64 start, unsigned int len)
 {
 	struct rb_node *parent = NULL, **n;
@@ -693,7 +693,7 @@  static int rb_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
 	return retval;
 }
 
-static errcode_t rb_set_bmap_range(ext2fs_generic_bitmap bitmap,
+static errcode_t rb_set_bmap_range(ext2fs_generic_bitmap_64 bitmap,
 				     __u64 start, size_t num, void *in)
 {
 	struct ext2fs_rb_private *bp;
@@ -739,7 +739,7 @@  static errcode_t rb_set_bmap_range(ext2fs_generic_bitmap bitmap,
 	return 0;
 }
 
-static errcode_t rb_get_bmap_range(ext2fs_generic_bitmap bitmap,
+static errcode_t rb_get_bmap_range(ext2fs_generic_bitmap_64 bitmap,
 				     __u64 start, size_t num, void *out)
 {
 
@@ -804,7 +804,7 @@  static errcode_t rb_get_bmap_range(ext2fs_generic_bitmap bitmap,
 	return 0;
 }
 
-static void rb_clear_bmap(ext2fs_generic_bitmap bitmap)
+static void rb_clear_bmap(ext2fs_generic_bitmap_64 bitmap)
 {
 	struct ext2fs_rb_private *bp;
 
@@ -817,7 +817,7 @@  static void rb_clear_bmap(ext2fs_generic_bitmap bitmap)
 	check_tree(&bp->root, __func__);
 }
 
-static errcode_t rb_find_first_zero(ext2fs_generic_bitmap bitmap,
+static errcode_t rb_find_first_zero(ext2fs_generic_bitmap_64 bitmap,
 				   __u64 start, __u64 end, __u64 *out)
 {
 	struct rb_node *parent = NULL, **n;
@@ -853,7 +853,7 @@  static errcode_t rb_find_first_zero(ext2fs_generic_bitmap bitmap,
 	return 0;
 }
 
-static errcode_t rb_find_first_set(ext2fs_generic_bitmap bitmap,
+static errcode_t rb_find_first_set(ext2fs_generic_bitmap_64 bitmap,
 				   __u64 start, __u64 end, __u64 *out)
 {
 	struct rb_node *parent = NULL, **n;
@@ -902,7 +902,7 @@  static errcode_t rb_find_first_set(ext2fs_generic_bitmap bitmap,
 }
 
 #ifdef ENABLE_BMAP_STATS
-static void rb_print_stats(ext2fs_generic_bitmap bitmap)
+static void rb_print_stats(ext2fs_generic_bitmap_64 bitmap)
 {
 	struct ext2fs_rb_private *bp;
 	struct rb_node *node = NULL;
@@ -963,7 +963,7 @@  static void rb_print_stats(ext2fs_generic_bitmap bitmap)
 		eff);
 }
 #else
-static void rb_print_stats(ext2fs_generic_bitmap bitmap EXT2FS_ATTR((unused)))
+static void rb_print_stats(ext2fs_generic_bitmap_64 bitmap EXT2FS_ATTR((unused)))
 {
 }
 #endif
diff --git a/lib/ext2fs/bmap64.h b/lib/ext2fs/bmap64.h
index d8c7a3c38..de3345481 100644
--- a/lib/ext2fs/bmap64.h
+++ b/lib/ext2fs/bmap64.h
@@ -37,7 +37,7 @@  struct ext2_bmap_statistics {
 };
 
 
-struct ext2fs_struct_generic_bitmap {
+struct ext2fs_struct_generic_bitmap_64 {
 	errcode_t		magic;
 	ext2_filsys 		fs;
 	struct ext2_bitmap_ops	*bitmap_ops;
@@ -53,6 +53,8 @@  struct ext2fs_struct_generic_bitmap {
 #endif
 };
 
+typedef struct ext2fs_struct_generic_bitmap_64 *ext2fs_generic_bitmap_64;
+
 #define EXT2FS_IS_32_BITMAP(bmap) \
 	(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
 	 ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
@@ -66,37 +68,37 @@  struct ext2fs_struct_generic_bitmap {
 struct ext2_bitmap_ops {
 	int	type;
 	/* Generic bmap operators */
-	errcode_t (*new_bmap)(ext2_filsys fs, ext2fs_generic_bitmap bmap);
-	void	(*free_bmap)(ext2fs_generic_bitmap bitmap);
-	errcode_t (*copy_bmap)(ext2fs_generic_bitmap src,
-			     ext2fs_generic_bitmap dest);
-	errcode_t (*resize_bmap)(ext2fs_generic_bitmap bitmap,
+	errcode_t (*new_bmap)(ext2_filsys fs, ext2fs_generic_bitmap_64 bmap);
+	void	(*free_bmap)(ext2fs_generic_bitmap_64 bitmap);
+	errcode_t (*copy_bmap)(ext2fs_generic_bitmap_64 src,
+			     ext2fs_generic_bitmap_64 dest);
+	errcode_t (*resize_bmap)(ext2fs_generic_bitmap_64 bitmap,
 			       __u64 new_end,
 			       __u64 new_real_end);
 	/* bit set/test operators */
-	int	(*mark_bmap)(ext2fs_generic_bitmap bitmap, __u64 arg);
-	int	(*unmark_bmap)(ext2fs_generic_bitmap bitmap, __u64 arg);
-	int	(*test_bmap)(ext2fs_generic_bitmap bitmap, __u64 arg);
-	void	(*mark_bmap_extent)(ext2fs_generic_bitmap bitmap, __u64 arg,
+	int	(*mark_bmap)(ext2fs_generic_bitmap_64 bitmap, __u64 arg);
+	int	(*unmark_bmap)(ext2fs_generic_bitmap_64 bitmap, __u64 arg);
+	int	(*test_bmap)(ext2fs_generic_bitmap_64 bitmap, __u64 arg);
+	void	(*mark_bmap_extent)(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
 				    unsigned int num);
-	void	(*unmark_bmap_extent)(ext2fs_generic_bitmap bitmap, __u64 arg,
+	void	(*unmark_bmap_extent)(ext2fs_generic_bitmap_64 bitmap, __u64 arg,
 				      unsigned int num);
-	int	(*test_clear_bmap_extent)(ext2fs_generic_bitmap bitmap,
+	int	(*test_clear_bmap_extent)(ext2fs_generic_bitmap_64 bitmap,
 					  __u64 arg, unsigned int num);
-	errcode_t (*set_bmap_range)(ext2fs_generic_bitmap bitmap,
+	errcode_t (*set_bmap_range)(ext2fs_generic_bitmap_64 bitmap,
 				    __u64 start, size_t num, void *in);
-	errcode_t (*get_bmap_range)(ext2fs_generic_bitmap bitmap,
+	errcode_t (*get_bmap_range)(ext2fs_generic_bitmap_64 bitmap,
 				    __u64 start, size_t num, void *out);
-	void (*clear_bmap)(ext2fs_generic_bitmap bitmap);
-	void (*print_stats)(ext2fs_generic_bitmap);
+	void (*clear_bmap)(ext2fs_generic_bitmap_64 bitmap);
+	void (*print_stats)(ext2fs_generic_bitmap_64);
 
 	/* Find the first zero bit between start and end, inclusive.
 	 * May be NULL, in which case a generic function is used. */
-	errcode_t (*find_first_zero)(ext2fs_generic_bitmap bitmap,
+	errcode_t (*find_first_zero)(ext2fs_generic_bitmap_64 bitmap,
 				     __u64 start, __u64 end, __u64 *out);
 	/* Find the first set bit between start and end, inclusive.
 	 * May be NULL, in which case a generic function is used. */
-	errcode_t (*find_first_set)(ext2fs_generic_bitmap bitmap,
+	errcode_t (*find_first_set)(ext2fs_generic_bitmap_64 bitmap,
 				    __u64 start, __u64 end, __u64 *out);
 };
 
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 3d4afac4b..c4a4ef019 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -111,9 +111,14 @@  typedef struct struct_ext2_filsys *ext2_filsys;
 #define EXT2FS_UNMARK_ERROR 	1
 #define EXT2FS_TEST_ERROR	2
 
-typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
-typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
-typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
+struct ext2fs_struct_generic_bitmap_base {
+	errcode_t		magic;
+	ext2_filsys 		fs;
+};
+
+typedef struct ext2fs_struct_generic_bitmap_base *ext2fs_generic_bitmap;
+typedef struct ext2fs_struct_generic_bitmap_base *ext2fs_inode_bitmap;
+typedef struct ext2fs_struct_generic_bitmap_base *ext2fs_block_bitmap;
 
 #define EXT2_FIRST_INODE(s)	EXT2_FIRST_INO(s)
 
diff --git a/lib/ext2fs/gen_bitmap.c b/lib/ext2fs/gen_bitmap.c
index d0061b822..181371c8c 100644
--- a/lib/ext2fs/gen_bitmap.c
+++ b/lib/ext2fs/gen_bitmap.c
@@ -28,7 +28,7 @@ 
 #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;
@@ -39,6 +39,8 @@  struct ext2fs_struct_generic_bitmap {
 	__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) || \
@@ -53,9 +55,11 @@  struct ext2fs_struct_generic_bitmap {
  * 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,
@@ -79,11 +83,11 @@  errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
 				     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;
@@ -127,7 +131,7 @@  errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
 		memcpy(bitmap->bitmap, init_map, size);
 	else
 		memset(bitmap->bitmap, 0, size);
-	*ret = bitmap;
+	*ret = (ext2fs_generic_bitmap) bitmap;
 	return 0;
 }
 
@@ -141,9 +145,11 @@  errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
 					  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,
@@ -151,9 +157,11 @@  errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,
 					   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;
@@ -171,6 +179,8 @@  void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
 int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
 					blk_t bitno)
 {
+	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__);
@@ -183,16 +193,18 @@  int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
 		return 0;
 	}
 
-	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+	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)
 {
+	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__);
@@ -205,16 +217,18 @@  int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
 		return 0;
 	}
 
-	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+	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)
 {
+	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__);
@@ -227,15 +241,17 @@  int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
 		return 0;
 	}
 
-	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+	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)
 {
+	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__);
@@ -248,11 +264,13 @@  __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)
 		return 0;
 	}
 
-	return bitmap->start;
+	return bitmap32->start;
 }
 
 __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap 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__);
@@ -264,11 +282,13 @@  __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)
 #endif
 		return 0;
 	}
-	return bitmap->end;
+	return bitmap32->end;
 }
 
 void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap 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__);
@@ -282,14 +302,16 @@  void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)
 		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)
@@ -302,8 +324,9 @@  errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
 
 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;
@@ -344,9 +367,11 @@  errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
 }
 
 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)
@@ -361,15 +386,16 @@  errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
 		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 */
@@ -379,11 +405,13 @@  void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map)
 		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;
 
@@ -394,11 +422,13 @@  errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
 	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;
 
@@ -432,10 +462,11 @@  int ext2fs_mem_is_zero(const char *mem, size_t len)
 /*
  * 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;
@@ -504,14 +535,15 @@  static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap bitmap,
 	return ext2fs_mem_is_zero(ADDR + start_byte, len_byte);
 }
 
-errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_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(bitmap, EXT2FS_TEST_ERROR, start);
+		ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR, start);
 		return EINVAL;
 	}
 
@@ -527,14 +559,15 @@  errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,
 	return ENOENT;
 }
 
-errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitmap,
+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(bitmap, EXT2FS_TEST_ERROR, start);
+		ext2fs_warn_bitmap2(gen_bitmap, EXT2FS_TEST_ERROR, start);
 		return EINVAL;
 	}
 
@@ -550,9 +583,11 @@  errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitmap,
 	return ENOENT;
 }
 
-int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+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)) {
 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
@@ -563,9 +598,11 @@  int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
 						      bitmap, block, num);
 }
 
-int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
+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)) {
 		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
@@ -576,9 +613,10 @@  int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
 						      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)) {
@@ -590,9 +628,10 @@  void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
 		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)) {
diff --git a/lib/ext2fs/gen_bitmap64.c b/lib/ext2fs/gen_bitmap64.c
index 3fc734981..d6f3ac12c 100644
--- a/lib/ext2fs/gen_bitmap64.c
+++ b/lib/ext2fs/gen_bitmap64.c
@@ -68,7 +68,7 @@ 
  * 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
@@ -93,7 +93,7 @@  errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
 				    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;
@@ -119,7 +119,7 @@  errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
 		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;
@@ -170,12 +170,12 @@  errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
 		return retval;
 	}
 
-	*ret = bitmap;
+	*ret = (ext2fs_generic_bitmap) bitmap;
 	return 0;
 }
 
 #ifdef ENABLE_BMAP_STATS
-static 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
@@ -241,13 +241,15 @@  static void ext2fs_print_bmap_statistics(ext2fs_generic_bitmap bitmap)
 }
 #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;
 	}
 
@@ -271,24 +273,25 @@  void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap)
 	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;
@@ -336,21 +339,23 @@  errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
 		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;
@@ -360,10 +365,12 @@  errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
 	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;
 
@@ -371,7 +378,8 @@  errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
 		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;
@@ -389,13 +397,15 @@  errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
 	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;
@@ -403,13 +413,15 @@  __u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap bitmap)
 	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;
@@ -417,27 +429,31 @@  __u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap bitmap)
 	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))
@@ -462,19 +478,21 @@  int ext2fs_mark_generic_bmap(ext2fs_generic_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))
@@ -492,19 +510,20 @@  int ext2fs_unmark_generic_bmap(ext2fs_generic_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))
@@ -529,20 +548,22 @@  int ext2fs_test_generic_bmap(ext2fs_generic_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);
 	}
 
@@ -554,20 +575,22 @@  errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
 	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);
 	}
 
@@ -580,9 +603,11 @@  errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
 }
 
 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)
@@ -592,7 +617,8 @@  errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
 
 	/* 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;
@@ -602,19 +628,20 @@  errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
 		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;
 	}
 
@@ -624,9 +651,10 @@  void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap)
 	/* 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)
@@ -666,9 +694,10 @@  int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap,
 	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)
@@ -704,9 +733,10 @@  void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap,
 	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)
@@ -742,8 +772,10 @@  void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap,
 	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,
@@ -758,21 +790,22 @@  void ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func)
 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;
 
-	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;
@@ -781,8 +814,8 @@  errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
 	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);
+		if (ext2fs_test_block_bitmap2(gen_bmap, i)) {
+			ext2fs_mark_block_bitmap2(gen_cmap, i);
 			i += ratio - n;
 			n = 0;
 			continue;
@@ -793,14 +826,15 @@  errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
 	}
 	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)
 {
+	ext2fs_generic_bitmap_64 bmap64 = (ext2fs_generic_bitmap_64) bitmap;
 	__u64 cstart, cend, cout;
 	errcode_t retval;
 
@@ -826,27 +860,27 @@  errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
 	if (!EXT2FS_IS_64_BITMAP(bitmap))
 		return EINVAL;
 
-	cstart = start >> bitmap->cluster_bits;
-	cend = end >> bitmap->cluster_bits;
+	cstart = start >> bmap64->cluster_bits;
+	cend = end >> bmap64->cluster_bits;
 
-	if (cstart < bitmap->start || cend > 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;
 	}
 
-	if (bitmap->bitmap_ops->find_first_zero) {
-		retval = bitmap->bitmap_ops->find_first_zero(bitmap, cstart,
+	if (bmap64->bitmap_ops->find_first_zero) {
+		retval = bmap64->bitmap_ops->find_first_zero(bmap64, cstart,
 							     cend, &cout);
 		if (retval)
 			return retval;
 	found:
-		cout <<= bitmap->cluster_bits;
+		cout <<= bmap64->cluster_bits;
 		*out = (cout >= start) ? cout : start;
 		return 0;
 	}
 
 	for (cout = cstart; cout <= cend; cout++)
-		if (!bitmap->bitmap_ops->test_bmap(bitmap, cout))
+		if (!bmap64->bitmap_ops->test_bmap(bmap64, cout))
 			goto found;
 
 	return ENOENT;
@@ -855,6 +889,7 @@  errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
 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;
 
@@ -880,27 +915,27 @@  errcode_t ext2fs_find_first_set_generic_bmap(ext2fs_generic_bitmap bitmap,
 	if (!EXT2FS_IS_64_BITMAP(bitmap))
 		return EINVAL;
 
-	cstart = start >> bitmap->cluster_bits;
-	cend = end >> bitmap->cluster_bits;
+	cstart = start >> bmap64->cluster_bits;
+	cend = end >> bmap64->cluster_bits;
 
-	if (cstart < bitmap->start || cend > 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;
 	}
 
-	if (bitmap->bitmap_ops->find_first_set) {
-		retval = bitmap->bitmap_ops->find_first_set(bitmap, cstart,
+	if (bmap64->bitmap_ops->find_first_set) {
+		retval = bmap64->bitmap_ops->find_first_set(bmap64, cstart,
 							    cend, &cout);
 		if (retval)
 			return retval;
 	found:
-		cout <<= bitmap->cluster_bits;
+		cout <<= bmap64->cluster_bits;
 		*out = (cout >= start) ? cout : start;
 		return 0;
 	}
 
 	for (cout = cstart; cout <= cend; cout++)
-		if (bitmap->bitmap_ops->test_bmap(bitmap, cout))
+		if (bmap64->bitmap_ops->test_bmap(bmap64, cout))
 			goto found;
 
 	return ENOENT;