1 ext4: Add ext4_find_next_bit()
3 From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
5 This function is used by the ext4 multi block allocator patches.
7 Also add generic_find_next_le_bit
9 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
10 Cc: <linux-ext4@vger.kernel.org>
11 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
14 include/asm-arm/bitops.h | 2 +
15 include/asm-generic/bitops/ext2-non-atomic.h | 2 +
16 include/asm-generic/bitops/le.h | 4 ++
17 include/asm-m68k/bitops.h | 2 +
18 include/asm-m68knommu/bitops.h | 2 +
19 include/asm-powerpc/bitops.h | 4 ++
20 include/asm-s390/bitops.h | 2 +
21 include/linux/ext4_fs.h | 1 +
22 lib/find_next_bit.c | 43 ++++++++++++++++++++++++++
23 9 files changed, 62 insertions(+), 0 deletions(-)
26 diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
27 index 47a6b08..5c60bfc 100644
28 --- a/include/asm-arm/bitops.h
29 +++ b/include/asm-arm/bitops.h
30 @@ -310,6 +310,8 @@ static inline int constant_fls(int x)
31 _find_first_zero_bit_le(p,sz)
32 #define ext2_find_next_zero_bit(p,sz,off) \
33 _find_next_zero_bit_le(p,sz,off)
34 +#define ext2_find_next_bit(p, sz, off) \
35 + _find_next_bit_le(p, sz, off)
38 * Minix is defined to use little-endian byte ordering.
39 diff --git a/include/asm-generic/bitops/ext2-non-atomic.h b/include/asm-generic/bitops/ext2-non-atomic.h
40 index 1697404..63cf822 100644
41 --- a/include/asm-generic/bitops/ext2-non-atomic.h
42 +++ b/include/asm-generic/bitops/ext2-non-atomic.h
44 generic_find_first_zero_le_bit((unsigned long *)(addr), (size))
45 #define ext2_find_next_zero_bit(addr, size, off) \
46 generic_find_next_zero_le_bit((unsigned long *)(addr), (size), (off))
47 +#define ext2_find_next_bit(addr, size, off) \
48 + generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
50 #endif /* _ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_ */
51 diff --git a/include/asm-generic/bitops/le.h b/include/asm-generic/bitops/le.h
52 index b9c7e5d..80e3bf1 100644
53 --- a/include/asm-generic/bitops/le.h
54 +++ b/include/asm-generic/bitops/le.h
56 #define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr)
58 #define generic_find_next_zero_le_bit(addr, size, offset) find_next_zero_bit(addr, size, offset)
59 +#define generic_find_next_le_bit(addr, size, offset) \
60 + find_next_bit(addr, size, offset)
62 #elif defined(__BIG_ENDIAN)
66 extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
67 unsigned long size, unsigned long offset);
68 +extern unsigned long generic_find_next_le_bit(const unsigned long *addr,
69 + unsigned long size, unsigned long offset);
72 #error "Please fix <asm/byteorder.h>"
73 diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
74 index 2976b5d..83d1f28 100644
75 --- a/include/asm-m68k/bitops.h
76 +++ b/include/asm-m68k/bitops.h
77 @@ -410,6 +410,8 @@ static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size,
78 res = ext2_find_first_zero_bit (p, size - 32 * (p - addr));
79 return (p - addr) * 32 + res;
81 +#define ext2_find_next_bit(addr, size, off) \
82 + generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
84 #endif /* __KERNEL__ */
86 diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
87 index f8dfb7b..f43afe1 100644
88 --- a/include/asm-m68knommu/bitops.h
89 +++ b/include/asm-m68knommu/bitops.h
90 @@ -294,6 +294,8 @@ found_middle:
91 return result + ffz(__swab32(tmp));
94 +#define ext2_find_next_bit(addr, size, off) \
95 + generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
96 #include <asm-generic/bitops/minix.h>
98 #endif /* __KERNEL__ */
99 diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
100 index 733b4af..220d9a7 100644
101 --- a/include/asm-powerpc/bitops.h
102 +++ b/include/asm-powerpc/bitops.h
103 @@ -359,6 +359,8 @@ static __inline__ int test_le_bit(unsigned long nr,
104 unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
105 unsigned long size, unsigned long offset);
107 +unsigned long generic_find_next_le_bit(const unsigned long *addr,
108 + unsigned long size, unsigned long offset);
109 /* Bitmap functions for the ext2 filesystem */
111 #define ext2_set_bit(nr,addr) \
112 @@ -378,6 +380,8 @@ unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
113 #define ext2_find_next_zero_bit(addr, size, off) \
114 generic_find_next_zero_le_bit((unsigned long*)addr, size, off)
116 +#define ext2_find_next_bit(addr, size, off) \
117 + generic_find_next_le_bit((unsigned long *)addr, size, off)
118 /* Bitmap functions for the minix filesystem. */
120 #define minix_test_and_set_bit(nr,addr) \
121 diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
122 index 34d9a63..dba6fec 100644
123 --- a/include/asm-s390/bitops.h
124 +++ b/include/asm-s390/bitops.h
125 @@ -772,6 +772,8 @@ static inline int sched_find_first_bit(unsigned long *b)
126 test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
127 #define ext2_test_bit(nr, addr) \
128 test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
129 +#define ext2_find_next_bit(addr, size, off) \
130 + generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
134 diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h
135 index 213974f..d0b7ca9 100644
136 --- a/include/linux/ext4_fs.h
137 +++ b/include/linux/ext4_fs.h
138 @@ -493,6 +493,7 @@ do { \
139 #define ext4_test_bit ext2_test_bit
140 #define ext4_find_first_zero_bit ext2_find_first_zero_bit
141 #define ext4_find_next_zero_bit ext2_find_next_zero_bit
142 +#define ext4_find_next_bit ext2_find_next_bit
145 * Maximal mount counts between two filesystem checks
146 diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c
147 index bda0d71..78ccd73 100644
148 --- a/lib/find_next_bit.c
149 +++ b/lib/find_next_bit.c
150 @@ -178,4 +178,47 @@ found_middle_swap:
152 EXPORT_SYMBOL(generic_find_next_zero_le_bit);
154 +unsigned long generic_find_next_le_bit(const unsigned long *addr, unsigned
155 + long size, unsigned long offset)
157 + const unsigned long *p = addr + BITOP_WORD(offset);
158 + unsigned long result = offset & ~(BITS_PER_LONG - 1);
161 + if (offset >= size)
164 + offset &= (BITS_PER_LONG - 1UL);
166 + tmp = ext2_swabp(p++);
167 + tmp &= (~0UL << offset);
168 + if (size < BITS_PER_LONG)
172 + size -= BITS_PER_LONG;
173 + result += BITS_PER_LONG;
176 + while (size & ~(BITS_PER_LONG - 1)) {
179 + goto found_middle_swap;
180 + result += BITS_PER_LONG;
181 + size -= BITS_PER_LONG;
185 + tmp = ext2_swabp(p);
187 + tmp &= (~0UL >> (BITS_PER_LONG - size));
188 + if (tmp == 0UL) /* Are any bits set? */
189 + return result + size; /* Nope. */
191 + return result + __ffs(tmp);
194 + return result + __ffs(ext2_swab(tmp));
196 +EXPORT_SYMBOL(generic_find_next_le_bit);
197 #endif /* __BIG_ENDIAN */