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