Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.21 296 lines 7.7 kB view raw
1/* 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18#include "xfs.h" 19#include "xfs_bit.h" 20#include "xfs_log.h" 21#include "xfs_trans.h" 22#include "xfs_buf_item.h" 23 24/* 25 * XFS bit manipulation routines, used in non-realtime code. 26 */ 27 28#ifndef HAVE_ARCH_HIGHBIT 29/* 30 * Index of high bit number in byte, -1 for none set, 0..7 otherwise. 31 */ 32static const char xfs_highbit[256] = { 33 -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ 34 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ 35 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ 36 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */ 37 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */ 38 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */ 39 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */ 40 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */ 41 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */ 42 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */ 43 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */ 44 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */ 45 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */ 46 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */ 47 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */ 48 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */ 49 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */ 50 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */ 51 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */ 52 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */ 53 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */ 54 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */ 55 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */ 56 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */ 57 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */ 58 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */ 59 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */ 60 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */ 61 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */ 62 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */ 63 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */ 64 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */ 65}; 66#endif 67 68/* 69 * Count of bits set in byte, 0..8. 70 */ 71static const char xfs_countbit[256] = { 72 0, 1, 1, 2, 1, 2, 2, 3, /* 00 .. 07 */ 73 1, 2, 2, 3, 2, 3, 3, 4, /* 08 .. 0f */ 74 1, 2, 2, 3, 2, 3, 3, 4, /* 10 .. 17 */ 75 2, 3, 3, 4, 3, 4, 4, 5, /* 18 .. 1f */ 76 1, 2, 2, 3, 2, 3, 3, 4, /* 20 .. 27 */ 77 2, 3, 3, 4, 3, 4, 4, 5, /* 28 .. 2f */ 78 2, 3, 3, 4, 3, 4, 4, 5, /* 30 .. 37 */ 79 3, 4, 4, 5, 4, 5, 5, 6, /* 38 .. 3f */ 80 1, 2, 2, 3, 2, 3, 3, 4, /* 40 .. 47 */ 81 2, 3, 3, 4, 3, 4, 4, 5, /* 48 .. 4f */ 82 2, 3, 3, 4, 3, 4, 4, 5, /* 50 .. 57 */ 83 3, 4, 4, 5, 4, 5, 5, 6, /* 58 .. 5f */ 84 2, 3, 3, 4, 3, 4, 4, 5, /* 60 .. 67 */ 85 3, 4, 4, 5, 4, 5, 5, 6, /* 68 .. 6f */ 86 3, 4, 4, 5, 4, 5, 5, 6, /* 70 .. 77 */ 87 4, 5, 5, 6, 5, 6, 6, 7, /* 78 .. 7f */ 88 1, 2, 2, 3, 2, 3, 3, 4, /* 80 .. 87 */ 89 2, 3, 3, 4, 3, 4, 4, 5, /* 88 .. 8f */ 90 2, 3, 3, 4, 3, 4, 4, 5, /* 90 .. 97 */ 91 3, 4, 4, 5, 4, 5, 5, 6, /* 98 .. 9f */ 92 2, 3, 3, 4, 3, 4, 4, 5, /* a0 .. a7 */ 93 3, 4, 4, 5, 4, 5, 5, 6, /* a8 .. af */ 94 3, 4, 4, 5, 4, 5, 5, 6, /* b0 .. b7 */ 95 4, 5, 5, 6, 5, 6, 6, 7, /* b8 .. bf */ 96 2, 3, 3, 4, 3, 4, 4, 5, /* c0 .. c7 */ 97 3, 4, 4, 5, 4, 5, 5, 6, /* c8 .. cf */ 98 3, 4, 4, 5, 4, 5, 5, 6, /* d0 .. d7 */ 99 4, 5, 5, 6, 5, 6, 6, 7, /* d8 .. df */ 100 3, 4, 4, 5, 4, 5, 5, 6, /* e0 .. e7 */ 101 4, 5, 5, 6, 5, 6, 6, 7, /* e8 .. ef */ 102 4, 5, 5, 6, 5, 6, 6, 7, /* f0 .. f7 */ 103 5, 6, 6, 7, 6, 7, 7, 8, /* f8 .. ff */ 104}; 105 106/* 107 * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. 108 */ 109inline int 110xfs_highbit32( 111 __uint32_t v) 112{ 113#ifdef HAVE_ARCH_HIGHBIT 114 return highbit32(v); 115#else 116 int i; 117 118 if (v & 0xffff0000) 119 if (v & 0xff000000) 120 i = 24; 121 else 122 i = 16; 123 else if (v & 0x0000ffff) 124 if (v & 0x0000ff00) 125 i = 8; 126 else 127 i = 0; 128 else 129 return -1; 130 return i + xfs_highbit[(v >> i) & 0xff]; 131#endif 132} 133 134/* 135 * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set. 136 */ 137int 138xfs_lowbit64( 139 __uint64_t v) 140{ 141 __uint32_t w = (__uint32_t)v; 142 int n = 0; 143 144 if (w) { /* lower bits */ 145 n = ffs(w); 146 } else { /* upper bits */ 147 w = (__uint32_t)(v >> 32); 148 if (w && (n = ffs(w))) 149 n += 32; 150 } 151 return n - 1; 152} 153 154/* 155 * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set. 156 */ 157int 158xfs_highbit64( 159 __uint64_t v) 160{ 161 __uint32_t h = (__uint32_t)(v >> 32); 162 163 if (h) 164 return xfs_highbit32(h) + 32; 165 return xfs_highbit32((__uint32_t)v); 166} 167 168 169/* 170 * Count the number of bits set in the bitmap starting with bit 171 * start_bit. Size is the size of the bitmap in words. 172 * 173 * Do the counting by mapping a byte value to the number of set 174 * bits for that value using the xfs_countbit array, i.e. 175 * xfs_countbit[0] == 0, xfs_countbit[1] == 1, xfs_countbit[2] == 1, 176 * xfs_countbit[3] == 2, etc. 177 */ 178int 179xfs_count_bits(uint *map, uint size, uint start_bit) 180{ 181 register int bits; 182 register unsigned char *bytep; 183 register unsigned char *end_map; 184 int byte_bit; 185 186 bits = 0; 187 end_map = (char*)(map + size); 188 bytep = (char*)(map + (start_bit & ~0x7)); 189 byte_bit = start_bit & 0x7; 190 191 /* 192 * If the caller fell off the end of the map, return 0. 193 */ 194 if (bytep >= end_map) { 195 return (0); 196 } 197 198 /* 199 * If start_bit is not byte aligned, then process the 200 * first byte separately. 201 */ 202 if (byte_bit != 0) { 203 /* 204 * Shift off the bits we don't want to look at, 205 * before indexing into xfs_countbit. 206 */ 207 bits += xfs_countbit[(*bytep >> byte_bit)]; 208 bytep++; 209 } 210 211 /* 212 * Count the bits in each byte until the end of the bitmap. 213 */ 214 while (bytep < end_map) { 215 bits += xfs_countbit[*bytep]; 216 bytep++; 217 } 218 219 return (bits); 220} 221 222/* 223 * Count the number of contiguous bits set in the bitmap starting with bit 224 * start_bit. Size is the size of the bitmap in words. 225 */ 226int 227xfs_contig_bits(uint *map, uint size, uint start_bit) 228{ 229 uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT); 230 uint result = 0; 231 uint tmp; 232 233 size <<= BIT_TO_WORD_SHIFT; 234 235 ASSERT(start_bit < size); 236 size -= start_bit & ~(NBWORD - 1); 237 start_bit &= (NBWORD - 1); 238 if (start_bit) { 239 tmp = *p++; 240 /* set to one first offset bits prior to start */ 241 tmp |= (~0U >> (NBWORD-start_bit)); 242 if (tmp != ~0U) 243 goto found; 244 result += NBWORD; 245 size -= NBWORD; 246 } 247 while (size) { 248 if ((tmp = *p++) != ~0U) 249 goto found; 250 result += NBWORD; 251 size -= NBWORD; 252 } 253 return result - start_bit; 254found: 255 return result + ffz(tmp) - start_bit; 256} 257 258/* 259 * This takes the bit number to start looking from and 260 * returns the next set bit from there. It returns -1 261 * if there are no more bits set or the start bit is 262 * beyond the end of the bitmap. 263 * 264 * Size is the number of words, not bytes, in the bitmap. 265 */ 266int xfs_next_bit(uint *map, uint size, uint start_bit) 267{ 268 uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT); 269 uint result = start_bit & ~(NBWORD - 1); 270 uint tmp; 271 272 size <<= BIT_TO_WORD_SHIFT; 273 274 if (start_bit >= size) 275 return -1; 276 size -= result; 277 start_bit &= (NBWORD - 1); 278 if (start_bit) { 279 tmp = *p++; 280 /* set to zero first offset bits prior to start */ 281 tmp &= (~0U << start_bit); 282 if (tmp != 0U) 283 goto found; 284 result += NBWORD; 285 size -= NBWORD; 286 } 287 while (size) { 288 if ((tmp = *p++) != 0U) 289 goto found; 290 result += NBWORD; 291 size -= NBWORD; 292 } 293 return -1; 294found: 295 return result + ffs(tmp) - 1; 296}