bitops.h revision dec5cd13fff821d1d3f6a922fbd986b3a86abb77
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
17extern int ext2fs_set_bit(unsigned int nr,void * addr);
18extern int ext2fs_clear_bit(unsigned int nr, void * addr);
19extern int ext2fs_test_bit(unsigned int nr, const void * addr);
20extern void ext2fs_fast_set_bit(unsigned int nr,void * addr);
21extern void ext2fs_fast_clear_bit(unsigned int nr, void * addr);
22extern __u16 ext2fs_swab16(__u16 val);
23extern __u32 ext2fs_swab32(__u32 val);
24extern __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 */
55extern const char *ext2fs_block_string;
56extern const char *ext2fs_inode_string;
57extern const char *ext2fs_mark_string;
58extern const char *ext2fs_unmark_string;
59extern const char *ext2fs_test_string;
60extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
61			       const char *description);
62extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
63				int code, unsigned long arg);
64
65extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
66extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
67				       blk_t block);
68extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
69
70extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
71extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
72				       ext2_ino_t inode);
73extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
74
75extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
76					  blk_t block);
77extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
78					    blk_t block);
79extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
80					 blk_t block);
81
82extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
83					  ext2_ino_t inode);
84extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
85					    ext2_ino_t inode);
86extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
87					 ext2_ino_t inode);
88extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
89extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
90extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
91extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
92
93extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
94					   blk_t block, int num);
95extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
96					     blk_t block, int num);
97extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
98					  blk_t block, int num);
99extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
100						blk_t block, int num);
101extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
102						  blk_t block, int num);
103extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
104					       blk_t block, int num);
105extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
106
107/* These two routines moved to gen_bitmap.c */
108extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
109					 __u32 bitno);
110extern 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 */
179struct __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