fs bitmaps: find_first_one_bit

Ben Fennema (bfennema@falcon.csc.calpoly.edu)
Mon, 23 Aug 1999 23:45:11 -0700 (PDT)


I was hoping someone could comment on the correctness of this code for
big endian and/or 64 bit machines.

Under UDF the free block bitmaps have bits set to one for free blocks vs
zero for ext2, so I can't use the current find_first_zero_bit macro's.

Thanks,

Ben

#define udf_find_first_one_bit(addr, size) find_first_one_bit(addr, size)
#define udf_find_next_one_bit(addr, size, offset) find_next_one_bit(addr, size, offset)

#define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x)
#define leNUM_to_cpup(x,y) xleNUM_to_cpup(x,y)
#define xleNUM_to_cpup(x,y) (le ## x ## _to_cpup(y))

extern inline int find_next_one_bit (void * addr, int size, int offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset / BITS_PER_LONG);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;

if (offset >= size)
return size;
size -= result;
offset &= (BITS_PER_LONG-1);
if (offset)
{
tmp = leBPL_to_cpup(p++);
tmp &= ~0UL << offset;
if (size < BITS_PER_LONG)
goto found_first;
if (tmp)
goto found_middle;
size -= BITS_PER_LONG;
result += BITS_PER_LONG;
}
while (size & ~(BITS_PER_LONG-1))
{
if ((tmp = leBPL_to_cpup(p++)))
goto found_middle;
result += BITS_PER_LONG;
size -= BITS_PER_LONG;
}
if (!size)
return result;
tmp = leBPL_to_cpup(p);
found_first:
tmp &= ~0UL >> (BITS_PER_LONG-size);
found_middle:
return result + ffs(tmp) - 1;
}

#define find_first_one_bit(addr, size)\
find_next_one_bit((addr), (size), 0)

-- 
Linux UDF - http://www.trylinux.com/projects/udf/index.html
Latest Is - udf-0.8.8 (http://www.csc.calpoly.edu/~bfennema/udf-0.8.8.tar.gz)

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/