diff options
Diffstat (limited to 'lib/bitmap.c')
-rw-r--r-- | lib/bitmap.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/lib/bitmap.c b/lib/bitmap.c index 06f7e4fe8d2d..ea190b7047c3 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -1114,14 +1114,23 @@ done: */ int bitmap_find_free_region(unsigned long *bitmap, int bits, int order) { - int pos, end; /* scans bitmap by regions of size order */ + int nlongs = BITS_TO_LONGS(bits); + int i; - for (pos = 0 ; (end = pos + (1 << order)) <= bits; pos = end) { - if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE)) - continue; - __reg_op(bitmap, pos, order, REG_OP_ALLOC); - return pos; - } + for (i = 0; i < nlongs; i++) + if (bitmap[i] != ~0UL) { + int pos = i * BITS_PER_LONG; + int nbit = min(bits, pos + BITS_PER_LONG); + int end; + + for (; (end = pos + (1 << order)) <= nbit; pos = end) { + if (!__reg_op(bitmap, pos, order, + REG_OP_ISFREE)) + continue; + __reg_op(bitmap, pos, order, REG_OP_ALLOC); + return pos; + } + } return -ENOMEM; } EXPORT_SYMBOL(bitmap_find_free_region); |