Skip to contentSkip to conversation

XFS bitops to Linux again

PATCH In review Andi Kleen 4 participants 7 messages Oct 3, 2007 – Oct 4, 2007 XFS filesystem

lore
Share & tools
lore

Andi Kleen

author
#0 lore raw

PATCH 1/1 XFS bitops to Linux again

This time against CVS

Replace XFS bit functions with call Linux functions

XFS had some own functions to find high and low bits.

This patch replaces them with a call to the respective Linux functions. The semantics of the Linux functions differ a little, but i checked all call sites that they can deal with that.

The resulting xfs.ko is about 500 bytes smaller on x86-64

fs/xfs/xfs_bit.c +1 -104
Index: linux-2.6-xfs/fs/xfs/xfs_bit.c
===================================================================
@@ -22,112 +22,9 @@
 #include "xfs_buf_item.h"
 
 /*
- * XFS bit manipulation routines, used in non-realtime code.
+ * XFS bit manipulation routines
  */
 
-#ifndef HAVE_ARCH_HIGHBIT
-/*
- * Index of high bit number in byte, -1 for none set, 0..7 otherwise.
- */
-static const char xfs_highbit[256] = {
-       -1, 0, 1, 1, 2, 2, 2, 2,			/* 00 .. 07 */
-	3, 3, 3, 3, 3, 3, 3, 3,			/* 08 .. 0f */
-	4, 4, 4, 4, 4, 4, 4, 4,			/* 10 .. 17 */
-	4, 4, 4, 4, 4, 4, 4, 4,			/* 18 .. 1f */
-	5, 5, 5, 5, 5, 5, 5, 5,			/* 20 .. 27 */
-	5, 5, 5, 5, 5, 5, 5, 5,			/* 28 .. 2f */
-	5, 5, 5, 5, 5, 5, 5, 5,			/* 30 .. 37 */
-	5, 5, 5, 5, 5, 5, 5, 5,			/* 38 .. 3f */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 40 .. 47 */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 48 .. 4f */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 50 .. 57 */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 58 .. 5f */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 60 .. 67 */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 68 .. 6f */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 70 .. 77 */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 78 .. 7f */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* 80 .. 87 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* 88 .. 8f */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* 90 .. 97 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* 98 .. 9f */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* a0 .. a7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* a8 .. af */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* b0 .. b7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* b8 .. bf */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* c0 .. c7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* c8 .. cf */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* d0 .. d7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* d8 .. df */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* e0 .. e7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* e8 .. ef */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* f0 .. f7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* f8 .. ff */
-};
-#endif
-
-/*
- * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set.
- */
-inline int
-xfs_highbit32(
-	__uint32_t	v)
-{
-#ifdef HAVE_ARCH_HIGHBIT
-	return highbit32(v);
-#else
-	int		i;
-
-	if (v & 0xffff0000)
-		if (v & 0xff000000)
-			i = 24;
-		else
-			i = 16;
-	else if (v & 0x0000ffff)
-		if (v & 0x0000ff00)
-			i = 8;
-		else
-			i = 0;
-	else
-		return -1;
-	return i + xfs_highbit[(v >> i) & 0xff];
-#endif
-}
-
-/*
- * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set.
- */
-int
-xfs_lowbit64(
-	__uint64_t	v)
-{
-	__uint32_t	w = (__uint32_t)v;
-	int		n = 0;
-
-	if (w) {	/* lower bits */
-		n = ffs(w);
-	} else {	/* upper bits */
-		w = (__uint32_t)(v >> 32);
-		if (w && (n = ffs(w)))
-			n += 32;
-	}
-	return n - 1;
-}
-
-/*
- * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set.
- */
-int
-xfs_highbit64(
-	__uint64_t	v)
-{
-	__uint32_t	h = (__uint32_t)(v >> 32);
-
-	if (h)
-		return xfs_highbit32(h) + 32;
-	return xfs_highbit32((__uint32_t)v);
-}
-
-
 /*
  * Return whether bitmap is empty.
  * Size is number of words in the bitmap, which is padded to word boundary
fs/xfs/xfs_bit.h +0 -9
Index: linux-2.6-xfs/fs/xfs/xfs_bit.h
===================================================================
@@ -46,15 +46,6 @@ static inline __uint64_t xfs_mask64lo(in
 	return ((__uint64_t)1 << (n)) - 1;
 }
 
-/* Get high bit set out of 32-bit argument, -1 if none set */
-extern int xfs_highbit32(__uint32_t v);
-
-/* Get low bit set out of 64-bit argument, -1 if none set */
-extern int xfs_lowbit64(__uint64_t v);
-
-/* Get high bit set out of 64-bit argument, -1 if none set */
-extern int xfs_highbit64(__uint64_t);
-
 /* Return whether bitmap is empty (1 == empty) */
 extern int xfs_bitmap_empty(uint *map, uint size);
 
