warnings: Add explict casts to silence many compiler warnings about sign comparisions.
[yaboot.git] / include / ext2fs / bitops.h
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
17 extern int ext2fs_set_bit(int nr,void * addr);
18 extern int ext2fs_clear_bit(int nr, void * addr);
19 extern int ext2fs_test_bit(int nr, const void * addr);
20 extern __u16 ext2fs_swab16(__u16 val);
21 extern __u32 ext2fs_swab32(__u32 val);
22
23 /*
24  * EXT2FS bitmap manipulation routines.
25  */
26
27 /* Support for sending warning messages from the inline subroutines */
28 extern const char *ext2fs_block_string;
29 extern const char *ext2fs_inode_string;
30 extern const char *ext2fs_mark_string;
31 extern const char *ext2fs_unmark_string;
32 extern const char *ext2fs_test_string;
33 extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
34                                const char *description);
35 extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
36                                 int code, unsigned long arg);
37
38 extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
39 extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
40                                        blk_t block);
41 extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
42
43 extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
44 extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
45                                        ext2_ino_t inode);
46 extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
47
48 extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
49                                           blk_t block);
50 extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
51                                             blk_t block);
52 extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
53                                          blk_t block);
54
55 extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
56                                           ext2_ino_t inode);
57 extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
58                                             ext2_ino_t inode);
59 extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
60                                          ext2_ino_t inode);
61 extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
62 extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
63 extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
64 extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
65
66 extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
67                                            blk_t block, int num);
68 extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
69                                              blk_t block, int num);
70 extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
71                                           blk_t block, int num);
72 extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
73                                                 blk_t block, int num);
74 extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
75                                                   blk_t block, int num);
76 extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
77                                                blk_t block, int num);
78 extern 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  */
126 struct __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 /* Use the prototype from builtin_ffs() */
414 extern int ffs(unsigned int);
415
416 _INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
417 {
418         unsigned char   *cp = (unsigned char *) addr;
419         int     res = 0, d0;
420
421         if (!size)
422                 return 0;
423
424         while ((size > res) && (*cp == 0)) {
425                 cp++;
426                 res += 8;
427         }
428         d0 = ffs(*cp);
429         if (d0 == 0)
430                 return size;
431
432         return res + d0 - 1;
433 }
434
435 _INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
436 {
437         unsigned char * p;
438         int set = 0, bit = offset & 7, res = 0, d0;
439
440         res = offset >> 3;
441         p = ((unsigned char *) addr) + res;
442
443         if (bit) {
444                 set = ffs(*p & ~((1 << bit) - 1));
445                 if (set)
446                         return (offset & ~7) + set - 1;
447                 p++;
448                 res += 8;
449         }
450         while ((size > res) && (*p == 0)) {
451                 p++;
452                 res += 8;
453         }
454         d0 = ffs(*p);
455         if (d0 == 0)
456                 return size;
457
458         return (res + d0 - 1);
459 }
460 #endif
461
462 /* These two routines moved to gen_bitmap.c */
463 extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
464                                          __u32 bitno);
465 extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
466                                            blk_t bitno);
467 _INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
468                                         blk_t bitno);
469
470 _INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
471                                         blk_t bitno)
472 {
473         if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
474                 ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
475                 return 0;
476         }
477         return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
478 }
479
480 _INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
481                                        blk_t block)
482 {
483         return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
484                                        bitmap,
485                                           block);
486 }
487
488 _INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
489                                          blk_t block)
490 {
491         return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
492                                             block);
493 }
494
495 _INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
496                                        blk_t block)
497 {
498         return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
499                                           block);
500 }
501
502 _INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
503                                        ext2_ino_t inode)
504 {
505         return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
506                                           inode);
507 }
508
509 _INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
510                                          ext2_ino_t inode)
511 {
512         return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
513                                      inode);
514 }
515
516 _INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
517                                        ext2_ino_t inode)
518 {
519         return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
520                                           inode);
521 }
522
523 _INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
524                                             blk_t block)
525 {
526 #ifdef EXT2FS_DEBUG_FAST_OPS
527         if ((block < bitmap->start) || (block > bitmap->end)) {
528                 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
529                                    bitmap->description);
530                 return;
531         }
532 #endif
533         ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
534 }
535
536 _INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
537                                               blk_t block)
538 {
539 #ifdef EXT2FS_DEBUG_FAST_OPS
540         if ((block < bitmap->start) || (block > bitmap->end)) {
541                 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
542                                    block, bitmap->description);
543                 return;
544         }
545 #endif
546         ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
547 }
548
549 _INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
550                                             blk_t block)
551 {
552 #ifdef EXT2FS_DEBUG_FAST_OPS
553         if ((block < bitmap->start) || (block > bitmap->end)) {
554                 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
555                                    block, bitmap->description);
556                 return 0;
557         }
558 #endif
559         return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
560 }
561
562 _INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
563                                             ext2_ino_t inode)
564 {
565 #ifdef EXT2FS_DEBUG_FAST_OPS
566         if ((inode < bitmap->start) || (inode > bitmap->end)) {
567                 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
568                                    inode, bitmap->description);
569                 return;
570         }
571 #endif
572         ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
573 }
574
575 _INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
576                                               ext2_ino_t inode)
577 {
578 #ifdef EXT2FS_DEBUG_FAST_OPS
579         if ((inode < bitmap->start) || (inode > bitmap->end)) {
580                 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
581                                    inode, bitmap->description);
582                 return;
583         }
584 #endif
585         ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
586 }
587
588 _INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
589                                            ext2_ino_t inode)
590 {
591 #ifdef EXT2FS_DEBUG_FAST_OPS
592         if ((inode < bitmap->start) || (inode > bitmap->end)) {
593                 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
594                                    inode, bitmap->description);
595                 return 0;
596         }
597 #endif
598         return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
599 }
600
601 _INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
602 {
603         return bitmap->start;
604 }
605
606 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
607 {
608         return bitmap->start;
609 }
610
611 _INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
612 {
613         return bitmap->end;
614 }
615
616 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
617 {
618         return bitmap->end;
619 }
620
621 _INLINE_ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
622                                             blk_t block, int num)
623 {
624         int     i;
625
626         if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
627                 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
628                                    block, bitmap->description);
629                 return 0;
630         }
631         for (i=0; i < num; i++) {
632                 if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
633                         return 0;
634         }
635         return 1;
636 }
637
638 _INLINE_ int ext2fs_fast_test_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_TEST,
646                                    block, bitmap->description);
647                 return 0;
648         }
649 #endif
650         for (i=0; i < num; i++) {
651                 if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
652                         return 0;
653         }
654         return 1;
655 }
656
657 _INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
658                                              blk_t block, int num)
659 {
660         int     i;
661
662         if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
663                 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
664                                    bitmap->description);
665                 return;
666         }
667         for (i=0; i < num; i++)
668                 ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
669 }
670
671 _INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
672                                                   blk_t block, int num)
673 {
674         int     i;
675
676 #ifdef EXT2FS_DEBUG_FAST_OPS
677         if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
678                 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
679                                    bitmap->description);
680                 return;
681         }
682 #endif
683         for (i=0; i < num; i++)
684                 ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
685 }
686
687 _INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
688                                                blk_t block, int num)
689 {
690         int     i;
691
692         if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
693                 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
694                                    bitmap->description);
695                 return;
696         }
697         for (i=0; i < num; i++)
698                 ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
699 }
700
701 _INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
702                                                     blk_t block, int num)
703 {
704         int     i;
705
706 #ifdef EXT2FS_DEBUG_FAST_OPS
707         if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
708                 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
709                                    bitmap->description);
710                 return;
711         }
712 #endif
713         for (i=0; i < num; i++)
714                 ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
715 }
716 #undef _INLINE_
717 #endif
718