Commit aa02ad67d9b308290fde390682cd039b29f7ab85
Committed by
Theodore Ts'o
1 parent
c549a95d40
Exists in
master
and in
7 other branches
ext4: Add ext4_find_next_bit()
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 <aneesh.kumar@linux.vnet.ibm.com> Cc: <linux-ext4@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Showing 9 changed files with 62 additions and 0 deletions Side-by-side Diff
include/asm-arm/bitops.h
... | ... | @@ -310,6 +310,8 @@ |
310 | 310 | _find_first_zero_bit_le(p,sz) |
311 | 311 | #define ext2_find_next_zero_bit(p,sz,off) \ |
312 | 312 | _find_next_zero_bit_le(p,sz,off) |
313 | +#define ext2_find_next_bit(p, sz, off) \ | |
314 | + _find_next_bit_le(p, sz, off) | |
313 | 315 | |
314 | 316 | /* |
315 | 317 | * Minix is defined to use little-endian byte ordering. |
include/asm-generic/bitops/ext2-non-atomic.h
... | ... | @@ -14,6 +14,8 @@ |
14 | 14 | generic_find_first_zero_le_bit((unsigned long *)(addr), (size)) |
15 | 15 | #define ext2_find_next_zero_bit(addr, size, off) \ |
16 | 16 | generic_find_next_zero_le_bit((unsigned long *)(addr), (size), (off)) |
17 | +#define ext2_find_next_bit(addr, size, off) \ | |
18 | + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) | |
17 | 19 | |
18 | 20 | #endif /* _ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_ */ |
include/asm-generic/bitops/le.h
... | ... | @@ -20,6 +20,8 @@ |
20 | 20 | #define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr) |
21 | 21 | |
22 | 22 | #define generic_find_next_zero_le_bit(addr, size, offset) find_next_zero_bit(addr, size, offset) |
23 | +#define generic_find_next_le_bit(addr, size, offset) \ | |
24 | + find_next_bit(addr, size, offset) | |
23 | 25 | |
24 | 26 | #elif defined(__BIG_ENDIAN) |
25 | 27 | |
... | ... | @@ -41,6 +43,8 @@ |
41 | 43 | __test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr)) |
42 | 44 | |
43 | 45 | extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, |
46 | + unsigned long size, unsigned long offset); | |
47 | +extern unsigned long generic_find_next_le_bit(const unsigned long *addr, | |
44 | 48 | unsigned long size, unsigned long offset); |
45 | 49 | |
46 | 50 | #else |
include/asm-m68k/bitops.h
... | ... | @@ -410,6 +410,8 @@ |
410 | 410 | res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); |
411 | 411 | return (p - addr) * 32 + res; |
412 | 412 | } |
413 | +#define ext2_find_next_bit(addr, size, off) \ | |
414 | + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) | |
413 | 415 | |
414 | 416 | #endif /* __KERNEL__ */ |
415 | 417 |
include/asm-m68knommu/bitops.h
include/asm-powerpc/bitops.h
... | ... | @@ -359,6 +359,8 @@ |
359 | 359 | unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, |
360 | 360 | unsigned long size, unsigned long offset); |
361 | 361 | |
362 | +unsigned long generic_find_next_le_bit(const unsigned long *addr, | |
363 | + unsigned long size, unsigned long offset); | |
362 | 364 | /* Bitmap functions for the ext2 filesystem */ |
363 | 365 | |
364 | 366 | #define ext2_set_bit(nr,addr) \ |
... | ... | @@ -378,6 +380,8 @@ |
378 | 380 | #define ext2_find_next_zero_bit(addr, size, off) \ |
379 | 381 | generic_find_next_zero_le_bit((unsigned long*)addr, size, off) |
380 | 382 | |
383 | +#define ext2_find_next_bit(addr, size, off) \ | |
384 | + generic_find_next_le_bit((unsigned long *)addr, size, off) | |
381 | 385 | /* Bitmap functions for the minix filesystem. */ |
382 | 386 | |
383 | 387 | #define minix_test_and_set_bit(nr,addr) \ |
include/asm-s390/bitops.h
... | ... | @@ -772,6 +772,8 @@ |
772 | 772 | test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) |
773 | 773 | #define ext2_test_bit(nr, addr) \ |
774 | 774 | test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) |
775 | +#define ext2_find_next_bit(addr, size, off) \ | |
776 | + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) | |
775 | 777 | |
776 | 778 | #ifndef __s390x__ |
777 | 779 |
include/linux/ext4_fs.h
... | ... | @@ -493,6 +493,7 @@ |
493 | 493 | #define ext4_test_bit ext2_test_bit |
494 | 494 | #define ext4_find_first_zero_bit ext2_find_first_zero_bit |
495 | 495 | #define ext4_find_next_zero_bit ext2_find_next_zero_bit |
496 | +#define ext4_find_next_bit ext2_find_next_bit | |
496 | 497 | |
497 | 498 | /* |
498 | 499 | * Maximal mount counts between two filesystem checks |
lib/find_next_bit.c
... | ... | @@ -178,5 +178,48 @@ |
178 | 178 | |
179 | 179 | EXPORT_SYMBOL(generic_find_next_zero_le_bit); |
180 | 180 | |
181 | +unsigned long generic_find_next_le_bit(const unsigned long *addr, unsigned | |
182 | + long size, unsigned long offset) | |
183 | +{ | |
184 | + const unsigned long *p = addr + BITOP_WORD(offset); | |
185 | + unsigned long result = offset & ~(BITS_PER_LONG - 1); | |
186 | + unsigned long tmp; | |
187 | + | |
188 | + if (offset >= size) | |
189 | + return size; | |
190 | + size -= result; | |
191 | + offset &= (BITS_PER_LONG - 1UL); | |
192 | + if (offset) { | |
193 | + tmp = ext2_swabp(p++); | |
194 | + tmp &= (~0UL << offset); | |
195 | + if (size < BITS_PER_LONG) | |
196 | + goto found_first; | |
197 | + if (tmp) | |
198 | + goto found_middle; | |
199 | + size -= BITS_PER_LONG; | |
200 | + result += BITS_PER_LONG; | |
201 | + } | |
202 | + | |
203 | + while (size & ~(BITS_PER_LONG - 1)) { | |
204 | + tmp = *(p++); | |
205 | + if (tmp) | |
206 | + goto found_middle_swap; | |
207 | + result += BITS_PER_LONG; | |
208 | + size -= BITS_PER_LONG; | |
209 | + } | |
210 | + if (!size) | |
211 | + return result; | |
212 | + tmp = ext2_swabp(p); | |
213 | +found_first: | |
214 | + tmp &= (~0UL >> (BITS_PER_LONG - size)); | |
215 | + if (tmp == 0UL) /* Are any bits set? */ | |
216 | + return result + size; /* Nope. */ | |
217 | +found_middle: | |
218 | + return result + __ffs(tmp); | |
219 | + | |
220 | +found_middle_swap: | |
221 | + return result + __ffs(ext2_swab(tmp)); | |
222 | +} | |
223 | +EXPORT_SYMBOL(generic_find_next_le_bit); | |
181 | 224 | #endif /* __BIG_ENDIAN */ |