fs/xfs/xfs_mount.c +4 -4
Index: linux-2.6-xfs/fs/xfs/xfs_mount.c
===================================================================
@@ -479,7 +479,7 @@ xfs_sb_to_disk(
 		return;
 
 	while (fields) {
-		f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
+		f = (xfs_sb_field_t)find_first_bit((unsigned long *)&fields,64);
 		first = xfs_sb_info[f].offset;
 		size = xfs_sb_info[f + 1].offset - first;
 
@@ -621,7 +621,7 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb
 	mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
 	mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
 	mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
-	mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
+	mp->m_agno_log = fls(sbp->sb_agcount - 1);
 	mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
 	mp->m_litino = sbp->sb_inodesize -
 		((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t));
@@ -1420,11 +1420,11 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fi
 
 	/* find modified range */
 
-	f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
+	f = (xfs_sb_field_t)find_first_bit((unsigned long *)&fields, 64);
 	ASSERT((1LL << f) & XFS_SB_MOD_BITS);
 	first = xfs_sb_info[f].offset;
 
-	f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields);
+	f = (xfs_sb_field_t)fls64((__uint64_t)fields) - 1;
 	ASSERT((1LL << f) & XFS_SB_MOD_BITS);
 	last = xfs_sb_info[f + 1].offset - 1;
 
fs/xfs/xfs_rtalloc.h +10 -4
Index: linux-2.6-xfs/fs/xfs/xfs_rtalloc.h
===================================================================
@@ -60,13 +60,19 @@ struct xfs_trans;
 #define	XFS_RTMIN(a,b)	((a) < (b) ? (a) : (b))
 #define	XFS_RTMAX(a,b)	((a) > (b) ? (a) : (b))
 
-#define	XFS_RTLOBIT(w)	xfs_lowbit32(w)
-#define	XFS_RTHIBIT(w)	xfs_highbit32(w)
+/* All callers check for 0 arguments already; so no -1 handling */
+static inline int xfs_rtlobit(unsigned long v)
+{
+	return find_first_bit(&v, 32);
+}
+
+#define	XFS_RTLOBIT(w)  xfs_rtlobit(w)
+#define	XFS_RTHIBIT(w)  (fls(w) - 1)
 
 #if XFS_BIG_BLKNOS
-#define	XFS_RTBLOCKLOG(b)	xfs_highbit64(b)
+#define	XFS_RTBLOCKLOG(b)	(fls64(b) - 1)
 #else
-#define	XFS_RTBLOCKLOG(b)	xfs_highbit32(b)
+#define	XFS_RTBLOCKLOG(b)	(fls(b) - 1)
 #endif
 
 
fs/xfs/xfs_rtalloc.c +14 -20
Index: linux-2.6-xfs/fs/xfs/xfs_rtalloc.c
===================================================================
@@ -73,18 +73,6 @@ STATIC int xfs_rtmodify_summary(xfs_moun
  */
 
 /*
- * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set.
- */
-STATIC int
-xfs_lowbit32(
-	__uint32_t	v)
-{
-	if (v)
-		return ffs(v) - 1;
-	return -1;
-}
-
-/*
  * Allocate space to the bitmap or summary file, and zero it, for growfs.
  */
 STATIC int				/* error */
@@ -444,7 +432,8 @@ xfs_rtallocate_extent_near(
 	}
 	bbno = XFS_BITTOBLOCK(mp, bno);
 	i = 0;
-	log2len = xfs_highbit32(minlen);
+	ASSERT(minlen != 0);
+	log2len = fls(minlen) - 1;
 	/*
 	 * Loop over all bitmap blocks (bbno + i is current block).
 	 */
@@ -607,11 +596,13 @@ xfs_rtallocate_extent_size(
 	int		error;		/* error value */
 	int		i;		/* bitmap block number */
 	int		l;		/* level number (loop control) */
+	int 		end;
 	xfs_rtblock_t	n;		/* next block to be tried */
 	xfs_rtblock_t	r;		/* result block number */
 	xfs_suminfo_t	sum;		/* summary information for extents */
 
 	ASSERT(minlen % prod == 0 && maxlen % prod == 0);
+	ASSERT(maxlen != 0);
 	/*
 	 * Loop over all the levels starting with maxlen.
 	 * At each level, look at all the bitmap blocks, to see if there
@@ -619,7 +610,7 @@ xfs_rtallocate_extent_size(
 	 * Note, only on the initial level can the allocation fail if
 	 * the summary says there's an extent.
 	 */
-	for (l = xfs_highbit32(maxlen); l < mp->m_rsumlevels; l++) {
+	for (l = fls(maxlen) - 1; l < mp->m_rsumlevels; l++) {
 		/*
 		 * Loop over all the bitmap blocks.
 		 */
@@ -669,12 +660,15 @@ xfs_rtallocate_extent_size(
 		*rtblock = NULLRTBLOCK;
 		return 0;
 	}
+	ASSERT(maxlen != 0);
+	ASSERT(minlen != 0);
 	/*
 	 * Loop over sizes, from maxlen down to minlen.
 	 * This time, when we do the allocations, allow smaller ones
 	 * to succeed.
 	 */
-	for (l = xfs_highbit32(maxlen); l >= xfs_highbit32(minlen); l--) {
+	end = fls(minlen) - 1;
+	for (l = fls(maxlen) - 1; l >= end; l--) {
 		/*
 		 * Loop over all the bitmap blocks, try an allocation
 		 * starting in that block.
@@ -1863,7 +1857,6 @@ xfs_growfs_rt(
 	xfs_drfsbno_t	nrblocks;	/* new number of realtime blocks */
 	xfs_extlen_t	nrbmblocks;	/* new number of rt bitmap blocks */
 	xfs_drtbno_t	nrextents;	/* new number of realtime extents */
-	uint8_t		nrextslog;	/* new log2 of sb_rextents */
 	xfs_extlen_t	nrsumblocks;	/* new number of summary blocks */
 	uint		nrsumlevels;	/* new rt summary levels */
 	uint		nrsumsize;	/* new size of rt summary, bytes */
@@ -1900,8 +1893,7 @@ xfs_growfs_rt(
 	nrextents = nrblocks;
 	do_div(nrextents, in->extsize);
 	nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize);
-	nrextslog = xfs_highbit32(nrextents);
-	nrsumlevels = nrextslog + 1;
+	nrsumlevels = fls(nrextents);
 	nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
 	nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
 	nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
@@ -1954,7 +1946,8 @@ xfs_growfs_rt(
 				  nsbp->sb_blocksize * nsbp->sb_rextsize);
 		nsbp->sb_rextents = nsbp->sb_rblocks;
 		do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
-		nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
+		ASSERT(nsbp->sb_rextents != 0);
+		nsbp->sb_rextslog = fls(nsbp->sb_rextents) - 1;
 		nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
 		nrsumsize =
 			(uint)sizeof(xfs_suminfo_t) * nrsumlevels *
@@ -2317,9 +2310,10 @@ xfs_rtpick_extent(
 		*seqp = 0;
 	}
 	seq = *seqp;
-	if ((log2 = xfs_highbit64(seq)) == -1)
+	if ((log2 = fls64(seq)) == 0)
 		b = 0;
 	else {
+		log2--;
 		resid = seq - (1ULL << log2);
 		b = (mp->m_sb.sb_rextents * ((resid << 1) + 1ULL)) >>
 		    (log2 + 1);
fs/xfs/xfs_ialloc.h +2 -2
Index: linux-2.6-xfs/fs/xfs/xfs_ialloc.h
===================================================================
@@ -52,10 +52,10 @@ xfs_make_iptr(struct xfs_mount *mp, stru
 #define	XFS_IALLOC_FIND_FREE(fp)	xfs_ialloc_find_free(fp)
 static inline int xfs_ialloc_find_free(xfs_inofree_t *fp)
 {
-	return xfs_lowbit64(*fp);
+	unsigned long v = *fp; /* Guarantee alignment */
+	return find_first_bit(&v, 64);
 }
 
-
 #ifdef __KERNEL__
 /*
  * Allocate an inode on disk.
fs/xfs/linux-2.6/xfs_ksyms.c +0 -2
Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_ksyms.c
===================================================================
@@ -222,8 +222,6 @@ EXPORT_SYMBOL(xfs_file_last_byte);
 EXPORT_SYMBOL(xfs_finish_reclaim_all);
 EXPORT_SYMBOL(xfs_freesb);
 EXPORT_SYMBOL(xfs_fs_cmn_err);
-EXPORT_SYMBOL(xfs_highbit32);
-EXPORT_SYMBOL(xfs_highbit64);
 EXPORT_SYMBOL(xfs_idestroy);
 EXPORT_SYMBOL(xfs_iaccess);
 EXPORT_SYMBOL(xfs_iextract);
#1 lore raw
Quoted 10 lines

This time against CVS

Replace XFS bit functions with call Linux functions

XFS had some own functions to find high and low bits.

This patch replaces them with a call to the respective Linux functions. The semantics of the Linux functions differ a little, but i checked all call sites that they can deal with that.

Several of these call sites are also compiled in userspace in libxfs. It would
be a good idea from that POV also to keep some level of abstraction so that these calls can be mapped to userspace routines as well.

Quoted 1 line

The resulting xfs.ko is about 500 bytes smaller on x86-64

Thats it? To be honest, this sounds like just code churn and risk introduction.
What testing was done? Changes to some of these routines has introuced subtle log recovery bugs in the past - has recovery been tested at all? The QA
suite has some log recovery tests, it'd be a good idea to verify with those..

cheers.

--
Nathan

author
#2 lore raw
Quoted 5 lines

Several of these call sites are also compiled in userspace in libxfs. It would
be a good idea from that POV also to keep some level of abstraction so that these calls can be mapped to userspace routines as well.

Again the same argument applies -- there is no difference if you map xfs_(high|low)bit or fls64/fls/find_find_bit() to something else.

Quoted 3 lines
Quoted 1 line

The resulting xfs.ko is about 500 bytes smaller on x86-64

Thats it?

It's probably a little faster too (admittedly unlikely to be really measurable in a macro benchmark) and the source code is smaller.

Quoted 5 lines

What testing was done? Changes to some of these routines has introuced subtle log recovery bugs in the past - has recovery been tested at all? The QA
suite has some log recovery tests, it'd be a good idea to verify with those..

I had a simple separate unit test to verify the 32bit space gave the same result. The only difference was the 0 case, but I checked all inputs manually. Usually they had != 0 tests already or zero was impossible;
in the few cases were not I added ASSERTs -- so if i got it wrong it should
bomb out quickly.

I did also some simple tests using the QA suite -- i believe a few logs were recovered -- but not the full tests.

Quoted 2 lines

To be honest, this sounds like just code churn and risk introduction.

Ok I got the message. I retract the patch. Sorry for bothering you with lowly cleanups.

-Andi

#3 lore raw
Quoted 7 lines · Andi Kleen
Quoted 2 lines

To be honest, this sounds like just code churn and risk introduction.

Ok I got the message. I retract the patch. Sorry for bothering you with lowly cleanups.

-Andi

Hrmph. I liked it. Every change has risk but why bother duplicating existing kernel infrastructure? Compared to everything else going on lately this hardly seems worth NAKing. (though I'm sure the same complaint/warning/caution could be leveled at the other boatload of changes in the past month).

-Eric

#4 lore raw
In reply to Andi Kleen

Hi Andi,

Quoted 9 lines
Quoted 6 lines

Several of these call sites are also compiled in userspace in libxfs. It
would
be a good idea from that POV also to keep some level of abstraction so that
these calls can be mapped to userspace routines as well.

Again the same argument applies -- there is no difference if you map xfs_(high|low)bit or fls64/fls/find_find_bit() to something else.

Yep, indeed. I guess what I'm saying is "just make sure userspace is fixed up
too". So, when you say "if you map...", instead say "when I did that mapping it
wasn't a problem... patch is included" so that other people (i.e. Barry here) get
less work to do to on the merge (and don't have to cleanup your cleanup).

Quoted 7 lines
Quoted 6 lines

What testing was done? Changes to some of these routines has introuced subtle log recovery bugs in the past - has recovery been tested at all? The QA
suite has some log recovery tests, it'd be a good idea to verify with those..

Quoted 6 lines

I had a simple separate unit test to verify the 32bit space gave the same result. The only difference was the 0 case, but I checked all inputs manually. Usually they had != 0 tests already or zero was impossible;
in the few cases were not I added ASSERTs -- so if i got it wrong it
should
bomb out quickly.

Great. You're light years ahead of the rest of the cleanup brigade. :)

Quoted 4 lines

I did also some simple tests using the QA suite -- i believe a few logs were recovered -- but not the full tests.

From a quick look, tests 085, 086 and 087 are the ones I was thinking of

yesterday.

Quoted 5 lines
Quoted 2 lines

To be honest, this sounds like just code churn and risk introduction.

Ok I got the message. I retract the patch. Sorry for bothering you with lowly cleanups.

Hey, I like cleanup as much as the next guy (as long as the next guy isn't Eric,
he just lives to clean ;) - also always ignores userspace despite knowing better)
- I just don't like seeing more work introduced for the people really fixing stuff.
I'm sure the patch could be merged (given its been tested) if either userspace is
updated too, or the same xfs_* naming convention was kept so that userspace needs no changes.

cheers.

--
Nathan

#5 lore raw
Quoted 1 line · [email protected] wrote:

Great. You're light years ahead of the rest of the cleanup brigade. :)

Hey, I resemble that remark! :)

(FWIW, I too first ran through xfsqa with both calculations in place, and caused it to complain loudly if there was a mismatch. Not 100% coverage, but I'm not trying to do this half-assed either...)

Quoted 6 lines
Quoted 2 lines

I did also some simple tests using the QA suite -- i believe a few logs were recovered -- but not the full tests.

From a quick look, tests 085, 086 and 087 are the ones I was thinking of yesterday.

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

To be honest, this sounds like just code churn and risk introduction.

Ok I got the message. I retract the patch. Sorry for bothering you with lowly cleanups.

Hey, I like cleanup as much as the next guy (as long as the next guy isn't Eric,
he just lives to clean ;)

If I do any real work I might lose my job ;-) </joke>

Quoted 2 lines

- also always ignores userspace despite knowing
better)

Nah, I just forget.

-Eric

#6 lore raw
In reply to Andi Kleen
Quoted 2 lines · Andi Kleen

Ok I got the message. I retract the patch. Sorry for bothering you with lowly cleanups.

Andi, please don't walk away with that attitude. I like the fact your patch makes use of generic code, I just didn't like the way it changed the core XFS code.

I've said exactly the same thing in the past about the removal of the min/max wrapper macros in XFS. we still have the wrapper macros because they help make the code readable, consistent and more maintainable from an _XFS perspective_.

What I'm saying here is consistent with that view - leave the wrappers, replace the implementation. (untested patch that does that below.)

Sorry if I didn't make that clear, but your patches and ideas are appreciated and sometimes we all fall down into being nasty coding style cops. :(

Cheers,

Dave.

Signature · 222 lines
Dave Chinner
Principal Engineer
SGI Australian Software Group

---
 fs/xfs/xfs_bit.c     |  103 ---------------------------------------------------
 fs/xfs/xfs_bit.h     |   27 ++++++++++---
 fs/xfs/xfs_rtalloc.c |   20 +++------
 3 files changed, 30 insertions(+), 120 deletions(-)

Index: 2.6.x-xfs-new/fs/xfs/xfs_bit.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_bit.c	2007-06-20 15:54:59.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_bit.c	2007-10-05 08:48:48.107390247 +1000
@@ -25,109 +25,6 @@
  * XFS bit manipulation routines, used in non-realtime code.
  */
 
-#ifndef HAVE_ARCH_HIGHBIT
-/*
- * Index of high bit number in byte, -1 for none set, 0..7 otherwise.
- */
-static const char xfs_highbit[256] = {
-       -1, 0, 1, 1, 2, 2, 2, 2,			/* 00 .. 07 */
-	3, 3, 3, 3, 3, 3, 3, 3,			/* 08 .. 0f */
-	4, 4, 4, 4, 4, 4, 4, 4,			/* 10 .. 17 */
-	4, 4, 4, 4, 4, 4, 4, 4,			/* 18 .. 1f */
-	5, 5, 5, 5, 5, 5, 5, 5,			/* 20 .. 27 */
-	5, 5, 5, 5, 5, 5, 5, 5,			/* 28 .. 2f */
-	5, 5, 5, 5, 5, 5, 5, 5,			/* 30 .. 37 */
-	5, 5, 5, 5, 5, 5, 5, 5,			/* 38 .. 3f */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 40 .. 47 */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 48 .. 4f */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 50 .. 57 */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 58 .. 5f */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 60 .. 67 */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 68 .. 6f */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 70 .. 77 */
-	6, 6, 6, 6, 6, 6, 6, 6,			/* 78 .. 7f */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* 80 .. 87 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* 88 .. 8f */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* 90 .. 97 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* 98 .. 9f */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* a0 .. a7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* a8 .. af */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* b0 .. b7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* b8 .. bf */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* c0 .. c7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* c8 .. cf */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* d0 .. d7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* d8 .. df */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* e0 .. e7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* e8 .. ef */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* f0 .. f7 */
-	7, 7, 7, 7, 7, 7, 7, 7,			/* f8 .. ff */
-};
-#endif
-
-/*
- * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set.
- */
-inline int
-xfs_highbit32(
-	__uint32_t	v)
-{
-#ifdef HAVE_ARCH_HIGHBIT
-	return highbit32(v);
-#else
-	int		i;
-
-	if (v & 0xffff0000)
-		if (v & 0xff000000)
-			i = 24;
-		else
-			i = 16;
-	else if (v & 0x0000ffff)
-		if (v & 0x0000ff00)
-			i = 8;
-		else
-			i = 0;
-	else
-		return -1;
-	return i + xfs_highbit[(v >> i) & 0xff];
-#endif
-}
-
-/*
- * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set.
- */
-int
-xfs_lowbit64(
-	__uint64_t	v)
-{
-	__uint32_t	w = (__uint32_t)v;
-	int		n = 0;
-
-	if (w) {	/* lower bits */
-		n = ffs(w);
-	} else {	/* upper bits */
-		w = (__uint32_t)(v >> 32);
-		if (w && (n = ffs(w)))
-			n += 32;
-	}
-	return n - 1;
-}
-
-/*
- * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set.
- */
-int
-xfs_highbit64(
-	__uint64_t	v)
-{
-	__uint32_t	h = (__uint32_t)(v >> 32);
-
-	if (h)
-		return xfs_highbit32(h) + 32;
-	return xfs_highbit32((__uint32_t)v);
-}
-
-
 /*
  * Return whether bitmap is empty.
  * Size is number of words in the bitmap, which is padded to word boundary
Index: 2.6.x-xfs-new/fs/xfs/xfs_bit.h
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_bit.h	2007-06-20 15:54:59.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_bit.h	2007-10-05 08:56:53.180459657 +1000
@@ -47,13 +47,30 @@ static inline __uint64_t xfs_mask64lo(in
 }
 
 /* Get high bit set out of 32-bit argument, -1 if none set */
-extern int xfs_highbit32(__uint32_t v);
-
-/* Get low bit set out of 64-bit argument, -1 if none set */
-extern int xfs_lowbit64(__uint64_t v);
+static inline int xfs_highbit32(__uint32_t v)
+{
+	return fls(v) - 1;
+}
 
 /* Get high bit set out of 64-bit argument, -1 if none set */
-extern int xfs_highbit64(__uint64_t);
+static inline int xfs_highbit64(__uint64_t v)
+{
+	return fls64(v) - 1;
+}
+
+/* Get low bit set out of 32-bit argument, -1 if none set */
+static inline int xfs_lowbit32(__uint32_t v)
+{
+	unsigned long	t = v;
+	return (v) ? find_first_bit(&t, 32) : -1;
+}
+
+/* Get low bit set out of 64-bit argument, -1 if none set */
+static inline int xfs_lowbit64(__uint64_t v)
+{
+	unsigned long	t = v;
+	return (v) ? find_first_bit(&t, 64) : -1;
+}
 
 /* Return whether bitmap is empty (1 == empty) */
 extern int xfs_bitmap_empty(uint *map, uint size);
Index: 2.6.x-xfs-new/fs/xfs/xfs_rtalloc.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_rtalloc.c	2007-08-24 22:24:45.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_rtalloc.c	2007-10-05 09:02:27.376952907 +1000
@@ -73,18 +73,6 @@ STATIC int xfs_rtmodify_summary(xfs_moun
  */
 
 /*
- * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set.
- */
-STATIC int
-xfs_lowbit32(
-	__uint32_t	v)
-{
-	if (v)
-		return ffs(v) - 1;
-	return -1;
-}
-
-/*
  * Allocate space to the bitmap or summary file, and zero it, for growfs.
  */
 STATIC int				/* error */
@@ -444,6 +433,7 @@ xfs_rtallocate_extent_near(
 	}
 	bbno = XFS_BITTOBLOCK(mp, bno);
 	i = 0;
+	ASSERT(minlen != 0);
 	log2len = xfs_highbit32(minlen);
 	/*
 	 * Loop over all bitmap blocks (bbno + i is current block).
@@ -612,6 +602,8 @@ xfs_rtallocate_extent_size(
 	xfs_suminfo_t	sum;		/* summary information for extents */
 
 	ASSERT(minlen % prod == 0 && maxlen % prod == 0);
+	ASSERT(maxlen != 0);
+
 	/*
 	 * Loop over all the levels starting with maxlen.
 	 * At each level, look at all the bitmap blocks, to see if there
@@ -669,6 +661,9 @@ xfs_rtallocate_extent_size(
 		*rtblock = NULLRTBLOCK;
 		return 0;
 	}
+	ASSERT(minlen != 0);
+	ASSERT(maxlen != 0);
+
 	/*
 	 * Loop over sizes, from maxlen down to minlen.
 	 * This time, when we do the allocations, allow smaller ones
@@ -1954,6 +1949,7 @@ xfs_growfs_rt(
 				  nsbp->sb_blocksize * nsbp->sb_rextsize);
 		nsbp->sb_rextents = nsbp->sb_rblocks;
 		do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
+		ASSERT(nsbp->sb_rextents != 0);
 		nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
 		nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
 		nrsumsize =