Whamcloud - gitweb
cb04453ccc8c9a3d0ed909b0e368775f02ae4f19
[tools/e2fsprogs.git] / lib / 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 /* These two routines moved to gen_bitmap.c */
81 extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
82                                          __u32 bitno);
83 extern 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  */
131 struct __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