Commit d80ba2fd authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

lib/bitmap.c: fix incorrect use of BITS_TO_LONGS()

Bug spotted by: Ian Molton <spyro@f2s.com>

BITS_TO_LONGS() can't be used to derive an index
into a bitmap array.

Also put a BUG_ON() for the pages > BITS_PER_LONG case
we don't cope with.
parent e73c64e3
...@@ -439,7 +439,7 @@ int bitmap_find_free_region(unsigned long *bitmap, int bits, int order) ...@@ -439,7 +439,7 @@ int bitmap_find_free_region(unsigned long *bitmap, int bits, int order)
/* run up the bitmap pages bits at a time */ /* run up the bitmap pages bits at a time */
for (i = 0; i < bits; i += pages) { for (i = 0; i < bits; i += pages) {
int index = BITS_TO_LONGS(i); int index = i/BITS_PER_LONG;
int offset = i - (index * BITS_PER_LONG); int offset = i - (index * BITS_PER_LONG);
if((bitmap[index] & (mask << offset)) == 0) { if((bitmap[index] & (mask << offset)) == 0) {
/* set region in bimap */ /* set region in bimap */
...@@ -464,7 +464,7 @@ void bitmap_release_region(unsigned long *bitmap, int pos, int order) ...@@ -464,7 +464,7 @@ void bitmap_release_region(unsigned long *bitmap, int pos, int order)
{ {
int pages = 1 << order; int pages = 1 << order;
unsigned long mask = (1ul << (pages - 1)); unsigned long mask = (1ul << (pages - 1));
int index = BITS_TO_LONGS(pos); int index = pos/BITS_PER_LONG;
int offset = pos - (index * BITS_PER_LONG); int offset = pos - (index * BITS_PER_LONG);
mask += mask - 1; mask += mask - 1;
bitmap[index] &= ~(mask << offset); bitmap[index] &= ~(mask << offset);
...@@ -475,8 +475,14 @@ int bitmap_allocate_region(unsigned long *bitmap, int pos, int order) ...@@ -475,8 +475,14 @@ int bitmap_allocate_region(unsigned long *bitmap, int pos, int order)
{ {
int pages = 1 << order; int pages = 1 << order;
unsigned long mask = (1ul << (pages - 1)); unsigned long mask = (1ul << (pages - 1));
int index = BITS_TO_LONGS(pos); int index = pos/BITS_PER_LONG;
int offset = pos - (index * BITS_PER_LONG); int offset = pos - (index * BITS_PER_LONG);
/* We don't do regions of pages > BITS_PER_LONG. The
* algorithm would be a simple look for multiple zeros in the
* array, but there's no driver today that needs this. If you
* trip this BUG(), you get to code it... */
BUG_ON(pages > BITS_PER_LONG);
mask += mask - 1; mask += mask - 1;
if (bitmap[index] & (mask << offset)) if (bitmap[index] & (mask << offset))
return -EBUSY; return -EBUSY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment