Introduce ext4_find_next_bit() From: Aneesh Kumar K.V This function is used by the ext4 multi block allocator patches. Also add generic_find_next_le_bit Signed-off-by: Aneesh Kumar K.V Cc: Signed-off-by: Andrew Morton --- include/asm-arm/bitops.h | 2 + include/asm-generic/bitops/ext2-non-atomic.h | 2 + include/asm-generic/bitops/le.h | 4 ++ include/asm-m68k/bitops.h | 2 + include/asm-m68knommu/bitops.h | 2 + include/asm-powerpc/bitops.h | 4 ++ include/asm-s390/bitops.h | 2 + include/linux/ext4_fs.h | 1 lib/find_next_bit.c | 43 +++++++++++++++++++++++++++ 9 files changed, 62 insertions(+) Index: linux-2.6.24-rc3/include/asm-arm/bitops.h =================================================================== --- linux-2.6.24-rc3.orig/include/asm-arm/bitops.h 2007-12-03 16:06:12.000000000 -0800 +++ linux-2.6.24-rc3/include/asm-arm/bitops.h 2007-12-03 16:06:36.000000000 -0800 @@ -310,6 +310,8 @@ static inline int constant_fls(int x) _find_first_zero_bit_le(p,sz) #define ext2_find_next_zero_bit(p,sz,off) \ _find_next_zero_bit_le(p,sz,off) +#define ext2_find_next_bit(p, sz, off) \ + _find_next_bit_le(p, sz, off) /* * Minix is defined to use little-endian byte ordering. Index: linux-2.6.24-rc3/include/asm-generic/bitops/ext2-non-atomic.h =================================================================== --- linux-2.6.24-rc3.orig/include/asm-generic/bitops/ext2-non-atomic.h 2007-12-03 16:06:12.000000000 -0800 +++ linux-2.6.24-rc3/include/asm-generic/bitops/ext2-non-atomic.h 2007-12-03 16:06:36.000000000 -0800 @@ -14,5 +14,7 @@ generic_find_first_zero_le_bit((unsigned long *)(addr), (size)) #define ext2_find_next_zero_bit(addr, size, off) \ generic_find_next_zero_le_bit((unsigned long *)(addr), (size), (off)) +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) #endif /* _ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_ */ Index: linux-2.6.24-rc3/include/asm-generic/bitops/le.h =================================================================== --- linux-2.6.24-rc3.orig/include/asm-generic/bitops/le.h 2007-12-03 16:06:12.000000000 -0800 +++ linux-2.6.24-rc3/include/asm-generic/bitops/le.h 2007-12-03 16:06:36.000000000 -0800 @@ -20,6 +20,8 @@ #define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr) #define generic_find_next_zero_le_bit(addr, size, offset) find_next_zero_bit(addr, size, offset) +#define generic_find_next_le_bit(addr, size, offset) \ + find_next_bit(addr, size, offset) #elif defined(__BIG_ENDIAN) @@ -42,6 +44,8 @@ extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, unsigned long size, unsigned long offset); +extern unsigned long generic_find_next_le_bit(const unsigned long *addr, + unsigned long size, unsigned long offset); #else #error "Please fix " Index: linux-2.6.24-rc3/include/asm-m68k/bitops.h =================================================================== --- linux-2.6.24-rc3.orig/include/asm-m68k/bitops.h 2007-12-03 16:06:12.000000000 -0800 +++ linux-2.6.24-rc3/include/asm-m68k/bitops.h 2007-12-03 16:06:36.000000000 -0800 @@ -410,6 +410,8 @@ static inline int ext2_find_next_zero_bi res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); return (p - addr) * 32 + res; } +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) #endif /* __KERNEL__ */ Index: linux-2.6.24-rc3/include/asm-m68knommu/bitops.h =================================================================== --- linux-2.6.24-rc3.orig/include/asm-m68knommu/bitops.h 2007-12-03 16:06:12.000000000 -0800 +++ linux-2.6.24-rc3/include/asm-m68knommu/bitops.h 2007-12-03 16:06:36.000000000 -0800 @@ -294,6 +294,8 @@ found_middle: return result + ffz(__swab32(tmp)); } +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) #include #endif /* __KERNEL__ */ Index: linux-2.6.24-rc3/include/asm-powerpc/bitops.h =================================================================== --- linux-2.6.24-rc3.orig/include/asm-powerpc/bitops.h 2007-12-03 16:06:12.000000000 -0800 +++ linux-2.6.24-rc3/include/asm-powerpc/bitops.h 2007-12-03 16:06:36.000000000 -0800 @@ -359,6 +359,8 @@ static __inline__ int test_le_bit(unsign unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, unsigned long size, unsigned long offset); +unsigned long generic_find_next_le_bit(const unsigned long *addr, + unsigned long size, unsigned long offset); /* Bitmap functions for the ext2 filesystem */ #define ext2_set_bit(nr,addr) \ @@ -378,6 +380,8 @@ unsigned long generic_find_next_zero_le_ #define ext2_find_next_zero_bit(addr, size, off) \ generic_find_next_zero_le_bit((unsigned long*)addr, size, off) +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)addr, size, off) /* Bitmap functions for the minix filesystem. */ #define minix_test_and_set_bit(nr,addr) \ Index: linux-2.6.24-rc3/include/asm-s390/bitops.h =================================================================== --- linux-2.6.24-rc3.orig/include/asm-s390/bitops.h 2007-12-03 16:06:12.000000000 -0800 +++ linux-2.6.24-rc3/include/asm-s390/bitops.h 2007-12-03 16:06:36.000000000 -0800 @@ -772,6 +772,8 @@ static inline int sched_find_first_bit(u test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) #define ext2_test_bit(nr, addr) \ test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) #ifndef __s390x__ Index: linux-2.6.24-rc3/include/linux/ext4_fs.h =================================================================== --- linux-2.6.24-rc3.orig/include/linux/ext4_fs.h 2007-12-03 16:06:34.000000000 -0800 +++ linux-2.6.24-rc3/include/linux/ext4_fs.h 2007-12-03 16:06:36.000000000 -0800 @@ -494,6 +494,7 @@ do { \ #define ext4_test_bit ext2_test_bit #define ext4_find_first_zero_bit ext2_find_first_zero_bit #define ext4_find_next_zero_bit ext2_find_next_zero_bit +#define ext4_find_next_bit ext2_find_next_bit /* * Maximal mount counts between two filesystem checks Index: linux-2.6.24-rc3/lib/find_next_bit.c =================================================================== --- linux-2.6.24-rc3.orig/lib/find_next_bit.c 2007-12-03 16:06:12.000000000 -0800 +++ linux-2.6.24-rc3/lib/find_next_bit.c 2007-12-03 16:06:36.000000000 -0800 @@ -178,4 +178,47 @@ found_middle_swap: EXPORT_SYMBOL(generic_find_next_zero_le_bit); +unsigned long generic_find_next_le_bit(const unsigned long *addr, unsigned + long size, unsigned long offset) +{ + const unsigned long *p = addr + BITOP_WORD(offset); + unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= (BITS_PER_LONG - 1UL); + if (offset) { + tmp = ext2_swabp(p++); + tmp &= (~0UL << offset); + if (size < BITS_PER_LONG) + goto found_first; + if (tmp) + goto found_middle; + size -= BITS_PER_LONG; + result += BITS_PER_LONG; + } + + while (size & ~(BITS_PER_LONG - 1)) { + tmp = *(p++); + if (tmp) + goto found_middle_swap; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = ext2_swabp(p); +found_first: + tmp &= (~0UL >> (BITS_PER_LONG - size)); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __ffs(tmp); + +found_middle_swap: + return result + __ffs(ext2_swab(tmp)); +} +EXPORT_SYMBOL(generic_find_next_le_bit); #endif /* __BIG_ENDIAN */