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