aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asm-arm/bitops.h2
-rw-r--r--include/asm-generic/bitops/ext2-non-atomic.h2
-rw-r--r--include/asm-generic/bitops/le.h4
-rw-r--r--include/asm-m68k/bitops.h2
-rw-r--r--include/asm-m68knommu/bitops.h2
-rw-r--r--include/asm-powerpc/bitops.h4
-rw-r--r--include/asm-s390/bitops.h2
-rw-r--r--include/linux/ext4_fs.h1
-rw-r--r--lib/find_next_bit.c43
9 files changed, 62 insertions, 0 deletions
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index 47a6b086eee2..5c60bfc1a84d 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -310,6 +310,8 @@ static inline int constant_fls(int x)
310 _find_first_zero_bit_le(p,sz) 310 _find_first_zero_bit_le(p,sz)
311#define ext2_find_next_zero_bit(p,sz,off) \ 311#define ext2_find_next_zero_bit(p,sz,off) \
312 _find_next_zero_bit_le(p,sz,off) 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 * Minix is defined to use little-endian byte ordering. 317 * Minix is defined to use little-endian byte ordering.
diff --git a/include/asm-generic/bitops/ext2-non-atomic.h b/include/asm-generic/bitops/ext2-non-atomic.h
index 1697404afa05..63cf822431a2 100644
--- a/include/asm-generic/bitops/ext2-non-atomic.h
+++ b/include/asm-generic/bitops/ext2-non-atomic.h
@@ -14,5 +14,7 @@
14 generic_find_first_zero_le_bit((unsigned long *)(addr), (size)) 14 generic_find_first_zero_le_bit((unsigned long *)(addr), (size))
15#define ext2_find_next_zero_bit(addr, size, off) \ 15#define ext2_find_next_zero_bit(addr, size, off) \
16 generic_find_next_zero_le_bit((unsigned long *)(addr), (size), (off)) 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#endif /* _ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_ */ 20#endif /* _ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_ */
diff --git a/include/asm-generic/bitops/le.h b/include/asm-generic/bitops/le.h
index b9c7e5d2d2ad..80e3bf13b2b9 100644
--- a/include/asm-generic/bitops/le.h
+++ b/include/asm-generic/bitops/le.h
@@ -20,6 +20,8 @@
20#define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr) 20#define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr)
21 21
22#define generic_find_next_zero_le_bit(addr, size, offset) find_next_zero_bit(addr, size, offset) 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#elif defined(__BIG_ENDIAN) 26#elif defined(__BIG_ENDIAN)
25 27
@@ -42,6 +44,8 @@
42 44
43extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, 45extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
44 unsigned long size, unsigned long offset); 46 unsigned long size, unsigned long offset);
47extern unsigned long generic_find_next_le_bit(const unsigned long *addr,
48 unsigned long size, unsigned long offset);
45 49
46#else 50#else
47#error "Please fix <asm/byteorder.h>" 51#error "Please fix <asm/byteorder.h>"
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
index 2976b5d68e96..83d1f286230b 100644
--- a/include/asm-m68k/bitops.h
+++ b/include/asm-m68k/bitops.h
@@ -410,6 +410,8 @@ static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size,
410 res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); 410 res = ext2_find_first_zero_bit (p, size - 32 * (p - addr));
411 return (p - addr) * 32 + res; 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#endif /* __KERNEL__ */ 416#endif /* __KERNEL__ */
415 417
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
index f8dfb7ba2e25..f43afe1fc3b3 100644
--- a/include/asm-m68knommu/bitops.h
+++ b/include/asm-m68knommu/bitops.h
@@ -294,6 +294,8 @@ found_middle:
294 return result + ffz(__swab32(tmp)); 294 return result + ffz(__swab32(tmp));
295} 295}
296 296
297#define ext2_find_next_bit(addr, size, off) \
298 generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
297#include <asm-generic/bitops/minix.h> 299#include <asm-generic/bitops/minix.h>
298 300
299#endif /* __KERNEL__ */ 301#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index 733b4af7f4f1..220d9a781ab9 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -359,6 +359,8 @@ static __inline__ int test_le_bit(unsigned long nr,
359unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, 359unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
360 unsigned long size, unsigned long offset); 360 unsigned long size, unsigned long offset);
361 361
362unsigned long generic_find_next_le_bit(const unsigned long *addr,
363 unsigned long size, unsigned long offset);
362/* Bitmap functions for the ext2 filesystem */ 364/* Bitmap functions for the ext2 filesystem */
363 365
364#define ext2_set_bit(nr,addr) \ 366#define ext2_set_bit(nr,addr) \
@@ -378,6 +380,8 @@ unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
378#define ext2_find_next_zero_bit(addr, size, off) \ 380#define ext2_find_next_zero_bit(addr, size, off) \
379 generic_find_next_zero_le_bit((unsigned long*)addr, size, off) 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/* Bitmap functions for the minix filesystem. */ 385/* Bitmap functions for the minix filesystem. */
382 386
383#define minix_test_and_set_bit(nr,addr) \ 387#define minix_test_and_set_bit(nr,addr) \
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index 34d9a6357c38..dba6fecad0be 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -772,6 +772,8 @@ static inline int sched_find_first_bit(unsigned long *b)
772 test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) 772 test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
773#define ext2_test_bit(nr, addr) \ 773#define ext2_test_bit(nr, addr) \
774 test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) 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#ifndef __s390x__ 778#ifndef __s390x__
777 779
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h
index 213974f7c5d8..d0b7ca99b91f 100644
--- a/include/linux/ext4_fs.h
+++ b/include/linux/ext4_fs.h
@@ -493,6 +493,7 @@ do { \
493#define ext4_test_bit ext2_test_bit 493#define ext4_test_bit ext2_test_bit
494#define ext4_find_first_zero_bit ext2_find_first_zero_bit 494#define ext4_find_first_zero_bit ext2_find_first_zero_bit
495#define ext4_find_next_zero_bit ext2_find_next_zero_bit 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 * Maximal mount counts between two filesystem checks 499 * Maximal mount counts between two filesystem checks
diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c
index bda0d71a2514..78ccd73a8841 100644
--- a/lib/find_next_bit.c
+++ b/lib/find_next_bit.c
@@ -178,4 +178,47 @@ found_middle_swap:
178 178
179EXPORT_SYMBOL(generic_find_next_zero_le_bit); 179EXPORT_SYMBOL(generic_find_next_zero_le_bit);
180 180
181unsigned 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);
213found_first:
214 tmp &= (~0UL >> (BITS_PER_LONG - size));
215 if (tmp == 0UL) /* Are any bits set? */
216 return result + size; /* Nope. */
217found_middle:
218 return result + __ffs(tmp);
219
220found_middle_swap:
221 return result + __ffs(ext2_swab(tmp));
222}
223EXPORT_SYMBOL(generic_find_next_le_bit);
181#endif /* __BIG_ENDIAN */ 224#endif /* __BIG_ENDIAN */