Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 9383e745e23602bc45f9c92184feea59 > files > 45

gfs2-utils-0.1.62-28.el5.src.rpm

commit d6e3399a259167c1762651586ea062cf7d0c6c30
Author: Bob Peterson <bob@ganesha.peterson>
Date:   Wed Nov 25 14:34:08 2009 -0600

    Simplify bitmap/block list structures
    
    This patch eliminates structures within structures to simplify the
    code and improve performance.
    
    rhbz#455300

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);