cluster: RHEL56 - Simplify bitmap/block list structures
Bob Peterson
rpeterso at fedoraproject.org
Sat Apr 10 04:51:57 UTC 2010
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=d6e3399a259167c1762651586ea062cf7d0c6c30
Commit: d6e3399a259167c1762651586ea062cf7d0c6c30
Parent: 3f47f6f9b2dc9f8e1dbfc27158d6bc1f64ad5cac
Author: Bob Peterson <bob at ganesha.peterson>
AuthorDate: Wed Nov 25 14:34:08 2009 -0600
Committer: Bob Peterson <rpeterso at redhat.com>
CommitterDate: Fri Apr 9 22:45:45 2010 -0500
Simplify bitmap/block list structures
This patch eliminates structures within structures to simplify the
code and improve performance.
rhbz#455300
---
gfs2/edit/savemeta.c | 8 +-
gfs2/fsck/fsck.h | 2 +-
gfs2/fsck/initialize.c | 4 +-
gfs2/fsck/main.c | 2 +-
gfs2/libgfs2/block_list.c | 166 ++++++++++++++++++++++++++++++++++++++++-----
gfs2/libgfs2/libgfs2.h | 48 +++++---------
6 files changed, 172 insertions(+), 58 deletions(-)
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 8959442..50c9e2a 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -47,7 +47,7 @@ struct saved_metablock {
struct saved_metablock *savedata;
uint64_t last_fs_block, last_reported_block, blks_saved, total_out, pct;
-struct gfs2_block_list *blocklist = NULL;
+struct gfs2_bmap *blocklist = NULL;
uint64_t journal_blocks[MAX_JOURNALS_SAVED];
uint64_t gfs1_journal_size = 0; /* in blocks */
int journals_found = 0;
@@ -588,8 +588,8 @@ void savemeta(char *out_fn, int saveoption)
fflush(stdout);
}
if (!slow) {
- blocklist = gfs2_block_list_create(&sbd, last_fs_block + 1,
- &memreq);
+ blocklist = gfs2_bmap_create(&sbd, last_fs_block + 1,
+ &memreq);
if (!blocklist)
slow = TRUE;
}
@@ -683,7 +683,7 @@ void savemeta(char *out_fn, int saveoption)
}
/* Clean up */
if (blocklist)
- gfs2_block_list_destroy(&sbd, blocklist);
+ gfs2_bmap_destroy(&sbd, blocklist);
/* There may be a gap between end of file system and end of device */
/* so we tell the user that we've processed everything. */
block = last_fs_block;
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 57dd6b4..7cf0d8b 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -97,7 +97,7 @@ extern struct gfs2_options opts;
extern struct gfs2_inode *lf_dip; /* Lost and found directory inode */
extern osi_list_t dir_hash[FSCK_HASH_SIZE];
extern osi_list_t inode_hash[FSCK_HASH_SIZE];
-extern struct gfs2_block_list *bl;
+extern struct gfs2_bmap *bl;
extern uint64_t last_fs_block, last_reported_block;
extern int skip_this_pass, fsck_abort;
extern int errors_found, errors_corrected;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 67fa1fb..5985919 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -115,7 +115,7 @@ static void empty_super_block(struct gfs2_sbd *sdp)
}
if (bl)
- gfs2_block_list_destroy(sdp, bl);
+ gfs2_bmap_destroy(sdp, bl);
}
@@ -271,7 +271,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
goto fail;
}
- bl = gfs2_block_list_create(sdp, last_fs_block+1, &addl_mem_needed);
+ bl = gfs2_bmap_create(sdp, last_fs_block+1, &addl_mem_needed);
if (!bl) {
log_crit( _("This system doesn't have enough memory + swap space to fsck this file system.\n"));
log_crit( _("Additional memory needed is approximately: %lluMB\n"),
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 56ac943..9da8dd2 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -32,7 +32,7 @@ struct gfs2_options opts = {0};
struct gfs2_inode *lf_dip; /* Lost and found directory inode */
osi_list_t dir_hash[FSCK_HASH_SIZE];
osi_list_t inode_hash[FSCK_HASH_SIZE];
-struct gfs2_block_list *bl = NULL;
+struct gfs2_bmap *bl = NULL;
uint64_t last_fs_block, last_reported_block = -1;
int skip_this_pass = FALSE, fsck_abort = FALSE;
int errors_found = 0, errors_corrected = 0;
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index c67c5a4..19e91df 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -29,19 +29,150 @@ static int mark_to_gbmap[16] = {
INVALID_META, INVALID_META
};
-struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
- uint64_t size,
- uint64_t *addl_mem_needed)
+#define BITMAP_SIZE(size, cpb) (size / cpb)
+#define BITMAP_SIZE1(size) (size >> 3)
+#define BITMAP_SIZE4(size) (size >> 1)
+
+#define BITMAP_BYTE_OFFSET(x, map) ((x % map->chunks_per_byte) \
+ * map->chunksize )
+
+/* BITMAP_BYTE_OFFSET1 is for chunksize==1, which implies chunks_per_byte==8 */
+/* Reducing the math, we get: */
+/* #define BITMAP_BYTE_OFFSET1(x) ((x % 8) * 1) */
+/* #define BITMAP_BYTE_OFFSET1(x) (x % 8) */
+/* #define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007) */
+#define BITMAP_BYTE_OFFSET1(x) (x & 0x0000000000000007)
+
+/* BITMAP_BYTE_OFFSET4 is for chunksize==4, which implies chunks_per_byte==2 */
+/* Reducing the math, we get: */
+/* #define BITMAP_BYTE_OFFSET4(x) ((x % 2) * 4) */
+/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) * 4) */
+/* #define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2) */
+#define BITMAP_BYTE_OFFSET4(x) ((x & 0x0000000000000001) << 2)
+
+#define BITMAP_MASK(chunksize) ((2 << (chunksize - 1)) - 1)
+/* BITMAP_MASK1 is for chunksize==1 */
+/* Reducing the math, we get: */
+/* #define BITMAP_MASK1(chunksize) ((2 << (1 - 1)) - 1) */
+/* #define BITMAP_MASK1(chunksize) ((2 << 0) - 1) */
+/* #define BITMAP_MASK1(chunksize) ((2) - 1) */
+#define BITMAP_MASK1(chunksize) (1)
+
+/* BITMAP_MASK4 is for chunksize==4 */
+/* #define BITMAP_MASK(chunksize) ((2 << (4 - 1)) - 1) */
+/* #define BITMAP_MASK(chunksize) ((2 << 3) - 1) */
+/* #define BITMAP_MASK(chunksize) (0x10 - 1) */
+#define BITMAP_MASK4(chunksize) (0xf)
+
+static int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size,
+ uint8_t chunksize)
{
- struct gfs2_block_list *il;
+ if((((chunksize >> 1) << 1) != chunksize) && chunksize != 1)
+ return -1;
+ if(chunksize > 8)
+ return -1;
+ bmap->chunksize = chunksize;
+ bmap->chunks_per_byte = 8 / chunksize;
+
+ bmap->size = size;
+
+ /* Have to add 1 to BITMAP_SIZE since it's 0-based and mallocs
+ * must be 1-based */
+ bmap->mapsize = BITMAP_SIZE(size, bmap->chunks_per_byte)+1;
+
+ if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
+ return -ENOMEM;
+ if(!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) {
+ free(bmap->map);
+ bmap->map = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int gfs2_bitmap_set(struct gfs2_bmap *bmap, uint64_t offset, uint8_t val)
+{
+ static char *byte;
+ static uint64_t b;
+
+ if(offset < bmap->size) {
+ if (bmap->chunksize == 1) {
+ byte = bmap->map + BITMAP_SIZE1(offset);
+ b = BITMAP_BYTE_OFFSET1(offset);
+ *byte |= (val & BITMAP_MASK1(bmap->chunksize));
+ } else {
+ byte = bmap->map + BITMAP_SIZE4(offset);
+ b = BITMAP_BYTE_OFFSET4(offset);
+ *byte |= (val & BITMAP_MASK4(bmap->chunksize)) << b;
+ }
+ return 0;
+ }
+ return -1;
+}
+
+static int gfs2_bitmap_get(struct gfs2_bmap *bmap, uint64_t bit, uint8_t *val)
+{
+ static char *byte;
+ static uint64_t b;
+
+ if(bit < bmap->size) {
+ if (bmap->chunksize == 1) {
+ byte = bmap->map + BITMAP_SIZE1(bit);
+ b = BITMAP_BYTE_OFFSET1(bit);
+ *val = (*byte & (BITMAP_MASK1(bmap->chunksize) << b )) >> b;
+ } else {
+ byte = bmap->map + BITMAP_SIZE4(bit);
+ b = BITMAP_BYTE_OFFSET4(bit);
+ *val = (*byte & (BITMAP_MASK4(bmap->chunksize) << b )) >> b;
+ }
+ return 0;
+ }
+ return -1;
+}
+
+static int gfs2_bitmap_clear(struct gfs2_bmap *bmap, uint64_t offset)
+{
+ static char *byte;
+ static uint64_t b;
+
+ if(offset < bmap->size) {
+ if (bmap->chunksize == 1) {
+ byte = bmap->map + BITMAP_SIZE1(offset);
+ b = BITMAP_BYTE_OFFSET1(offset);
+ *byte &= ~(BITMAP_MASK1(bmap->chunksize) << b);
+ } else {
+ byte = bmap->map + BITMAP_SIZE4(offset);
+ b = BITMAP_BYTE_OFFSET4(offset);
+ *byte &= ~(BITMAP_MASK4(bmap->chunksize) << b);
+ }
+ return 0;
+ }
+ return -1;
+
+}
+
+static void gfs2_bitmap_destroy(struct gfs2_bmap *bmap)
+{
+ if(bmap->map)
+ free(bmap->map);
+ bmap->size = 0;
+ bmap->mapsize = 0;
+ bmap->chunksize = 0;
+ bmap->chunks_per_byte = 0;
+}
+
+struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed)
+{
+ struct gfs2_bmap *il;
*addl_mem_needed = 0L;
il = malloc(sizeof(*il));
if (!il || !memset(il, 0, sizeof(*il)))
return NULL;
- if(gfs2_bitmap_create(&il->list.gbmap, size, 4)) {
- *addl_mem_needed = il->list.gbmap.mapsize;
+ if(gfs2_bitmap_create(il, size, 4)) {
+ *addl_mem_needed = il->mapsize;
free(il);
il = NULL;
}
@@ -156,7 +287,7 @@ static void gfs2_dup_clear(struct dup_blocks *blocklist, uint64_t block)
}
}
-int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark)
{
int err = 0;
@@ -166,13 +297,12 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
else if(mark == gfs2_eattr_block)
gfs2_special_set(&sdp->eattr_blocks, block);
else
- err = gfs2_bitmap_set(&il->list.gbmap, block,
- mark_to_gbmap[mark]);
+ err = gfs2_bitmap_set(il, block, mark_to_gbmap[mark]);
return err;
}
/* gfs2_block_unmark clears ONE mark for the given block */
-int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark)
{
int err = 0;
@@ -186,25 +316,25 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
break;
default:
/* FIXME: check types */
- err = gfs2_bitmap_clear(&il->list.gbmap, block);
+ err = gfs2_bitmap_clear(il, block);
break;
}
return err;
}
/* gfs2_block_clear clears all the marks for the given block */
-int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block)
{
int err = 0;
gfs2_dup_clear(&sdp->dup_blocks, block);
gfs2_special_clear(&sdp->eattr_blocks, block);
- err = gfs2_bitmap_clear(&il->list.gbmap, block);
+ err = gfs2_bitmap_clear(il, block);
return err;
}
-int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, enum gfs2_mark_block mark)
{
int err;
@@ -215,7 +345,7 @@ int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
return err;
}
-int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
+int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
uint64_t block, struct gfs2_block_query *val)
{
int err = 0;
@@ -226,15 +356,15 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
val->dup_block = 1;
if (blockfind(&sdp->eattr_blocks, block))
val->eattr_block = 1;
- if((err = gfs2_bitmap_get(&il->list.gbmap, block, &val->block_type)))
+ if((err = gfs2_bitmap_get(il, block, &val->block_type)))
return err;
return 0;
}
-void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, struct gfs2_block_list *il)
+void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
{
if(il) {
- gfs2_bitmap_destroy(&il->list.gbmap);
+ gfs2_bitmap_destroy(il);
free(il);
il = NULL;
}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index a9aeb2a..fc8af3f 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -301,11 +301,6 @@ struct gfs2_bmap {
char *map;
};
-int gfs2_bitmap_create(struct gfs2_bmap *bmap, uint64_t size, uint8_t bitsize);
-int gfs2_bitmap_set(struct gfs2_bmap *bmap, uint64_t offset, uint8_t val);
-int gfs2_bitmap_get(struct gfs2_bmap *bmap, uint64_t bit, uint8_t *val);
-int gfs2_bitmap_clear(struct gfs2_bmap *bmap, uint64_t offset);
-void gfs2_bitmap_destroy(struct gfs2_bmap *bmap);
uint64_t gfs2_bitmap_size(struct gfs2_bmap *bmap);
/* block_list.c */
@@ -354,35 +349,24 @@ struct gfs2_block_query {
uint8_t eattr_block;
};
-union gfs2_block_lists {
- struct gfs2_bmap gbmap;
-};
-
-/* bitmap implementation */
-struct gfs2_block_list {
- union gfs2_block_lists list;
-};
-
-struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
- uint64_t size,
- uint64_t *addl_mem_needed);
-struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num);
-void gfs2_special_set(struct special_blocks *blocklist, uint64_t block);
-void gfs2_special_free(struct special_blocks *blist);
-int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block, enum gfs2_mark_block mark);
-int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block, enum gfs2_mark_block mark);
+extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+ uint64_t *addl_mem_needed);
+extern struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num);
+extern void gfs2_special_set(struct special_blocks *blocklist, uint64_t block);
+extern void gfs2_special_free(struct special_blocks *blist);
+extern int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block, enum gfs2_mark_block mark);
+extern int gfs2_block_set(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block, enum gfs2_mark_block mark);
/* gfs2_block_unmark clears ONE mark for the given block */
-int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block, enum gfs2_mark_block m);
+extern int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block, enum gfs2_mark_block m);
/* gfs2_block_clear clears all the marks for the given block */
-int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block);
-int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
- uint64_t block, struct gfs2_block_query *val);
-void *gfs2_block_list_destroy(struct gfs2_sbd *sdp,
- struct gfs2_block_list *il);
+extern int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block);
+extern int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_bmap *il,
+ uint64_t block, struct gfs2_block_query *val);
+extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
/* buf.c */
void init_buf_list(struct gfs2_sbd *sdp, struct buf_list *bl, uint32_t limit);
More information about the cluster-commits
mailing list