cluster: STABLE3 - libgfs2: fs_bits speed up bitmap operations

Bob Peterson rpeterso at fedoraproject.org
Tue Jan 26 21:19:40 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=c0c86631cd56ee2f91295034a039685044fc11b7
Commit:        c0c86631cd56ee2f91295034a039685044fc11b7
Parent:        324588669d02c9a1e1d2fe3ba3b8edf11863721b
Author:        Bob Peterson <bob at ganesha.peterson>
AuthorDate:    Thu Jan 21 08:50:05 2010 -0600
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Tue Jan 26 14:39:28 2010 -0600

libgfs2: fs_bits speed up bitmap operations

This patch incorporates a faster set of bitmap operations once
used by the kernel code and currently used by GFS1.

rhbz#455300
---
 gfs2/libgfs2/fs_bits.c |   77 +++++++++++++++++++++++++++++++++++-------------
 1 files changed, 56 insertions(+), 21 deletions(-)

diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index e657aa5..c420dfc 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -5,6 +5,18 @@
 
 #include "libgfs2.h"
 
+#if BITS_PER_LONG == 32
+#define LBITMASK   (0x55555555UL)
+#define LBITSKIP55 (0x55555555UL)
+#define LBITSKIP00 (0x00000000UL)
+#else
+#define LBITMASK   (0x5555555555555555UL)
+#define LBITSKIP55 (0x5555555555555555UL)
+#define LBITSKIP00 (0x0000000000000000UL)
+#endif
+
+#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
+
 /**
  * gfs2_bitfit - Find a free block in the bitmaps
  * @buffer: the buffer that holds the bitmaps
@@ -18,32 +30,55 @@
 uint32_t gfs2_bitfit(unsigned char *buffer, unsigned int buflen,
 		     uint32_t goal, unsigned char old_state)
 {
-	unsigned char *byte, *end, alloc;
-	uint32_t blk = goal;
-	unsigned int bit;
-
-	byte = buffer + (goal / GFS2_NBBY);
-	bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE;
-	end = buffer + buflen;
-	alloc = (old_state & 1) ? 0 : 0x55;
-
-	while (byte < end){
-		if ((*byte & 0x55) == alloc){
-			blk += (8 - bit) >> 1;
-			bit = 0;
-			byte++;
-			continue;
+	const uint8_t *byte, *start, *end;
+	int bit, startbit;
+	uint32_t g1, g2, misaligned;
+	unsigned long *plong;
+	unsigned long lskipval;
+
+	lskipval = (old_state & GFS2_BLKST_USED) ? LBITSKIP00 : LBITSKIP55;
+	g1 = (goal / GFS2_NBBY);
+	start = buffer + g1;
+	byte = start;
+        end = buffer + buflen;
+	g2 = ALIGN(g1, sizeof(unsigned long));
+	plong = (unsigned long *)(buffer + g2);
+	startbit = bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE;
+	misaligned = g2 - g1;
+	if (!misaligned)
+		goto ulong_aligned;
+/* parse the bitmap a byte at a time */
+misaligned:
+	while (byte < end) {
+		if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) {
+			return goal +
+				(((byte - start) * GFS2_NBBY) +
+				 ((bit - startbit) >> 1));
 		}
-
-		if (((*byte >> bit) & GFS2_BIT_MASK) == old_state)
-			return blk;
-
 		bit += GFS2_BIT_SIZE;
-		if (bit >= 8){
+		if (bit >= GFS2_NBBY * GFS2_BIT_SIZE) {
 			bit = 0;
 			byte++;
+			misaligned--;
+			if (!misaligned) {
+				plong = (unsigned long *)byte;
+				goto ulong_aligned;
+			}
 		}
-		blk++;
+	}
+	return BFITNOENT;
+
+/* parse the bitmap a unsigned long at a time */
+ulong_aligned:
+	while ((unsigned char *)plong < end) {
+		if (((*plong) & LBITMASK) != lskipval)
+			break;
+		plong++;
+	}
+	if ((unsigned char *)plong < end) {
+		byte = (const uint8_t *)plong;
+		misaligned += sizeof(unsigned long) - 1;
+		goto misaligned;
 	}
 	return BFITNOENT;
 }


More information about the cluster-commits mailing list