]> git.ozlabs.org Git - yaboot.git/blob - include/ext2fs/bitops.h
Commit yaboot 1.3.5-pre1
[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 _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 */
460 extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
461                                          __u32 bitno);
462 extern 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