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