patch-2.4.27 linux-2.4.27/fs/xfs/xfs_bit.c
Next file: linux-2.4.27/fs/xfs/xfs_bmap.c
Previous file: linux-2.4.27/fs/xfs/xfs_attr.h
Back to the patch index
Back to the overall index
- Lines: 137
- Date:
2004-08-07 16:26:06.111406646 -0700
- Orig file:
linux-2.4.26/fs/xfs/xfs_bit.c
- Orig date:
2004-02-18 05:36:32.000000000 -0800
diff -urN linux-2.4.26/fs/xfs/xfs_bit.c linux-2.4.27/fs/xfs/xfs_bit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -154,14 +154,17 @@
xfs_lowbit64(
__uint64_t v)
{
- int n;
- n = ffs((unsigned)v);
- if (n <= 0) {
- n = ffs(v >> 32);
- if (n >= 0)
- n+=32;
+ __uint32_t w = (__uint32_t)v;
+ int n = 0;
+
+ if (w) { /* lower bits */
+ n = ffs(w);
+ } else { /* upper bits */
+ w = (__uint32_t)(v >> 32);
+ if (w && (n = ffs(w)))
+ n += 32;
}
- return (n <= 0) ? n : n-1;
+ return n - 1;
}
/*
@@ -171,10 +174,11 @@
xfs_highbit64(
__uint64_t v)
{
- __uint32_t h = v >> 32;
+ __uint32_t h = (__uint32_t)(v >> 32);
+
if (h)
return xfs_highbit32(h) + 32;
- return xfs_highbit32((__u32)v);
+ return xfs_highbit32((__uint32_t)v);
}
@@ -238,32 +242,33 @@
int
xfs_contig_bits(uint *map, uint size, uint start_bit)
{
-#if BITS_PER_LONG == 32
- return find_next_zero_bit((unsigned long *)map,
- size * sizeof(uint) * 8, start_bit) - start_bit;
-#else
- /*
- * The first argument to find_next_zero_bit needs to be aligned,
- * but this is coming from the xfs_buf_log_format_t on-disk
- * struct, which can't be padded or otherwise modified w/o breaking
- * on-disk compatibility... so create a temporary, aligned
- * variable, copy over the bitmap, and send that to find_next_zero_bit
- * This only happens in recovery, so it's ugly but not too bad.
- */
- void * addr;
- int bit;
- size_t bitmap_size = size * sizeof(uint);
-
- addr = (void *)kmem_alloc(bitmap_size, KM_SLEEP);
- memcpy(addr, map, size * sizeof(uint));
-
- bit = find_next_zero_bit((unsigned long *)addr,
- size * sizeof(uint) * 8, start_bit) - start_bit;
+ uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT);
+ uint result = 0;
+ uint tmp;
- kmem_free(addr, bitmap_size);
+ size <<= BIT_TO_WORD_SHIFT;
- return bit;
-#endif
+ ASSERT(start_bit < size);
+ size -= start_bit & ~(NBWORD - 1);
+ start_bit &= (NBWORD - 1);
+ if (start_bit) {
+ tmp = *p++;
+ /* set to one first offset bits prior to start */
+ tmp |= (~0U >> (NBWORD-start_bit));
+ if (tmp != ~0U)
+ goto found;
+ result += NBWORD;
+ size -= NBWORD;
+ }
+ while (size) {
+ if ((tmp = *p++) != ~0U)
+ goto found;
+ result += NBWORD;
+ size -= NBWORD;
+ }
+ return result - start_bit;
+found:
+ return result + ffz(tmp) - start_bit;
}
/*
@@ -288,25 +293,20 @@
start_bit &= (NBWORD - 1);
if (start_bit) {
tmp = *p++;
- /* set to zero first offset bits */
+ /* set to zero first offset bits prior to start */
tmp &= (~0U << start_bit);
- if (size < NBWORD)
- goto found_first;
if (tmp != 0U)
- goto found_middle;
- size -= NBWORD;
+ goto found;
result += NBWORD;
+ size -= NBWORD;
}
- while (size >= NBWORD) {
+ while (size) {
if ((tmp = *p++) != 0U)
- goto found_middle;
+ goto found;
result += NBWORD;
size -= NBWORD;
}
- if (!size)
- return -1;
- tmp = *p;
-found_first:
-found_middle:
+ return -1;
+found:
return result + ffs(tmp) - 1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)