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