Home | History | Annotate | Download | only in ext2fs
      1 /*
      2  * bitops.h --- Bitmap frobbing code.  The byte swapping routines are
      3  * 	also included here.
      4  *
      5  * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
      6  *
      7  * %Begin-Header%
      8  * This file may be redistributed under the terms of the GNU Public
      9  * License.
     10  * %End-Header%
     11  *
     12  * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
     13  * Linus Torvalds.
     14  */
     15 
     16 
     17 extern int ext2fs_set_bit(unsigned int nr,void * addr);
     18 extern int ext2fs_clear_bit(unsigned int nr, void * addr);
     19 extern int ext2fs_test_bit(unsigned int nr, const void * addr);
     20 extern void ext2fs_fast_set_bit(unsigned int nr,void * addr);
     21 extern void ext2fs_fast_clear_bit(unsigned int nr, void * addr);
     22 extern __u16 ext2fs_swab16(__u16 val);
     23 extern __u32 ext2fs_swab32(__u32 val);
     24 extern __u64 ext2fs_swab64(__u64 val);
     25 
     26 #ifdef WORDS_BIGENDIAN
     27 #define ext2fs_cpu_to_le64(x) ext2fs_swab64((x))
     28 #define ext2fs_le64_to_cpu(x) ext2fs_swab64((x))
     29 #define ext2fs_cpu_to_le32(x) ext2fs_swab32((x))
     30 #define ext2fs_le32_to_cpu(x) ext2fs_swab32((x))
     31 #define ext2fs_cpu_to_le16(x) ext2fs_swab16((x))
     32 #define ext2fs_le16_to_cpu(x) ext2fs_swab16((x))
     33 #define ext2fs_cpu_to_be32(x) ((__u32)(x))
     34 #define ext2fs_be32_to_cpu(x) ((__u32)(x))
     35 #define ext2fs_cpu_to_be16(x) ((__u16)(x))
     36 #define ext2fs_be16_to_cpu(x) ((__u16)(x))
     37 #else
     38 #define ext2fs_cpu_to_le64(x) ((__u64)(x))
     39 #define ext2fs_le64_to_cpu(x) ((__u64)(x))
     40 #define ext2fs_cpu_to_le32(x) ((__u32)(x))
     41 #define ext2fs_le32_to_cpu(x) ((__u32)(x))
     42 #define ext2fs_cpu_to_le16(x) ((__u16)(x))
     43 #define ext2fs_le16_to_cpu(x) ((__u16)(x))
     44 #define ext2fs_cpu_to_be32(x) ext2fs_swab32((x))
     45 #define ext2fs_be32_to_cpu(x) ext2fs_swab32((x))
     46 #define ext2fs_cpu_to_be16(x) ext2fs_swab16((x))
     47 #define ext2fs_be16_to_cpu(x) ext2fs_swab16((x))
     48 #endif
     49 
     50 /*
     51  * EXT2FS bitmap manipulation routines.
     52  */
     53 
     54 /* Support for sending warning messages from the inline subroutines */
     55 extern const char *ext2fs_block_string;
     56 extern const char *ext2fs_inode_string;
     57 extern const char *ext2fs_mark_string;
     58 extern const char *ext2fs_unmark_string;
     59 extern const char *ext2fs_test_string;
     60 extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
     61 			       const char *description);
     62 extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
     63 				int code, unsigned long arg);
     64 
     65 extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
     66 extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
     67 				       blk_t block);
     68 extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
     69 
     70 extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
     71 extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
     72 				       ext2_ino_t inode);
     73 extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
     74 
     75 extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
     76 					  blk_t block);
     77 extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
     78 					    blk_t block);
     79 extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
     80 					 blk_t block);
     81 
     82 extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
     83 					  ext2_ino_t inode);
     84 extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
     85 					    ext2_ino_t inode);
     86 extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
     87 					 ext2_ino_t inode);
     88 extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
     89 extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
     90 extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
     91 extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
     92 
     93 extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
     94 					   blk_t block, int num);
     95 extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
     96 					     blk_t block, int num);
     97 extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
     98 					  blk_t block, int num);
     99 extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
    100 						blk_t block, int num);
    101 extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
    102 						  blk_t block, int num);
    103 extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
    104 					       blk_t block, int num);
    105 extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
    106 
    107 /* These two routines moved to gen_bitmap.c */
    108 extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
    109 					 __u32 bitno);
    110 extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
    111 					   blk_t bitno);
    112 /*
    113  * The inline routines themselves...
    114  *
    115  * If NO_INLINE_FUNCS is defined, then we won't try to do inline
    116  * functions at all; they will be included as normal functions in
    117  * inline.c
    118  */
    119 #ifdef NO_INLINE_FUNCS
    120 #if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
    121 			   defined(__i586__) || defined(__mc68000__)))
    122 	/* This prevents bitops.c from trying to include the C */
    123 	/* function version of these functions */
    124 #define _EXT2_HAVE_ASM_BITOPS_
    125 #endif
    126 #endif /* NO_INLINE_FUNCS */
    127 
    128 #if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
    129 #ifdef INCLUDE_INLINE_FUNCS
    130 #define _INLINE_ extern
    131 #else
    132 #ifdef __GNUC__
    133 #define _INLINE_ extern __inline__
    134 #else				/* For Watcom C */
    135 #define _INLINE_ extern inline
    136 #endif
    137 #endif
    138 
    139 /*
    140  * Fast bit set/clear functions that doesn't need to return the
    141  * previous bit value.
    142  */
    143 
    144 _INLINE_ void ext2fs_fast_set_bit(unsigned int nr,void * addr)
    145 {
    146 	unsigned char	*ADDR = (unsigned char *) addr;
    147 
    148 	ADDR += nr >> 3;
    149 	*ADDR |= (1 << (nr & 0x07));
    150 }
    151 
    152 _INLINE_ void ext2fs_fast_clear_bit(unsigned int nr, void * addr)
    153 {
    154 	unsigned char	*ADDR = (unsigned char *) addr;
    155 
    156 	ADDR += nr >> 3;
    157 	*ADDR &= ~(1 << (nr & 0x07));
    158 }
    159 
    160 
    161 #if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
    162      (defined(__i386__) || defined(__i486__) || defined(__i586__)))
    163 
    164 #define _EXT2_HAVE_ASM_BITOPS_
    165 #define _EXT2_HAVE_ASM_SWAB_
    166 #define _EXT2_HAVE_ASM_FINDBIT_
    167 
    168 /*
    169  * These are done by inline assembly for speed reasons.....
    170  *
    171  * All bitoperations return 0 if the bit was cleared before the
    172  * operation and != 0 if it was not.  Bit 0 is the LSB of addr; bit 32
    173  * is the LSB of (addr+1).
    174  */
    175 
    176 /*
    177  * Some hacks to defeat gcc over-optimizations..
    178  */
    179 struct __dummy_h { unsigned long a[100]; };
    180 #define EXT2FS_ADDR (*(struct __dummy_h *) addr)
    181 #define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
    182 
    183 _INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr)
    184 {
    185 	int oldbit;
    186 
    187 	addr = (void *) (((unsigned char *) addr) + (nr >> 3));
    188 	__asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
    189 		:"=r" (oldbit),"+m" (EXT2FS_ADDR)
    190 		:"r" (nr & 7));
    191 	return oldbit;
    192 }
    193 
    194 _INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
    195 {
    196 	int oldbit;
    197 
    198 	addr = (void *) (((unsigned char *) addr) + (nr >> 3));
    199 	__asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
    200 		:"=r" (oldbit),"+m" (EXT2FS_ADDR)
    201 		:"r" (nr & 7));
    202 	return oldbit;
    203 }
    204 
    205 _INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
    206 {
    207 	int oldbit;
    208 
    209 	addr = (const void *) (((const unsigned char *) addr) + (nr >> 3));
    210 	__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
    211 		:"=r" (oldbit)
    212 		:"m" (EXT2FS_CONST_ADDR),"r" (nr & 7));
    213 	return oldbit;
    214 }
    215 
    216 #if 0
    217 _INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
    218 {
    219 	int d0, d1, d2;
    220 	int res;
    221 
    222 	if (!size)
    223 		return 0;
    224 	/* This looks at memory. Mark it volatile to tell gcc not to move it around */
    225 	__asm__ __volatile__(
    226 		"cld\n\t"
    227 		"xorl %%eax,%%eax\n\t"
    228 		"xorl %%edx,%%edx\n\t"
    229 		"repe; scasl\n\t"
    230 		"je 1f\n\t"
    231 		"movl -4(%%edi),%%eax\n\t"
    232 		"subl $4,%%edi\n\t"
    233 		"bsfl %%eax,%%edx\n"
    234 		"1:\tsubl %%esi,%%edi\n\t"
    235 		"shll $3,%%edi\n\t"
    236 		"addl %%edi,%%edx"
    237 		:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
    238 		:"1" ((size + 31) >> 5), "2" (addr), "S" (addr));
    239 	return res;
    240 }
    241 
    242 _INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
    243 {
    244 	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
    245 	int set = 0, bit = offset & 31, res;
    246 
    247 	if (bit) {
    248 		/*
    249 		 * Look for zero in first byte
    250 		 */
    251 		__asm__("bsfl %1,%0\n\t"
    252 			"jne 1f\n\t"
    253 			"movl $32, %0\n"
    254 			"1:"
    255 			: "=r" (set)
    256 			: "r" (*p >> bit));
    257 		if (set < (32 - bit))
    258 			return set + offset;
    259 		set = 32 - bit;
    260 		p++;
    261 	}
    262 	/*
    263 	 * No bit found yet, search remaining full bytes for a bit
    264 	 */
    265 	res = ext2fs_find_first_bit_set(p, size - 32 * (p - (unsigned long *) addr));
    266 	return (offset + set + res);
    267 }
    268 #endif
    269 
    270 #ifdef EXT2FS_ENABLE_SWAPFS
    271 _INLINE_ __u32 ext2fs_swab32(__u32 val)
    272 {
    273 #ifdef EXT2FS_REQUIRE_486
    274 	__asm__("bswap %0" : "=r" (val) : "0" (val));
    275 #else
    276 	__asm__("xchgb %b0,%h0\n\t"	/* swap lower bytes	*/
    277 		"rorl $16,%0\n\t"	/* swap words		*/
    278 		"xchgb %b0,%h0"		/* swap higher bytes	*/
    279 		:"=q" (val)
    280 		: "0" (val));
    281 #endif
    282 	return val;
    283 }
    284 
    285 _INLINE_ __u16 ext2fs_swab16(__u16 val)
    286 {
    287 	__asm__("xchgb %b0,%h0"		/* swap bytes		*/ \
    288 		: "=q" (val) \
    289 		:  "0" (val)); \
    290 		return val;
    291 }
    292 
    293 _INLINE_ __u64 ext2fs_swab64(__u64 val)
    294 {
    295 	return (ext2fs_swab32(val >> 32) |
    296 		(((__u64)ext2fs_swab32(val & 0xFFFFFFFFUL)) << 32));
    297 }
    298 #endif
    299 
    300 #undef EXT2FS_ADDR
    301 
    302 #endif	/* i386 */
    303 
    304 #if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
    305      (defined(__mc68000__)))
    306 
    307 #define _EXT2_HAVE_ASM_BITOPS_
    308 
    309 _INLINE_ int ext2fs_set_bit(unsigned int nr,void * addr)
    310 {
    311 	char retval;
    312 
    313 	__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
    314 	     : "=d" (retval) : "d" (nr^7), "a" (addr));
    315 
    316 	return retval;
    317 }
    318 
    319 _INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
    320 {
    321 	char retval;
    322 
    323 	__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
    324 	     : "=d" (retval) : "d" (nr^7), "a" (addr));
    325 
    326 	return retval;
    327 }
    328 
    329 _INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
    330 {
    331 	char retval;
    332 
    333 	__asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
    334 	     : "=d" (retval) : "d" (nr^7), "a" (addr));
    335 
    336 	return retval;
    337 }
    338 
    339 #endif /* __mc68000__ */
    340 
    341 
    342 #if !defined(_EXT2_HAVE_ASM_SWAB_) && defined(EXT2FS_ENABLE_SWAPFS)
    343 
    344 _INLINE_ __u16 ext2fs_swab16(__u16 val)
    345 {
    346 	return (val >> 8) | (val << 8);
    347 }
    348 
    349 _INLINE_ __u32 ext2fs_swab32(__u32 val)
    350 {
    351 	return ((val>>24) | ((val>>8)&0xFF00) |
    352 		((val<<8)&0xFF0000) | (val<<24));
    353 }
    354 
    355 #endif /* !_EXT2_HAVE_ASM_SWAB */
    356 
    357 #if !defined(_EXT2_HAVE_ASM_FINDBIT_)
    358 _INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
    359 {
    360 	char	*cp = (char *) addr;
    361 	int 	res = 0, d0;
    362 
    363 	if (!size)
    364 		return 0;
    365 
    366 	while ((size > res) && (*cp == 0)) {
    367 		cp++;
    368 		res += 8;
    369 	}
    370 	d0 = ffs(*cp);
    371 	if (d0 == 0)
    372 		return size;
    373 
    374 	return res + d0 - 1;
    375 }
    376 
    377 _INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
    378 {
    379 	unsigned char * p;
    380 	int set = 0, bit = offset & 7, res = 0, d0;
    381 
    382 	res = offset >> 3;
    383 	p = ((unsigned char *) addr) + res;
    384 
    385 	if (bit) {
    386 		set = ffs(*p & ~((1 << bit) - 1));
    387 		if (set)
    388 			return (offset & ~7) + set - 1;
    389 		p++;
    390 		res += 8;
    391 	}
    392 	while ((size > res) && (*p == 0)) {
    393 		p++;
    394 		res += 8;
    395 	}
    396 	d0 = ffs(*p);
    397 	if (d0 == 0)
    398 		return size;
    399 
    400 	return (res + d0 - 1);
    401 }
    402 #endif
    403 
    404 _INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
    405 					blk_t bitno);
    406 
    407 _INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
    408 					blk_t bitno)
    409 {
    410 	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
    411 		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
    412 		return 0;
    413 	}
    414 	return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
    415 }
    416 
    417 _INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
    418 				       blk_t block)
    419 {
    420 	return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
    421 				       bitmap,
    422 					  block);
    423 }
    424 
    425 _INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
    426 					 blk_t block)
    427 {
    428 	return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
    429 					    block);
    430 }
    431 
    432 _INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
    433 				       blk_t block)
    434 {
    435 	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
    436 					  block);
    437 }
    438 
    439 _INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
    440 				       ext2_ino_t inode)
    441 {
    442 	return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
    443 					  inode);
    444 }
    445 
    446 _INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
    447 					 ext2_ino_t inode)
    448 {
    449 	return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
    450 				     inode);
    451 }
    452 
    453 _INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
    454 				       ext2_ino_t inode)
    455 {
    456 	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
    457 					  inode);
    458 }
    459 
    460 _INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
    461 					    blk_t block)
    462 {
    463 #ifdef EXT2FS_DEBUG_FAST_OPS
    464 	if ((block < bitmap->start) || (block > bitmap->end)) {
    465 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
    466 				   bitmap->description);
    467 		return;
    468 	}
    469 #endif
    470 	ext2fs_fast_set_bit(block - bitmap->start, bitmap->bitmap);
    471 }
    472 
    473 _INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
    474 					      blk_t block)
    475 {
    476 #ifdef EXT2FS_DEBUG_FAST_OPS
    477 	if ((block < bitmap->start) || (block > bitmap->end)) {
    478 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
    479 				   block, bitmap->description);
    480 		return;
    481 	}
    482 #endif
    483 	ext2fs_fast_clear_bit(block - bitmap->start, bitmap->bitmap);
    484 }
    485 
    486 _INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
    487 					    blk_t block)
    488 {
    489 #ifdef EXT2FS_DEBUG_FAST_OPS
    490 	if ((block < bitmap->start) || (block > bitmap->end)) {
    491 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
    492 				   block, bitmap->description);
    493 		return 0;
    494 	}
    495 #endif
    496 	return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
    497 }
    498 
    499 _INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
    500 					    ext2_ino_t inode)
    501 {
    502 #ifdef EXT2FS_DEBUG_FAST_OPS
    503 	if ((inode < bitmap->start) || (inode > bitmap->end)) {
    504 		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
    505 				   inode, bitmap->description);
    506 		return;
    507 	}
    508 #endif
    509 	ext2fs_fast_set_bit(inode - bitmap->start, bitmap->bitmap);
    510 }
    511 
    512 _INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
    513 					      ext2_ino_t inode)
    514 {
    515 #ifdef EXT2FS_DEBUG_FAST_OPS
    516 	if ((inode < bitmap->start) || (inode > bitmap->end)) {
    517 		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
    518 				   inode, bitmap->description);
    519 		return;
    520 	}
    521 #endif
    522 	ext2fs_fast_clear_bit(inode - bitmap->start, bitmap->bitmap);
    523 }
    524 
    525 _INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
    526 					   ext2_ino_t inode)
    527 {
    528 #ifdef EXT2FS_DEBUG_FAST_OPS
    529 	if ((inode < bitmap->start) || (inode > bitmap->end)) {
    530 		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
    531 				   inode, bitmap->description);
    532 		return 0;
    533 	}
    534 #endif
    535 	return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
    536 }
    537 
    538 _INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
    539 {
    540 	return bitmap->start;
    541 }
    542 
    543 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
    544 {
    545 	return bitmap->start;
    546 }
    547 
    548 _INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
    549 {
    550 	return bitmap->end;
    551 }
    552 
    553 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
    554 {
    555 	return bitmap->end;
    556 }
    557 
    558 _INLINE_ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
    559 					    blk_t block, int num)
    560 {
    561 	int	i;
    562 
    563 	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
    564 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
    565 				   block, bitmap->description);
    566 		return 0;
    567 	}
    568 	for (i=0; i < num; i++) {
    569 		if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
    570 			return 0;
    571 	}
    572 	return 1;
    573 }
    574 
    575 _INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
    576 						 blk_t block, int num)
    577 {
    578 	int	i;
    579 
    580 #ifdef EXT2FS_DEBUG_FAST_OPS
    581 	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
    582 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
    583 				   block, bitmap->description);
    584 		return 0;
    585 	}
    586 #endif
    587 	for (i=0; i < num; i++) {
    588 		if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
    589 			return 0;
    590 	}
    591 	return 1;
    592 }
    593 
    594 _INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
    595 					     blk_t block, int num)
    596 {
    597 	int	i;
    598 
    599 	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
    600 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
    601 				   bitmap->description);
    602 		return;
    603 	}
    604 	for (i=0; i < num; i++)
    605 		ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
    606 }
    607 
    608 _INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
    609 						  blk_t block, int num)
    610 {
    611 	int	i;
    612 
    613 #ifdef EXT2FS_DEBUG_FAST_OPS
    614 	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
    615 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
    616 				   bitmap->description);
    617 		return;
    618 	}
    619 #endif
    620 	for (i=0; i < num; i++)
    621 		ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
    622 }
    623 
    624 _INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
    625 					       blk_t block, int num)
    626 {
    627 	int	i;
    628 
    629 	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
    630 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
    631 				   bitmap->description);
    632 		return;
    633 	}
    634 	for (i=0; i < num; i++)
    635 		ext2fs_fast_clear_bit(block + i - bitmap->start,
    636 				      bitmap->bitmap);
    637 }
    638 
    639 _INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
    640 						    blk_t block, int num)
    641 {
    642 	int	i;
    643 
    644 #ifdef EXT2FS_DEBUG_FAST_OPS
    645 	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
    646 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
    647 				   bitmap->description);
    648 		return;
    649 	}
    650 #endif
    651 	for (i=0; i < num; i++)
    652 		ext2fs_fast_clear_bit(block + i - bitmap->start,
    653 				      bitmap->bitmap);
    654 }
    655 #undef _INLINE_
    656 #endif
    657 
    658