2 * bitops.h --- Bitmap frobbing code. The byte swapping routines are
5 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
8 * This file may be redistributed under the terms of the GNU Public
12 * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
17 extern int ext2fs_set_bit(unsigned int nr,void * addr);
18 extern int ext2fs_clear_bit(unsigned int nr, void * addr);
19 extern int ext2fs_test_bit(unsigned int nr, const void * addr);
20 extern void ext2fs_fast_set_bit(unsigned int nr,void * addr);
21 extern void ext2fs_fast_clear_bit(unsigned int nr, void * addr);
22 extern int ext2fs_set_bit64(__u64 nr,void * addr);
23 extern int ext2fs_clear_bit64(__u64 nr, void * addr);
24 extern int ext2fs_test_bit64(__u64 nr, const void * addr);
25 extern void ext2fs_fast_set_bit64(__u64 nr,void * addr);
26 extern void ext2fs_fast_clear_bit64(__u64 nr, void * addr);
27 extern __u16 ext2fs_swab16(__u16 val);
28 extern __u32 ext2fs_swab32(__u32 val);
29 extern __u64 ext2fs_swab64(__u64 val);
31 #ifdef WORDS_BIGENDIAN
32 #define ext2fs_cpu_to_le64(x) ext2fs_swab64((x))
33 #define ext2fs_le64_to_cpu(x) ext2fs_swab64((x))
34 #define ext2fs_cpu_to_le32(x) ext2fs_swab32((x))
35 #define ext2fs_le32_to_cpu(x) ext2fs_swab32((x))
36 #define ext2fs_cpu_to_le16(x) ext2fs_swab16((x))
37 #define ext2fs_le16_to_cpu(x) ext2fs_swab16((x))
38 #define ext2fs_cpu_to_be32(x) ((__u32)(x))
39 #define ext2fs_be32_to_cpu(x) ((__u32)(x))
40 #define ext2fs_cpu_to_be16(x) ((__u16)(x))
41 #define ext2fs_be16_to_cpu(x) ((__u16)(x))
43 #define ext2fs_cpu_to_le64(x) ((__u64)(x))
44 #define ext2fs_le64_to_cpu(x) ((__u64)(x))
45 #define ext2fs_cpu_to_le32(x) ((__u32)(x))
46 #define ext2fs_le32_to_cpu(x) ((__u32)(x))
47 #define ext2fs_cpu_to_le16(x) ((__u16)(x))
48 #define ext2fs_le16_to_cpu(x) ((__u16)(x))
49 #define ext2fs_cpu_to_be32(x) ext2fs_swab32((x))
50 #define ext2fs_be32_to_cpu(x) ext2fs_swab32((x))
51 #define ext2fs_cpu_to_be16(x) ext2fs_swab16((x))
52 #define ext2fs_be16_to_cpu(x) ext2fs_swab16((x))
56 * EXT2FS bitmap manipulation routines.
59 /* Support for sending warning messages from the inline subroutines */
60 extern const char *ext2fs_block_string;
61 extern const char *ext2fs_inode_string;
62 extern const char *ext2fs_mark_string;
63 extern const char *ext2fs_unmark_string;
64 extern const char *ext2fs_test_string;
65 extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
66 const char *description);
67 extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
68 int code, unsigned long arg);
70 extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
71 extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
73 extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
75 extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
76 extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
78 extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
80 extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
82 extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
84 extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
87 extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
89 extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
91 extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
93 extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
94 extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
95 extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
96 extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
98 extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
99 blk_t block, int num);
100 extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
101 blk_t block, int num);
102 extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
103 blk_t block, int num);
104 extern int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
105 ino_t inode, int num);
106 extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
107 blk_t block, int num);
108 extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
109 blk_t block, int num);
110 extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
111 blk_t block, int num);
112 extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
114 /* These routines moved to gen_bitmap.c (actually, some of the above, too) */
115 extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
117 extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
119 extern int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
121 extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
122 blk_t block, int num);
123 extern __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap);
124 extern __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap);
126 /* 64-bit versions */
128 extern int ext2fs_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
130 extern int ext2fs_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
132 extern int ext2fs_test_block_bitmap2(ext2fs_block_bitmap bitmap,
135 extern int ext2fs_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
137 extern int ext2fs_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
139 extern int ext2fs_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
142 extern void ext2fs_fast_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
144 extern void ext2fs_fast_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
146 extern int ext2fs_fast_test_block_bitmap2(ext2fs_block_bitmap bitmap,
149 extern void ext2fs_fast_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
151 extern void ext2fs_fast_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
153 extern int ext2fs_fast_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
155 extern blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap bitmap);
156 extern ext2_ino_t ext2fs_get_inode_bitmap_start2(ext2fs_inode_bitmap bitmap);
157 extern blk64_t ext2fs_get_block_bitmap_end2(ext2fs_block_bitmap bitmap);
158 extern ext2_ino_t ext2fs_get_inode_bitmap_end2(ext2fs_inode_bitmap bitmap);
160 extern int ext2fs_fast_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
163 extern void ext2fs_fast_mark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
166 extern void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
169 /* These routines moved to gen_bitmap64.c */
170 extern void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap);
171 extern errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
172 ext2fs_generic_bitmap bm1,
173 ext2fs_generic_bitmap bm2);
174 extern void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap);
175 extern int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
177 extern int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
179 extern int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
181 extern int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
182 blk64_t block, unsigned int num);
183 extern __u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap bitmap);
184 extern __u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap bitmap);
185 extern int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
186 blk64_t block, unsigned int num);
187 extern void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
188 blk64_t block, unsigned int num);
189 extern void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
190 blk64_t block, unsigned int num);
193 * The inline routines themselves...
195 * If NO_INLINE_FUNCS is defined, then we won't try to do inline
196 * functions at all; they will be included as normal functions in
199 #ifdef NO_INLINE_FUNCS
200 #if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
201 defined(__i586__) || defined(__mc68000__)))
202 /* This prevents bitops.c from trying to include the C */
203 /* function version of these functions */
204 #define _EXT2_HAVE_ASM_BITOPS_
206 #endif /* NO_INLINE_FUNCS */
208 #if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
209 #ifdef INCLUDE_INLINE_FUNCS
210 #define _INLINE_ extern
213 #define _INLINE_ extern __inline__
214 #else /* For Watcom C */
215 #define _INLINE_ extern inline
220 * Fast bit set/clear functions that doesn't need to return the
221 * previous bit value.
224 _INLINE_ void ext2fs_fast_set_bit(unsigned int nr,void * addr)
226 unsigned char *ADDR = (unsigned char *) addr;
229 *ADDR |= (1 << (nr & 0x07));
232 _INLINE_ void ext2fs_fast_clear_bit(unsigned int nr, void * addr)
234 unsigned char *ADDR = (unsigned char *) addr;
237 *ADDR &= ~(1 << (nr & 0x07));
241 _INLINE_ void ext2fs_fast_set_bit64(__u64 nr, void * addr)
243 unsigned char *ADDR = (unsigned char *) addr;
246 *ADDR |= (1 << (nr & 0x07));
249 _INLINE_ void ext2fs_fast_clear_bit64(__u64 nr, void * addr)
251 unsigned char *ADDR = (unsigned char *) addr;
254 *ADDR &= ~(1 << (nr & 0x07));
258 #if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
259 (defined(__i386__) || defined(__i486__) || defined(__i586__)))
261 #define _EXT2_HAVE_ASM_BITOPS_
262 #define _EXT2_HAVE_ASM_SWAB_
265 * These are done by inline assembly for speed reasons.....
267 * All bitoperations return 0 if the bit was cleared before the
268 * operation and != 0 if it was not. Bit 0 is the LSB of addr; bit 32
269 * is the LSB of (addr+1).
273 * Some hacks to defeat gcc over-optimizations..
275 struct __dummy_h { unsigned long a[100]; };
276 #define EXT2FS_ADDR (*(struct __dummy_h *) addr)
277 #define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
279 _INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr)
283 addr = (void *) (((unsigned char *) addr) + (nr >> 3));
284 __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
285 :"=r" (oldbit),"+m" (EXT2FS_ADDR)
290 _INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
294 addr = (void *) (((unsigned char *) addr) + (nr >> 3));
295 __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
296 :"=r" (oldbit),"+m" (EXT2FS_ADDR)
301 _INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
305 addr = (const void *) (((const unsigned char *) addr) + (nr >> 3));
306 __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
308 :"m" (EXT2FS_CONST_ADDR),"r" (nr & 7));
312 _INLINE_ __u32 ext2fs_swab32(__u32 val)
314 #ifdef EXT2FS_REQUIRE_486
315 __asm__("bswap %0" : "=r" (val) : "0" (val));
317 __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
318 "rorl $16,%0\n\t" /* swap words */
319 "xchgb %b0,%h0" /* swap higher bytes */
326 _INLINE_ __u16 ext2fs_swab16(__u16 val)
328 __asm__("xchgb %b0,%h0" /* swap bytes */ \
338 #if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
339 (defined(__mc68000__)))
341 #define _EXT2_HAVE_ASM_BITOPS_
343 _INLINE_ int ext2fs_set_bit(unsigned int nr,void * addr)
347 __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
348 : "=d" (retval) : "d" (nr^7), "a" (addr));
353 _INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
357 __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
358 : "=d" (retval) : "d" (nr^7), "a" (addr));
363 _INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
367 __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
368 : "=d" (retval) : "d" (nr^7), "a" (addr));
373 #endif /* __mc68000__ */
376 #if !defined(_EXT2_HAVE_ASM_SWAB_)
378 _INLINE_ __u16 ext2fs_swab16(__u16 val)
380 return (val >> 8) | (val << 8);
383 _INLINE_ __u32 ext2fs_swab32(__u32 val)
385 return ((val>>24) | ((val>>8)&0xFF00) |
386 ((val<<8)&0xFF0000) | (val<<24));
389 #endif /* !_EXT2_HAVE_ASM_SWAB */
391 _INLINE_ __u64 ext2fs_swab64(__u64 val)
393 return (ext2fs_swab32(val >> 32) |
394 (((__u64)ext2fs_swab32(val & 0xFFFFFFFFUL)) << 32));
397 _INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
400 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
404 _INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
407 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
411 _INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
414 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
418 _INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
421 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
425 _INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
428 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
432 _INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
435 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
439 _INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
442 ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
445 _INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
448 ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
451 _INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
454 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
458 _INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
461 ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
464 _INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
467 ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
470 _INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
473 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
477 _INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
479 return ext2fs_get_generic_bitmap_start((ext2fs_generic_bitmap) bitmap);
482 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
484 return ext2fs_get_generic_bitmap_start((ext2fs_generic_bitmap) bitmap);
487 _INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
489 return ext2fs_get_generic_bitmap_end((ext2fs_generic_bitmap) bitmap);
492 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
494 return ext2fs_get_generic_bitmap_end((ext2fs_generic_bitmap) bitmap);
497 _INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
498 blk_t block, int num)
500 return ext2fs_test_block_bitmap_range(bitmap, block, num);
503 _INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
504 blk_t block, int num)
506 ext2fs_mark_block_bitmap_range(bitmap, block, num);
509 _INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
510 blk_t block, int num)
512 ext2fs_unmark_block_bitmap_range(bitmap, block, num);
515 /* 64-bit versions */
517 _INLINE_ int ext2fs_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
520 return ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap,
524 _INLINE_ int ext2fs_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
527 return ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap, block);
530 _INLINE_ int ext2fs_test_block_bitmap2(ext2fs_block_bitmap bitmap,
533 return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
537 _INLINE_ int ext2fs_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
540 return ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap,
544 _INLINE_ int ext2fs_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
547 return ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap,
551 _INLINE_ int ext2fs_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
554 return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
558 _INLINE_ void ext2fs_fast_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
561 ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap, block);
564 _INLINE_ void ext2fs_fast_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
567 ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap, block);
570 _INLINE_ int ext2fs_fast_test_block_bitmap2(ext2fs_block_bitmap bitmap,
573 return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
577 _INLINE_ void ext2fs_fast_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
580 ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap, inode);
583 _INLINE_ void ext2fs_fast_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
586 ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap, inode);
589 _INLINE_ int ext2fs_fast_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
592 return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
596 _INLINE_ blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap bitmap)
598 return ext2fs_get_generic_bmap_start((ext2fs_generic_bitmap) bitmap);
601 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start2(ext2fs_inode_bitmap bitmap)
603 return ext2fs_get_generic_bmap_start((ext2fs_generic_bitmap) bitmap);
606 _INLINE_ blk64_t ext2fs_get_block_bitmap_end2(ext2fs_block_bitmap bitmap)
608 return ext2fs_get_generic_bmap_end((ext2fs_generic_bitmap) bitmap);
611 _INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end2(ext2fs_inode_bitmap bitmap)
613 return ext2fs_get_generic_bmap_end((ext2fs_generic_bitmap) bitmap);
616 _INLINE_ int ext2fs_fast_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
620 return ext2fs_test_block_bitmap_range2(bitmap, block, num);
623 _INLINE_ void ext2fs_fast_mark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
627 ext2fs_mark_block_bitmap_range2(bitmap, block, num);
630 _INLINE_ void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
634 ext2fs_unmark_block_bitmap_range2(bitmap, block, num);