2 * bitops.h --- Bitmap frobbing code. The byte swapping routines are
5 * Copyright (C) 1993, 1994, 1995 Theodore Ts'o. This file may be
6 * redistributed under the terms of the GNU Public License.
8 * Taken from <asm/bitops.h>, Copyright 1992, Linus Torvalds.
12 extern int ext2fs_set_bit(int nr,void * addr);
13 extern int ext2fs_clear_bit(int nr, void * addr);
14 extern int ext2fs_test_bit(int nr, const void * addr);
15 extern __u16 ext2fs_swab16(__u16 val);
16 extern __u32 ext2fs_swab32(__u32 val);
19 * EXT2FS bitmap manipulation routines.
22 /* Support for sending warning messages from the inline subroutines */
23 extern const char *ext2fs_block_string;
24 extern const char *ext2fs_inode_string;
25 extern const char *ext2fs_mark_string;
26 extern const char *ext2fs_unmark_string;
27 extern const char *ext2fs_test_string;
28 extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
29 const char *description);
31 extern void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
32 extern void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
34 extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
36 extern void ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ino_t inode);
37 extern void ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
39 extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ino_t inode);
41 extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
43 extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
45 extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
48 extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
50 extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
52 extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
54 extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
55 extern blk_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
56 extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
57 extern blk_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
60 * The inline routines themselves...
62 * If NO_INLINE_FUNCS is defined, then we won't try to do inline
63 * functions at all; they will be included as normal functions in
66 #ifdef NO_INLINE_FUNCS
67 #if (defined(__i386__) || defined(__i486__) || defined(__i586__) || \
68 defined(__mc68000__) || defined(__sparc__))
69 /* This prevents bitops.c from trying to include the C */
70 /* function version of these functions */
71 #define _EXT2_HAVE_ASM_BITOPS_
73 #endif /* NO_INLINE_FUNCS */
75 #if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
76 #ifdef INCLUDE_INLINE_FUNCS
77 #define _INLINE_ extern
79 #define _INLINE_ extern __inline__
82 #if (defined(__i386__) || defined(__i486__) || defined(__i586__))
84 #define _EXT2_HAVE_ASM_BITOPS_
87 * These are done by inline assembly for speed reasons.....
89 * All bitoperations return 0 if the bit was cleared before the
90 * operation and != 0 if it was not. Bit 0 is the LSB of addr; bit 32
91 * is the LSB of (addr+1).
95 * Some hacks to defeat gcc over-optimizations..
97 struct __dummy_h { unsigned long a[100]; };
98 #define EXT2FS_ADDR (*(struct __dummy_h *) addr)
99 #define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
101 _INLINE_ int ext2fs_set_bit(int nr, void * addr)
105 __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
106 :"=r" (oldbit),"=m" (EXT2FS_ADDR)
111 _INLINE_ int ext2fs_clear_bit(int nr, void * addr)
115 __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
116 :"=r" (oldbit),"=m" (EXT2FS_ADDR)
121 _INLINE_ int ext2fs_test_bit(int nr, const void * addr)
125 __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
127 :"m" (EXT2FS_CONST_ADDR),"r" (nr));
137 #define _EXT2_HAVE_ASM_BITOPS_
139 _INLINE_ int ext2fs_set_bit(int nr,void * addr)
143 __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
144 : "=d" (retval) : "d" (nr^7), "a" (addr));
149 _INLINE_ int ext2fs_clear_bit(int nr, void * addr)
153 __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
154 : "=d" (retval) : "d" (nr^7), "a" (addr));
159 _INLINE_ int ext2fs_test_bit(int nr, const void * addr)
163 __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
164 : "=d" (retval) : "d" (nr^7), "a" (addr));
169 #endif /* __mc68000__ */
173 #define _EXT2_HAVE_ASM_BITOPS_
175 _INLINE_ int ext2fs_set_bit(int nr, void *addr)
178 unsigned long *ADDR = (unsigned long *) addr;
181 mask = 1 << (nr & 31);
182 retval = ((mask & *ADDR) != 0);
187 _INLINE_ int ext2fs_clear_bit(int nr, void *addr)
190 unsigned long *ADDR = (unsigned long *) addr;
193 mask = 1 << (nr & 31);
194 retval = ((mask & *ADDR) != 0);
199 _INLINE_ int ext2fs_test_bit(int nr, const void *addr)
202 const unsigned long *ADDR = (const unsigned long *) addr;
205 mask = 1 << (nr & 31);
206 return ((mask & *ADDR) != 0);
209 #endif /* __sparc__ */
211 #ifndef _EXT2_HAVE_ASM_SWAB
213 _INLINE_ __u16 ext2fs_swab16(__u16 val)
215 return (val >> 8) | (val << 8);
218 _INLINE_ __u32 ext2fs_swab32(__u32 val)
220 return ((val>>24) | ((val>>8)&0xFF00) |
221 ((val<<8)&0xFF0000) | (val<<24));
224 #endif /* !_EXT2_HAVE_ASM_SWAB */
226 _INLINE_ void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
229 if ((block < bitmap->start) || (block > bitmap->end)) {
230 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
231 bitmap->description);
234 ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
237 _INLINE_ void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
240 if ((block < bitmap->start) || (block > bitmap->end)) {
241 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
242 block, bitmap->description);
245 ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
248 _INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
251 if ((block < bitmap->start) || (block > bitmap->end)) {
252 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
253 block, bitmap->description);
256 return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
259 _INLINE_ void ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
262 if ((inode < bitmap->start) || (inode > bitmap->end)) {
263 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
264 inode, bitmap->description);
267 ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
270 _INLINE_ void ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
273 if ((inode < bitmap->start) || (inode > bitmap->end)) {
274 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
275 inode, bitmap->description);
278 ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
281 _INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
284 if ((inode < bitmap->start) || (inode > bitmap->end)) {
285 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
286 inode, bitmap->description);
289 return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
292 _INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
295 #ifdef EXT2FS_DEBUG_FAST_OPS
296 if ((block < bitmap->start) || (block > bitmap->end)) {
297 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
298 bitmap->description);
302 ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
305 _INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
308 #ifdef EXT2FS_DEBUG_FAST_OPS
309 if ((block < bitmap->start) || (block > bitmap->end)) {
310 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
311 block, bitmap->description);
315 ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
318 _INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
321 #ifdef EXT2FS_DEBUG_FAST_OPS
322 if ((block < bitmap->start) || (block > bitmap->end)) {
323 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
324 block, bitmap->description);
328 return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
331 _INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
334 #ifdef EXT2FS_DEBUG_FAST_OPS
335 if ((inode < bitmap->start) || (inode > bitmap->end)) {
336 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
337 inode, bitmap->description);
341 ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
344 _INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
347 #ifdef EXT2FS_DEBUG_FAST_OPS
348 if ((inode < bitmap->start) || (inode > bitmap->end)) {
349 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
350 inode, bitmap->description);
354 ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
357 _INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
360 #ifdef EXT2FS_DEBUG_FAST_OPS
361 if ((inode < bitmap->start) || (inode > bitmap->end)) {
362 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
363 inode, bitmap->description);
367 return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
370 _INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
372 return bitmap->start;
375 _INLINE_ blk_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
377 return bitmap->start;
380 _INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
385 _INLINE_ blk_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)