bitops.h revision 4ea7bd04390935e1f8b473c8b857e518df2e226b
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/* These two routines moved to gen_bitmap.c */
81extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
82					 __u32 bitno);
83extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
84					   blk_t bitno);
85/*
86 * The inline routines themselves...
87 *
88 * If NO_INLINE_FUNCS is defined, then we won't try to do inline
89 * functions at all; they will be included as normal functions in
90 * inline.c
91 */
92#ifdef NO_INLINE_FUNCS
93#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
94			   defined(__i586__) || defined(__mc68000__) || \
95			   defined(__sparc__)))
96	/* This prevents bitops.c from trying to include the C */
97	/* function version of these functions */
98#define _EXT2_HAVE_ASM_BITOPS_
99#endif
100#endif /* NO_INLINE_FUNCS */
101
102#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
103#ifdef INCLUDE_INLINE_FUNCS
104#define _INLINE_ extern
105#else
106#ifdef __GNUC__
107#define _INLINE_ extern __inline__
108#else				/* For Watcom C */
109#define _INLINE_ extern inline
110#endif
111#endif
112
113#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
114     (defined(__i386__) || defined(__i486__) || defined(__i586__)))
115
116#define _EXT2_HAVE_ASM_BITOPS_
117#define _EXT2_HAVE_ASM_SWAB_
118#define _EXT2_HAVE_ASM_FINDBIT_
119
120/*
121 * These are done by inline assembly for speed reasons.....
122 *
123 * All bitoperations return 0 if the bit was cleared before the
124 * operation and != 0 if it was not.  Bit 0 is the LSB of addr; bit 32
125 * is the LSB of (addr+1).
126 */
127
128/*
129 * Some hacks to defeat gcc over-optimizations..
130 */
131struct __dummy_h { unsigned long a[100]; };
132#define EXT2FS_ADDR (*(struct __dummy_h *) addr)
133#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
134
135_INLINE_ int ext2fs_set_bit(int nr, void * addr)
136{
137	int oldbit;
138
139	__asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
140		:"=r" (oldbit),"=m" (EXT2FS_ADDR)
141		:"r" (nr));
142	return oldbit;
143}
144
145_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
146{
147	int oldbit;
148
149	__asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
150		:"=r" (oldbit),"=m" (EXT2FS_ADDR)
151		:"r" (nr));
152	return oldbit;
153}
154
155_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
156{
157	int oldbit;
158
159	__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
160		:"=r" (oldbit)
161		:"m" (EXT2FS_CONST_ADDR),"r" (nr));
162	return oldbit;
163}
164
165#if 0
166_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
167{
168	int d0, d1, d2;
169	int res;
170
171	if (!size)
172		return 0;
173	/* This looks at memory. Mark it volatile to tell gcc not to move it around */
174	__asm__ __volatile__(
175		"cld\n\t"
176		"xorl %%eax,%%eax\n\t"
177		"xorl %%edx,%%edx\n\t"
178		"repe; scasl\n\t"
179		"je 1f\n\t"
180		"movl -4(%%edi),%%eax\n\t"
181		"subl $4,%%edi\n\t"
182		"bsfl %%eax,%%edx\n"
183		"1:\tsubl %%esi,%%edi\n\t"
184		"shll $3,%%edi\n\t"
185		"addl %%edi,%%edx"
186		:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
187		:"1" ((size + 31) >> 5), "2" (addr), "S" (addr));
188	return res;
189}
190
191_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
192{
193	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
194	int set = 0, bit = offset & 31, res;
195
196	if (bit) {
197		/*
198		 * Look for zero in first byte
199		 */
200		__asm__("bsfl %1,%0\n\t"
201			"jne 1f\n\t"
202			"movl $32, %0\n"
203			"1:"
204			: "=r" (set)
205			: "r" (*p >> bit));
206		if (set < (32 - bit))
207			return set + offset;
208		set = 32 - bit;
209		p++;
210	}
211	/*
212	 * No bit found yet, search remaining full bytes for a bit
213	 */
214	res = ext2fs_find_first_bit_set(p, size - 32 * (p - (unsigned long *) addr));
215	return (offset + set + res);
216}
217#endif
218
219#ifdef EXT2FS_ENABLE_SWAPFS
220_INLINE_ __u32 ext2fs_swab32(__u32 val)
221{
222#ifdef EXT2FS_REQUIRE_486
223	__asm__("bswap %0" : "=r" (val) : "0" (val));
224#else
225	__asm__("xchgb %b0,%h0\n\t"	/* swap lower bytes	*/
226		"rorl $16,%0\n\t"	/* swap words		*/
227		"xchgb %b0,%h0"		/* swap higher bytes	*/
228		:"=q" (val)
229		: "0" (val));
230#endif
231	return val;
232}
233
234_INLINE_ __u16 ext2fs_swab16(__u16 val)
235{
236	__asm__("xchgb %b0,%h0"		/* swap bytes		*/ \
237		: "=q" (val) \
238		:  "0" (val)); \
239		return val;
240}
241#endif
242
243#undef EXT2FS_ADDR
244
245#endif	/* i386 */
246
247#ifdef __mc68000__
248
249#define _EXT2_HAVE_ASM_BITOPS_
250
251_INLINE_ int ext2fs_set_bit(int nr,void * addr)
252{
253	char retval;
254
255	__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
256	     : "=d" (retval) : "d" (nr^7), "a" (addr));
257
258	return retval;
259}
260
261_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
262{
263	char retval;
264
265	__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
266	     : "=d" (retval) : "d" (nr^7), "a" (addr));
267
268	return retval;
269}
270
271_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
272{
273	char retval;
274
275	__asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
276	     : "=d" (retval) : "d" (nr^7), "a" (addr));
277
278	return retval;
279}
280
281#endif /* __mc68000__ */
282
283#ifdef __sparc__
284
285#define _EXT2_HAVE_ASM_BITOPS_
286
287#ifndef EXT2_OLD_BITOPS
288
289/*
290 * Do the bitops so that we are compatible with the standard i386
291 * convention.
292 */
293
294_INLINE_ int ext2fs_set_bit(int nr,void * addr)
295{
296#if 1
297	int		mask;
298	unsigned char	*ADDR = (unsigned char *) addr;
299
300	ADDR += nr >> 3;
301	mask = 1 << (nr & 0x07);
302	__asm__ __volatile__("ldub	[%0], %%g6\n\t"
303			     "or	%%g6, %2, %%g5\n\t"
304			     "stb	%%g5, [%0]\n\t"
305			     "and	%%g6, %2, %0\n"
306	: "=&r" (ADDR)
307	: "0" (ADDR), "r" (mask)
308	: "g5", "g6");
309	return (int) ADDR;
310#else
311	int		mask, retval;
312	unsigned char	*ADDR = (unsigned char *) addr;
313
314	ADDR += nr >> 3;
315	mask = 1 << (nr & 0x07);
316	retval = (mask & *ADDR) != 0;
317	*ADDR |= mask;
318	return retval;
319#endif
320}
321
322_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
323{
324#if 1
325	int		mask;
326	unsigned char	*ADDR = (unsigned char *) addr;
327
328	ADDR += nr >> 3;
329	mask = 1 << (nr & 0x07);
330	__asm__ __volatile__("ldub	[%0], %%g6\n\t"
331			     "andn	%%g6, %2, %%g5\n\t"
332			     "stb	%%g5, [%0]\n\t"
333			     "and	%%g6, %2, %0\n"
334	: "=&r" (ADDR)
335	: "0" (ADDR), "r" (mask)
336	: "g5", "g6");
337	return (int) ADDR;
338
339#else
340	int		mask, retval;
341	unsigned char	*ADDR = (unsigned char *) addr;
342
343	ADDR += nr >> 3;
344	mask = 1 << (nr & 0x07);
345	retval = (mask & *ADDR) != 0;
346	*ADDR &= ~mask;
347	return retval;
348#endif
349}
350
351_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
352{
353	int			mask;
354	const unsigned char	*ADDR = (const unsigned char *) addr;
355
356	ADDR += nr >> 3;
357	mask = 1 << (nr & 0x07);
358	return ((mask & *ADDR) != 0);
359}
360
361#else
362
363/* Do things the old, unplesant way. */
364
365_INLINE_ int ext2fs_set_bit(int nr, void *addr)
366{
367	int		mask, retval;
368	unsigned long	*ADDR = (unsigned long *) addr;
369
370	ADDR += nr >> 5;
371	mask = 1 << (nr & 31);
372	retval = ((mask & *ADDR) != 0);
373	*ADDR |= mask;
374	return retval;
375}
376
377_INLINE_ int ext2fs_clear_bit(int nr, void *addr)
378{
379	int		mask, retval;
380	unsigned long	*ADDR = (unsigned long *) addr;
381
382	ADDR += nr >> 5;
383	mask = 1 << (nr & 31);
384	retval = ((mask & *ADDR) != 0);
385	*ADDR &= ~mask;
386	return retval;
387}
388
389_INLINE_ int ext2fs_test_bit(int nr, const void *addr)
390{
391	int			mask;
392	const unsigned long	*ADDR = (const unsigned long *) addr;
393
394	ADDR += nr >> 5;
395	mask = 1 << (nr & 31);
396	return ((mask & *ADDR) != 0);
397}
398#endif
399
400#endif /* __sparc__ */
401
402#if !defined(_EXT2_HAVE_ASM_SWAB_) && defined(EXT2FS_ENABLE_SWAPFS)
403
404_INLINE_ __u16 ext2fs_swab16(__u16 val)
405{
406	return (val >> 8) | (val << 8);
407}
408
409_INLINE_ __u32 ext2fs_swab32(__u32 val)
410{
411	return ((val>>24) | ((val>>8)&0xFF00) |
412		((val<<8)&0xFF0000) | (val<<24));
413}
414
415#endif /* !_EXT2_HAVE_ASM_SWAB */
416
417#if !defined(_EXT2_HAVE_ASM_FINDBIT_)
418_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
419{
420	char	*cp = (unsigned char *) addr;
421	int 	res = 0, d0;
422
423	if (!size)
424		return 0;
425
426	while ((size > res) && (*cp == 0)) {
427		cp++;
428		res += 8;
429	}
430	d0 = ffs(*cp);
431	if (d0 == 0)
432		return size;
433
434	return res + d0 - 1;
435}
436
437_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
438{
439	unsigned char * p;
440	int set = 0, bit = offset & 7, res = 0, d0;
441
442	res = offset >> 3;
443	p = ((unsigned char *) addr) + res;
444
445	if (bit) {
446		set = ffs(*p & ~((1 << bit) - 1));
447		if (set)
448			return (offset & ~7) + set - 1;
449		p++;
450		res += 8;
451	}
452	while ((size > res) && (*p == 0)) {
453		p++;
454		res += 8;
455	}
456	d0 = ffs(*p);
457	if (d0 == 0)
458		return size;
459
460	return (res + d0 - 1);
461}
462#endif
463
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