[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1226461390-5502-5-git-send-email-vaurora@redhat.com>
Date: Tue, 11 Nov 2008 19:42:57 -0800
From: Valerie Aurora Henson <vaurora@...hat.com>
To: linux-ext4@...r.kernel.org
Cc: Valerie Aurora Henson <vaurora@...hat.com>
Subject: [RFC PATCH 04/17] Implement 64-bit "bitarray" bmap ops
---
lib/ext2fs/bitops.h | 176 ++++++++++++++++++++++++-
lib/ext2fs/blkmap64_ba.c | 174 ++++++++++++++++++++++-
lib/ext2fs/ext2fs.h | 4 +
lib/ext2fs/ext2fsP.h | 15 +-
lib/ext2fs/gen_bitmap64.c | 333 ++++++++++++++++++++++++++++++++++++++++-----
5 files changed, 649 insertions(+), 53 deletions(-)
diff --git a/lib/ext2fs/bitops.h b/lib/ext2fs/bitops.h
index d681778..1138800 100644
--- a/lib/ext2fs/bitops.h
+++ b/lib/ext2fs/bitops.h
@@ -109,7 +109,7 @@ extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
-/* These routines moved to gen_bitmap.c */
+/* These routines moved to gen_bitmap.c (actually, some of the above, too) */
extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
__u32 bitno);
extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
@@ -121,6 +121,60 @@ extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
extern __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap);
extern __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap);
+/* 64-bit versions */
+
+extern int ext2fs_mark_block_bitmap2(ext2fs_block_bitmap64 bitmap, blk64_t block);
+extern int ext2fs_unmark_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block);
+extern int ext2fs_test_block_bitmap2(ext2fs_block_bitmap64 bitmap, blk64_t block);
+
+extern int ext2fs_mark_inode_bitmap2(ext2fs_inode_bitmap64 bitmap, ext2_ino_t inode);
+extern int ext2fs_unmark_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode);
+extern int ext2fs_test_inode_bitmap2(ext2fs_inode_bitmap64 bitmap, ext2_ino_t inode);
+
+extern void ext2fs_fast_mark_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block);
+extern void ext2fs_fast_unmark_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block);
+extern int ext2fs_fast_test_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block);
+
+extern void ext2fs_fast_mark_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode);
+extern void ext2fs_fast_unmark_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode);
+extern int ext2fs_fast_test_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode);
+extern blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap64 bitmap);
+extern ext2_ino_t ext2fs_get_inode_bitmap_start2(ext2fs_inode_bitmap64 bitmap);
+extern blk64_t ext2fs_get_block_bitmap_end2(ext2fs_block_bitmap64 bitmap);
+extern ext2_ino_t ext2fs_get_inode_bitmap_end2(ext2fs_inode_bitmap64 bitmap);
+
+extern int ext2fs_fast_test_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num);
+extern void ext2fs_fast_mark_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num);
+extern void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num);
+/* These routines moved to gen_bitmap64.c */
+extern int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap64 bitmap,
+ blk64_t bitno);
+extern int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap64 bitmap,
+ blk64_t bitno);
+extern int ext2fs_test_generic_bmap(ext2fs_generic_bitmap64 bitmap,
+ blk64_t bitno);
+extern int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num);
+extern __u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap64 bitmap);
+extern __u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap64 bitmap);
+extern int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num);
+extern void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num);
+extern void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num);
+
/*
* The inline routines themselves...
*
@@ -546,6 +600,126 @@ _INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
{
ext2fs_unmark_block_bitmap_range(bitmap, block, num);
}
+
+/* 64-bit versions */
+
+_INLINE_ int ext2fs_mark_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block)
+{
+ return ext2fs_mark_generic_bmap((ext2fs_generic_bitmap64) bitmap,
+ block);
+}
+
+_INLINE_ int ext2fs_unmark_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block)
+{
+ return ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap64) bitmap, block);
+}
+
+_INLINE_ int ext2fs_test_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block)
+{
+ return ext2fs_test_generic_bmap((ext2fs_generic_bitmap64) bitmap,
+ block);
+}
+
+_INLINE_ int ext2fs_mark_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode)
+{
+ return ext2fs_mark_generic_bmap((ext2fs_generic_bitmap64) bitmap,
+ inode);
+}
+
+_INLINE_ int ext2fs_unmark_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode)
+{
+ return ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap64) bitmap,
+ inode);
+}
+
+_INLINE_ int ext2fs_test_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode)
+{
+ return ext2fs_test_generic_bmap((ext2fs_generic_bitmap64) bitmap,
+ inode);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block)
+{
+ ext2fs_mark_generic_bmap((ext2fs_generic_bitmap64) bitmap, block);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block)
+{
+ ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap64) bitmap, block);
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block)
+{
+ return ext2fs_test_generic_bmap((ext2fs_generic_bitmap64) bitmap,
+ block);
+}
+
+_INLINE_ void ext2fs_fast_mark_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode)
+{
+ ext2fs_mark_generic_bmap((ext2fs_generic_bitmap64) bitmap, inode);
+}
+
+_INLINE_ void ext2fs_fast_unmark_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode)
+{
+ ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap64) bitmap, inode);
+}
+
+_INLINE_ int ext2fs_fast_test_inode_bitmap2(ext2fs_inode_bitmap64 bitmap,
+ ext2_ino_t inode)
+{
+ return ext2fs_test_generic_bmap((ext2fs_generic_bitmap64) bitmap,
+ inode);
+}
+
+_INLINE_ blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap64 bitmap)
+{
+ return ext2fs_get_generic_bmap_start((ext2fs_generic_bitmap64) bitmap);
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start2(ext2fs_inode_bitmap64 bitmap)
+{
+ return ext2fs_get_generic_bmap_start((ext2fs_generic_bitmap64) bitmap);
+}
+
+_INLINE_ blk64_t ext2fs_get_block_bitmap_end2(ext2fs_block_bitmap64 bitmap)
+{
+ return ext2fs_get_generic_bmap_end((ext2fs_generic_bitmap64) bitmap);
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end2(ext2fs_inode_bitmap64 bitmap)
+{
+ return ext2fs_get_generic_bmap_end((ext2fs_generic_bitmap64) bitmap);
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num)
+{
+ return ext2fs_test_block_bitmap_range2(bitmap, block, num);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num)
+{
+ ext2fs_mark_block_bitmap_range2(bitmap, block, num);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap64 bitmap,
+ blk64_t block, int num)
+{
+ ext2fs_unmark_block_bitmap_range2(bitmap, block, num);
+}
+
#undef _INLINE_
#endif
diff --git a/lib/ext2fs/blkmap64_ba.c b/lib/ext2fs/blkmap64_ba.c
index 855a160..f7f7097 100644
--- a/lib/ext2fs/blkmap64_ba.c
+++ b/lib/ext2fs/blkmap64_ba.c
@@ -26,54 +26,211 @@
#include "ext2_fs.h"
#include "ext2fsP.h"
-static errcode_t ba_new_bmap(ext2_filsys fs, ext2fs_generic_bitmap64 *bmap)
+/*
+ * Private data for bit array implementation of bitmap ops.
+ * Currently, this is just a pointer to our big flat hunk of memory,
+ * exactly equivalent to the old-skool char * bitmap member.
+ */
+
+struct ext2fs_ba_private_struct {
+ char *bitarray;
+};
+
+typedef struct ext2fs_ba_private_struct *ext2fs_ba_private;
+
+static errcode_t ba_alloc_private_data (ext2fs_generic_bitmap64 bitmap)
+{
+ ext2fs_ba_private bp;
+ errcode_t retval;
+ size_t size;
+
+ /*
+ * Since we only have the one pointer, we could just shove our
+ * private data in the void *private field itself, but then
+ * we'd have to do a fair bit of rewriting if we ever added a
+ * field. I'm agnostic.
+ */
+ retval = ext2fs_get_mem(sizeof (ext2fs_ba_private), &bp);
+ if (retval)
+ return retval;
+
+ size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
+
+ retval = ext2fs_get_mem(size, &bp->bitarray);
+ if (retval) {
+ ext2fs_free_mem(&bp);
+ bp = 0;
+ return retval;
+ }
+ bitmap->private = (void *) bp;
+ return 0;
+}
+
+static errcode_t ba_new_bmap(ext2_filsys fs, ext2fs_generic_bitmap64 bitmap)
{
+ ext2fs_ba_private bp;
+ errcode_t retval;
+ size_t size;
+
+ retval = ba_alloc_private_data (bitmap);
+ if (retval)
+ return retval;
+
+ bp = (ext2fs_ba_private) bitmap->private;
+ size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
+ memset(bp->bitarray, 0, size);
+
+ return 0;
}
static void ba_free_bmap(ext2fs_generic_bitmap64 bitmap)
{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+
+ if (!bp)
+ return;
+
+ if (bp->bitarray) {
+ ext2fs_free_mem (&bp->bitarray);
+ bp->bitarray = 0;
+ }
+ ext2fs_free_mem (&bp);
+ bp = 0;
}
static errcode_t ba_copy_bmap(ext2fs_generic_bitmap64 src,
- ext2fs_generic_bitmap64 *dest)
+ ext2fs_generic_bitmap64 dest)
{
+ ext2fs_ba_private src_bp = (ext2fs_ba_private) src->private;
+ ext2fs_ba_private dest_bp;
+ errcode_t retval;
+ size_t size;
+
+ retval = ba_alloc_private_data (dest);
+ if (retval)
+ return retval;
+
+ dest_bp = (ext2fs_ba_private) dest->private;
+
+ size = (size_t) (((src->real_end - src->start) / 8) + 1);
+ memcpy (dest_bp->bitarray, src_bp->bitarray, size);
+
+ return 0;
}
-static errcode_t ba_resize_bmap(ext2fs_generic_bitmap64 bitmap,
+static errcode_t ba_resize_bmap(ext2fs_generic_bitmap64 bmap,
__u64 new_end, __u64 new_real_end)
{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bmap->private;
+ errcode_t retval;
+ size_t size, new_size;
+ __u32 bitno;
+
+ /*
+ * If we're expanding the bitmap, make sure all of the new
+ * parts of the bitmap are zero.
+ */
+ if (new_end > bmap->end) {
+ bitno = bmap->real_end;
+ if (bitno > new_end)
+ bitno = new_end;
+ for (; bitno > bmap->end; bitno--)
+ ext2fs_clear_bit64(bitno - bmap->start, bp->bitarray);
+ }
+ if (new_real_end == bmap->real_end) {
+ bmap->end = new_end;
+ return 0;
+ }
+
+ size = ((bmap->real_end - bmap->start) / 8) + 1;
+ new_size = ((new_real_end - bmap->start) / 8) + 1;
+
+ if (size != new_size) {
+ retval = ext2fs_resize_mem(size, new_size, &bp->bitarray);
+ if (retval)
+ return retval;
+ }
+ if (new_size > size)
+ memset(bp->bitarray + size, 0, new_size - size);
+
+ bmap->end = new_end;
+ bmap->real_end = new_real_end;
+ return 0;
+
}
static int ba_mark_bmap(ext2fs_generic_bitmap64 bitmap, __u64 arg)
{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+ blk64_t bitno = (blk64_t) arg;
+
+ return ext2fs_set_bit64(bitno - bitmap->start, bp->bitarray);
}
static int ba_unmark_bmap(ext2fs_generic_bitmap64 bitmap, __u64 arg)
{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+ blk64_t bitno = (blk64_t) arg;
+
+ return ext2fs_clear_bit64(bitno - bitmap->start, bp->bitarray);
}
static int ba_test_bmap(ext2fs_generic_bitmap64 bitmap, __u64 arg)
{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+ blk64_t bitno = (blk64_t) arg;
+
+ return ext2fs_test_bit64(bitno - bitmap->start, bp->bitarray);
}
static void ba_mark_bmap_extent(ext2fs_generic_bitmap64 bitmap, __u64 arg,
- int num)
+ size_t num)
{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+ blk64_t bitno = (blk64_t) arg;
+ size_t i;
+
+ for (i = 0; i < num; i++)
+ ext2fs_fast_set_bit64(bitno + i - bitmap->start, bp->bitarray);
}
static void ba_unmark_bmap_extent(ext2fs_generic_bitmap64 bitmap, __u64 arg,
- int num)
+ size_t num)
{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+ blk64_t bitno = (blk64_t) arg;
+ size_t i;
+
+ for (i = 0; i < num; i++)
+ ext2fs_fast_clear_bit64(bitno + i - bitmap->start, bp->bitarray);
}
static errcode_t ba_set_bmap_range(ext2fs_generic_bitmap64 bitmap,
- __u64 start, unsigned int num, void *in)
+ __u64 start, size_t num, void *in)
{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+
+ memcpy (bp->bitarray + (start >> 3), in, (num + 7) >> 3);
+
+ return 0;
}
static errcode_t ba_get_bmap_range(ext2fs_generic_bitmap64 bitmap,
- __u64 start, unsigned int num, void *out)
+ __u64 start, size_t num, void *out)
{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+
+ memcpy (out, bp->bitarray + (start >> 3), (num + 7) >> 3);
+
+ return 0;
+}
+
+static void ba_clear_bmap(ext2fs_generic_bitmap64 bitmap)
+{
+ ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+
+ memset(bp->bitarray, 0,
+ (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
}
struct ext2_bitmap_ops ext2fs_blkmap64_bitarray = {
@@ -88,5 +245,6 @@ struct ext2_bitmap_ops ext2fs_blkmap64_bitarray = {
.mark_bmap_extent = ba_mark_bmap_extent,
.unmark_bmap_extent = ba_unmark_bmap_extent,
.set_bmap_range = ba_set_bmap_range,
- .get_bmap_range = ba_get_bmap_range
+ .get_bmap_range = ba_get_bmap_range,
+ .clear_bmap = ba_clear_bmap,
};
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index ad21fd7..dbc5909 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -103,6 +103,10 @@ 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;
+typedef struct ext2fs_struct_generic_bitmap64 *ext2fs_generic_bitmap64;
+typedef struct ext2fs_struct_generic_bitmap64 *ext2fs_inode_bitmap64;
+typedef struct ext2fs_struct_generic_bitmap64 *ext2fs_block_bitmap64;
+
#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
diff --git a/lib/ext2fs/ext2fsP.h b/lib/ext2fs/ext2fsP.h
index 6f8a4e1..390733b 100644
--- a/lib/ext2fs/ext2fsP.h
+++ b/lib/ext2fs/ext2fsP.h
@@ -113,15 +113,13 @@ struct ext2fs_struct_generic_bitmap64 {
#define EXT2FS_BMAP64_BITARRAY 1
-typedef struct ext2fs_struct_generic_bitmap64 *ext2fs_generic_bitmap64;
-
struct ext2_bitmap_ops {
int type;
/* Generic bmap operators */
- errcode_t (*new_bmap)(ext2_filsys fs, ext2fs_generic_bitmap64 *bmap);
+ errcode_t (*new_bmap)(ext2_filsys fs, ext2fs_generic_bitmap64 bmap);
void (*free_bmap)(ext2fs_generic_bitmap64 bitmap);
errcode_t (*copy_bmap)(ext2fs_generic_bitmap64 src,
- ext2fs_generic_bitmap64 *dest);
+ ext2fs_generic_bitmap64 dest);
errcode_t (*resize_bmap)(ext2fs_generic_bitmap64 bitmap,
__u64 new_end,
__u64 new_real_end);
@@ -130,13 +128,14 @@ struct ext2_bitmap_ops {
int (*unmark_bmap)(ext2fs_generic_bitmap64 bitmap, __u64 arg);
int (*test_bmap)(ext2fs_generic_bitmap64 bitmap, __u64 arg);
void (*mark_bmap_extent)(ext2fs_generic_bitmap64 bitmap, __u64 arg,
- int num);
+ size_t num);
void (*unmark_bmap_extent)(ext2fs_generic_bitmap64 bitmap, __u64 arg,
- int num);
+ size_t num);
errcode_t (*set_bmap_range)(ext2fs_generic_bitmap64 bitmap,
- __u64 start, unsigned int num, void *in);
+ __u64 start, size_t num, void *in);
errcode_t (*get_bmap_range)(ext2fs_generic_bitmap64 bitmap,
- __u64 start, unsigned int num, void *out);
+ __u64 start, size_t num, void *out);
+ void (*clear_bmap)(ext2fs_generic_bitmap64 bitmap);
};
extern struct ext2_bitmap_ops ext2fs_blkmap64_bitarray;
diff --git a/lib/ext2fs/gen_bitmap64.c b/lib/ext2fs/gen_bitmap64.c
index 75af6de..f2c0119 100644
--- a/lib/ext2fs/gen_bitmap64.c
+++ b/lib/ext2fs/gen_bitmap64.c
@@ -99,6 +99,7 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
if (retval)
return retval;
+ /* XXX factor out, repeated in copy_bmap */
bitmap->magic = magic;
bitmap->fs = fs;
bitmap->start = start;
@@ -125,7 +126,7 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
} else
bitmap->description = 0;
- retval = bitmap->bitmap_ops->new_bmap(fs, &bitmap);
+ retval = bitmap->bitmap_ops->new_bmap(fs, bitmap);
if (retval) {
ext2fs_free_mem(&bitmap);
ext2fs_free_mem(&bitmap->description);
@@ -162,37 +163,53 @@ errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap64 src,
ext2fs_generic_bitmap64 *dest)
{
char *descr, *new_descr;
+ ext2fs_generic_bitmap64 new_bmap;
errcode_t retval;
if (!src)
- return;
+ return EINVAL;
- if (EXT2FS_IS_32_BITMAP(src)) {
- ext2fs_copy_generic_bitmap((ext2fs_generic_bitmap) src,
- (ext2fs_generic_bitmap *) dest);
- return;
- }
+ if (EXT2FS_IS_32_BITMAP(src))
+ return ext2fs_copy_generic_bitmap((ext2fs_generic_bitmap) src,
+ (ext2fs_generic_bitmap *) dest);
if (!EXT2FS_IS_64_BITMAP(src))
- return;
+ return EINVAL;
+
+ /* Allocate a new bitmap struct */
+ retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap64),
+ &new_bmap);
+ if (retval)
+ return retval;
+
+ /* Copy all the high-level parts over */
+ new_bmap->magic = src->magic;
+ new_bmap->fs = src->fs;
+ new_bmap->start = src->start;
+ new_bmap->end = src->end;
+ new_bmap->real_end = src->real_end;
+ new_bmap->bitmap_ops = src->bitmap_ops;
+ new_bmap->base_error_code = src->base_error_code;
descr = src->description;
if (descr) {
retval = ext2fs_get_mem(strlen(descr)+1, &new_descr);
if (retval) {
- new_descr = 0;
+ ext2fs_free_mem(&new_bmap);
return retval;
}
strcpy(new_descr, descr);
+ new_bmap->description = new_descr;
}
- retval = src->bitmap_ops->copy_bmap(src, dest);
+ retval = src->bitmap_ops->copy_bmap(src, new_bmap);
if (retval) {
- ext2fs_free_mem(&new_descr);
+ ext2fs_free_mem(&new_bmap->description);
+ ext2fs_free_mem(&new_bmap);
return retval;
}
- (*dest)->description = new_descr;
+ *dest = new_bmap;
return 0;
}
@@ -201,24 +218,95 @@ errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap64 bmap,
__u64 new_end,
__u64 new_real_end)
{
- errcode_t retval;
-
if (!bmap)
- return;
+ return EINVAL;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- ext2fs_resize_generic_bitmap(bmap->magic,
- new_end, new_real_end,
- (ext2fs_generic_bitmap) bmap);
- return;
+ return ext2fs_resize_generic_bitmap(bmap->magic,
+ new_end, new_real_end,
+ (ext2fs_generic_bitmap) bmap);
}
if (!EXT2FS_IS_64_BITMAP(bmap))
- return;
+ return EINVAL;
return bmap->bitmap_ops->resize_bmap(bmap, new_end, new_real_end);
}
+errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap64 bitmap,
+ errcode_t neq,
+ __u64 end, __u64 *oend)
+{
+ if (!bitmap)
+ return EINVAL;
+
+ if (EXT2FS_IS_32_BITMAP(bitmap)) {
+ ext2_ino_t tmp_oend;
+ int retval;
+
+ retval = ext2fs_fudge_generic_bitmap_end((ext2fs_generic_bitmap) bitmap,
+ bitmap->magic, neq,
+ end, &tmp_oend);
+ if (oend)
+ *oend = tmp_oend;
+ return retval;
+ }
+
+ if (!EXT2FS_IS_64_BITMAP(bitmap))
+ return EINVAL;
+
+ if (end > bitmap->real_end)
+ return neq;
+ if (oend)
+ *oend = bitmap->end;
+ bitmap->end = end;
+ return 0;
+}
+
+__u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap64 bitmap)
+{
+ if (!bitmap)
+ return EINVAL;
+
+ if (EXT2FS_IS_32_BITMAP(bitmap)) {
+ return ext2fs_get_generic_bitmap_start((ext2fs_generic_bitmap)
+ bitmap);
+
+ }
+
+ if (!EXT2FS_IS_64_BITMAP(bitmap))
+ return EINVAL;
+
+ return bitmap->start;
+}
+
+__u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap64 bitmap)
+{
+ if (!bitmap)
+ return EINVAL;
+
+ if (EXT2FS_IS_32_BITMAP(bitmap)) {
+ return ext2fs_get_generic_bitmap_end((ext2fs_generic_bitmap)
+ bitmap);
+
+ }
+
+ if (!EXT2FS_IS_64_BITMAP(bitmap))
+ return EINVAL;
+
+ return bitmap->end;
+}
+
+void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap64 bitmap)
+{
+ if (EXT2FS_IS_32_BITMAP(bitmap)) {
+ ext2fs_clear_generic_bitmap((ext2fs_generic_bitmap) bitmap);
+ return;
+ }
+
+ bitmap->bitmap_ops->clear_bmap (bitmap);
+}
+
int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap64 bitmap,
__u64 arg)
{
@@ -226,7 +314,7 @@ int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap64 bitmap,
return 0;
if (EXT2FS_IS_32_BITMAP(bitmap)) {
- if (arg & ~0xffffffff) {
+ if (arg & ~0xffffffffULL) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bitmap,
EXT2FS_MARK_ERROR, 0xffffffff);
return 0;
@@ -253,7 +341,7 @@ int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap64 bitmap,
return 0;
if (EXT2FS_IS_32_BITMAP(bitmap)) {
- if (arg & ~0xffffffff) {
+ if (arg & ~0xffffffffULL) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bitmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return 0;
@@ -280,7 +368,7 @@ int ext2fs_test_generic_bmap(ext2fs_generic_bitmap64 bitmap,
return 0;
if (EXT2FS_IS_32_BITMAP(bitmap)) {
- if (arg & ~0xffffffff) {
+ if (arg & ~0xffffffffULL) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bitmap,
EXT2FS_TEST_ERROR, 0xffffffff);
return 0;
@@ -300,25 +388,28 @@ int ext2fs_test_generic_bmap(ext2fs_generic_bitmap64 bitmap,
return bitmap->bitmap_ops->test_bmap(bitmap, arg);
}
+/*
+ * XXX mark/unmark extents are new functions, do we need to make them
+ * handle old-style bitmaps?
+ */
+
void ext2fs_mark_generic_bmap_extent(ext2fs_generic_bitmap64 bmap,
__u64 arg, int num)
{
- errcode_t retval;
- __u32 i;
- int c;
+ int i;
if (!bmap)
return;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- if ((arg+num) & ~0xffffffff) {
+ if ((arg+num) & ~0xffffffffULL) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_MARK_ERROR, 0xffffffff);
return;
}
- for (i = arg, c = num; c > 0; c--)
+ for (i = 0; i < num; i++)
ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
- bmap, i);
+ bmap, arg + i);
return;
}
@@ -331,22 +422,20 @@ void ext2fs_mark_generic_bmap_extent(ext2fs_generic_bitmap64 bmap,
void ext2fs_unmark_generic_bmap_extent(ext2fs_generic_bitmap64 bmap,
__u64 arg, int num)
{
- errcode_t retval;
__u32 i;
- int c;
if (!bmap)
return;
if (EXT2FS_IS_32_BITMAP(bmap)) {
- if ((arg+num) & ~0xffffffff) {
+ if ((arg+num) & ~0xffffffffULL) {
ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
EXT2FS_UNMARK_ERROR, 0xffffffff);
return;
}
- for (i = arg, c = num; c > 0; c--)
+ for (i = 0; i < num; i++)
ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap)
- bmap, i);
+ bmap, arg + i);
return;
}
@@ -356,14 +445,186 @@ void ext2fs_unmark_generic_bmap_extent(ext2fs_generic_bitmap64 bmap,
bmap->bitmap_ops->unmark_bmap_extent(bmap, arg, num);
}
-errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap64 bitmap,
+errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap64 bmap,
__u64 start, unsigned int num,
void *in)
{
+ if (!bmap)
+ return EINVAL;
+
+ if (EXT2FS_IS_32_BITMAP(bmap)) {
+ if ((start+num) & ~0xffffffffULL) {
+ ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
+ EXT2FS_UNMARK_ERROR, 0xffffffff);
+ return EINVAL;
+ }
+ return ext2fs_set_generic_bitmap_range((ext2fs_generic_bitmap) bmap,
+ bmap->magic, start, num,
+ in);
+ }
+
+ if (!EXT2FS_IS_64_BITMAP(bmap))
+ return EINVAL;
+
+ return bmap->bitmap_ops->set_bmap_range(bmap, start, num, in);
}
-errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap64 bitmap,
+errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap64 bmap,
__u64 start, unsigned int num,
void *out)
{
+ if (!bmap)
+ return EINVAL;
+
+ if (EXT2FS_IS_32_BITMAP(bmap)) {
+ if ((start+num) & ~0xffffffffULL) {
+ ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
+ EXT2FS_UNMARK_ERROR, 0xffffffff);
+ return EINVAL;
+ }
+ return ext2fs_get_generic_bitmap_range((ext2fs_generic_bitmap) bmap,
+ bmap->magic, start, num,
+ out);
+ }
+
+ if (!EXT2FS_IS_64_BITMAP(bmap))
+ return EINVAL;
+
+ return bmap->bitmap_ops->get_bmap_range(bmap, start, num, out);
+}
+
+errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
+ ext2fs_generic_bitmap64 bm1,
+ ext2fs_generic_bitmap64 bm2)
+{
+ blk64_t i;
+
+ if (!bm1 || !bm2)
+ return EINVAL;
+ if (bm1->magic != bm2->magic)
+ return EINVAL;
+
+ /* Now we know both bitmaps have the same magic */
+ if (EXT2FS_IS_32_BITMAP(bm1))
+ return ext2fs_compare_generic_bitmap(bm1->magic, neq,
+ (ext2fs_generic_bitmap) bm1,
+ (ext2fs_generic_bitmap) bm2);
+
+ if (!EXT2FS_IS_64_BITMAP(bm1))
+ return EINVAL;
+
+ if ((bm1->start != bm2->start) ||
+ (bm1->end != bm2->end))
+ 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))
+ return neq;
+
+ return 0;
+}
+
+void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap64 bmap)
+{
+ __u64 start, num;
+
+ if (EXT2FS_IS_32_BITMAP(bmap)) {
+ ext2fs_set_generic_bitmap_padding((ext2fs_generic_bitmap) bmap);
+ return;
+ }
+
+ start = bmap->end + 1;
+ num = bmap->real_end - bmap->end;
+ bmap->bitmap_ops->mark_bmap_extent(bmap, start, num);
+ /* XXX ought to warn on error */
+}
+
+int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap64 bmap,
+ blk64_t block, int num)
+{
+ int i;
+
+ if (!bmap)
+ return EINVAL;
+
+ if (EXT2FS_IS_32_BITMAP(bmap)) {
+ if ((block+num) & ~0xffffffffULL) {
+ ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
+ EXT2FS_UNMARK_ERROR, 0xffffffff);
+ return EINVAL;
+ }
+ return ext2fs_test_block_bitmap_range((ext2fs_generic_bitmap) bmap,
+ block, num);
+ }
+
+ if (!EXT2FS_IS_64_BITMAP(bmap))
+ return EINVAL;
+
+ if ((block < bmap->start) || (block+num-1 > bmap->real_end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+ block, bmap->description);
+ return 0;
+ }
+ for (i=0; i < num; i++) {
+ if (ext2fs_fast_test_block_bitmap2(bmap, block+i))
+ return 0;
+ }
+ return 1;
+}
+
+void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap64 bmap,
+ blk64_t block, int num)
+{
+ if (!bmap)
+ return;
+
+ if (EXT2FS_IS_32_BITMAP(bmap)) {
+ if ((block+num) & ~0xffffffffULL) {
+ ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
+ EXT2FS_UNMARK_ERROR, 0xffffffff);
+ return;
+ }
+ ext2fs_mark_block_bitmap_range((ext2fs_generic_bitmap) bmap,
+ block, num);
+ }
+
+ if (!EXT2FS_IS_64_BITMAP(bmap))
+ return;
+
+ if ((block < bmap->start) || (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_bitmap64 bmap,
+ blk64_t block, int num)
+{
+ if (!bmap)
+ return;
+
+ if (EXT2FS_IS_32_BITMAP(bmap)) {
+ if ((block+num) & ~0xffffffffULL) {
+ ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
+ EXT2FS_UNMARK_ERROR, 0xffffffff);
+ return;
+ }
+ ext2fs_unmark_block_bitmap_range((ext2fs_generic_bitmap) bmap,
+ block, num);
+ }
+
+ if (!EXT2FS_IS_64_BITMAP(bmap))
+ return;
+
+ if ((block < bmap->start) || (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);
}
--
1.5.6.5
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists