bitops.h revision 9b9a780f5a5823865f62f0c9fd194d262f63a06f
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * bitops.h --- Bitmap frobbing code.  The byte swapping routines are
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 	also included here.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch * %Begin-Header%
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This file may be redistributed under the terms of the GNU Public
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License.
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * %End-Header%
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Linus Torvalds.
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_set_bit(unsigned int nr,void * addr);
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_clear_bit(unsigned int nr, void * addr);
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_test_bit(unsigned int nr, const void * addr);
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern __u16 ext2fs_swab16(__u16 val);
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern __u32 ext2fs_swab32(__u32 val);
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef WORDS_BIGENDIAN
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_cpu_to_le32(x) ext2fs_swab32((x))
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_le32_to_cpu(x) ext2fs_swab32((x))
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#define ext2fs_cpu_to_le16(x) ext2fs_swab16((x))
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_le16_to_cpu(x) ext2fs_swab16((x))
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_cpu_to_be32(x) ((__u32)(x))
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_be32_to_cpu(x) ((__u32)(x))
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_cpu_to_be16(x) ((__u16)(x))
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_be16_to_cpu(x) ((__u16)(x))
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_cpu_to_le32(x) ((__u32)(x))
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_le32_to_cpu(x) ((__u32)(x))
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_cpu_to_le16(x) ((__u16)(x))
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_le16_to_cpu(x) ((__u16)(x))
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_cpu_to_be32(x) ext2fs_swab32((x))
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_be32_to_cpu(x) ext2fs_swab32((x))
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_cpu_to_be16(x) ext2fs_swab16((x))
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ext2fs_be16_to_cpu(x) ext2fs_swab16((x))
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * EXT2FS bitmap manipulation routines.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* Support for sending warning messages from the inline subroutines */
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern const char *ext2fs_block_string;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern const char *ext2fs_inode_string;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern const char *ext2fs_mark_string;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern const char *ext2fs_unmark_string;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern const char *ext2fs_test_string;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			       const char *description);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				int code, unsigned long arg);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				       blk_t block);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				       ext2_ino_t inode);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)					  blk_t block);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)					    blk_t block);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)					 blk_t block);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)					  ext2_ino_t inode);
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochextern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch					    ext2_ino_t inode);
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochextern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch					 ext2_ino_t inode);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)					   blk_t block, int num);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)					     blk_t block, int num);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)					  blk_t block, int num);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)						blk_t block, int num);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)						  blk_t block, int num);
96extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
97					       blk_t block, int num);
98extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
99
100/* These two routines moved to gen_bitmap.c */
101extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
102					 __u32 bitno);
103extern 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	/* This prevents bitops.c from trying to include the C */
116	/* function version of these functions */
117#define _EXT2_HAVE_ASM_BITOPS_
118#endif
119#endif /* NO_INLINE_FUNCS */
120
121#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
122#ifdef INCLUDE_INLINE_FUNCS
123#define _INLINE_ extern
124#else
125#ifdef __GNUC__
126#define _INLINE_ extern __inline__
127#else				/* For Watcom C */
128#define _INLINE_ extern inline
129#endif
130#endif
131
132#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
133     (defined(__i386__) || defined(__i486__) || defined(__i586__)))
134
135#define _EXT2_HAVE_ASM_BITOPS_
136#define _EXT2_HAVE_ASM_SWAB_
137#define _EXT2_HAVE_ASM_FINDBIT_
138
139/*
140 * These are done by inline assembly for speed reasons.....
141 *
142 * All bitoperations return 0 if the bit was cleared before the
143 * operation and != 0 if it was not.  Bit 0 is the LSB of addr; bit 32
144 * is the LSB of (addr+1).
145 */
146
147/*
148 * Some hacks to defeat gcc over-optimizations..
149 */
150struct __dummy_h { unsigned long a[100]; };
151#define EXT2FS_ADDR (*(struct __dummy_h *) addr)
152#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
153
154_INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr)
155{
156	int oldbit;
157
158	__asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
159		:"=r" (oldbit),"=m" (EXT2FS_ADDR)
160		:"r" (nr));
161	return oldbit;
162}
163
164_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
165{
166	int oldbit;
167
168	__asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
169		:"=r" (oldbit),"=m" (EXT2FS_ADDR)
170		:"r" (nr));
171	return oldbit;
172}
173
174_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
175{
176	int oldbit;
177
178	__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
179		:"=r" (oldbit)
180		:"m" (EXT2FS_CONST_ADDR),"r" (nr));
181	return oldbit;
182}
183
184#if 0
185_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
186{
187	int d0, d1, d2;
188	int res;
189
190	if (!size)
191		return 0;
192	/* This looks at memory. Mark it volatile to tell gcc not to move it around */
193	__asm__ __volatile__(
194		"cld\n\t"
195		"xorl %%eax,%%eax\n\t"
196		"xorl %%edx,%%edx\n\t"
197		"repe; scasl\n\t"
198		"je 1f\n\t"
199		"movl -4(%%edi),%%eax\n\t"
200		"subl $4,%%edi\n\t"
201		"bsfl %%eax,%%edx\n"
202		"1:\tsubl %%esi,%%edi\n\t"
203		"shll $3,%%edi\n\t"
204		"addl %%edi,%%edx"
205		:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
206		:"1" ((size + 31) >> 5), "2" (addr), "S" (addr));
207	return res;
208}
209
210_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
211{
212	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
213	int set = 0, bit = offset & 31, res;
214
215	if (bit) {
216		/*
217		 * Look for zero in first byte
218		 */
219		__asm__("bsfl %1,%0\n\t"
220			"jne 1f\n\t"
221			"movl $32, %0\n"
222			"1:"
223			: "=r" (set)
224			: "r" (*p >> bit));
225		if (set < (32 - bit))
226			return set + offset;
227		set = 32 - bit;
228		p++;
229	}
230	/*
231	 * No bit found yet, search remaining full bytes for a bit
232	 */
233	res = ext2fs_find_first_bit_set(p, size - 32 * (p - (unsigned long *) addr));
234	return (offset + set + res);
235}
236#endif
237
238#ifdef EXT2FS_ENABLE_SWAPFS
239_INLINE_ __u32 ext2fs_swab32(__u32 val)
240{
241#ifdef EXT2FS_REQUIRE_486
242	__asm__("bswap %0" : "=r" (val) : "0" (val));
243#else
244	__asm__("xchgb %b0,%h0\n\t"	/* swap lower bytes	*/
245		"rorl $16,%0\n\t"	/* swap words		*/
246		"xchgb %b0,%h0"		/* swap higher bytes	*/
247		:"=q" (val)
248		: "0" (val));
249#endif
250	return val;
251}
252
253_INLINE_ __u16 ext2fs_swab16(__u16 val)
254{
255	__asm__("xchgb %b0,%h0"		/* swap bytes		*/ \
256		: "=q" (val) \
257		:  "0" (val)); \
258		return val;
259}
260#endif
261
262#undef EXT2FS_ADDR
263
264#endif	/* i386 */
265
266#ifdef __mc68000__
267
268#define _EXT2_HAVE_ASM_BITOPS_
269
270_INLINE_ int ext2fs_set_bit(unsigned int nr,void * addr)
271{
272	char retval;
273
274	__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
275	     : "=d" (retval) : "d" (nr^7), "a" (addr));
276
277	return retval;
278}
279
280_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
281{
282	char retval;
283
284	__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
285	     : "=d" (retval) : "d" (nr^7), "a" (addr));
286
287	return retval;
288}
289
290_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
291{
292	char retval;
293
294	__asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
295	     : "=d" (retval) : "d" (nr^7), "a" (addr));
296
297	return retval;
298}
299
300#endif /* __mc68000__ */
301
302
303#if !defined(_EXT2_HAVE_ASM_SWAB_) && defined(EXT2FS_ENABLE_SWAPFS)
304
305_INLINE_ __u16 ext2fs_swab16(__u16 val)
306{
307	return (val >> 8) | (val << 8);
308}
309
310_INLINE_ __u32 ext2fs_swab32(__u32 val)
311{
312	return ((val>>24) | ((val>>8)&0xFF00) |
313		((val<<8)&0xFF0000) | (val<<24));
314}
315
316#endif /* !_EXT2_HAVE_ASM_SWAB */
317
318#if !defined(_EXT2_HAVE_ASM_FINDBIT_)
319_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
320{
321	char	*cp = (char *) addr;
322	int 	res = 0, d0;
323
324	if (!size)
325		return 0;
326
327	while ((size > res) && (*cp == 0)) {
328		cp++;
329		res += 8;
330	}
331	d0 = ffs(*cp);
332	if (d0 == 0)
333		return size;
334
335	return res + d0 - 1;
336}
337
338_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
339{
340	unsigned char * p;
341	int set = 0, bit = offset & 7, res = 0, d0;
342
343	res = offset >> 3;
344	p = ((unsigned char *) addr) + res;
345
346	if (bit) {
347		set = ffs(*p & ~((1 << bit) - 1));
348		if (set)
349			return (offset & ~7) + set - 1;
350		p++;
351		res += 8;
352	}
353	while ((size > res) && (*p == 0)) {
354		p++;
355		res += 8;
356	}
357	d0 = ffs(*p);
358	if (d0 == 0)
359		return size;
360
361	return (res + d0 - 1);
362}
363#endif
364
365_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
366					blk_t bitno);
367
368_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
369					blk_t bitno)
370{
371	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
372		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
373		return 0;
374	}
375	return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
376}
377
378_INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
379				       blk_t block)
380{
381	return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
382				       bitmap,
383					  block);
384}
385
386_INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
387					 blk_t block)
388{
389	return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
390					    block);
391}
392
393_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
394				       blk_t block)
395{
396	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
397					  block);
398}
399
400_INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
401				       ext2_ino_t inode)
402{
403	return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
404					  inode);
405}
406
407_INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
408					 ext2_ino_t inode)
409{
410	return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
411				     inode);
412}
413
414_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
415				       ext2_ino_t inode)
416{
417	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
418					  inode);
419}
420
421_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
422					    blk_t block)
423{
424#ifdef EXT2FS_DEBUG_FAST_OPS
425	if ((block < bitmap->start) || (block > bitmap->end)) {
426		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
427				   bitmap->description);
428		return;
429	}
430#endif
431	ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
432}
433
434_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
435					      blk_t block)
436{
437#ifdef EXT2FS_DEBUG_FAST_OPS
438	if ((block < bitmap->start) || (block > bitmap->end)) {
439		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
440				   block, bitmap->description);
441		return;
442	}
443#endif
444	ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
445}
446
447_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
448					    blk_t block)
449{
450#ifdef EXT2FS_DEBUG_FAST_OPS
451	if ((block < bitmap->start) || (block > bitmap->end)) {
452		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
453				   block, bitmap->description);
454		return 0;
455	}
456#endif
457	return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
458}
459
460_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
461					    ext2_ino_t inode)
462{
463#ifdef EXT2FS_DEBUG_FAST_OPS
464	if ((inode < bitmap->start) || (inode > bitmap->end)) {
465		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
466				   inode, bitmap->description);
467		return;
468	}
469#endif
470	ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
471}
472
473_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
474					      ext2_ino_t inode)
475{
476#ifdef EXT2FS_DEBUG_FAST_OPS
477	if ((inode < bitmap->start) || (inode > bitmap->end)) {
478		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
479				   inode, bitmap->description);
480		return;
481	}
482#endif
483	ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
484}
485
486_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
487					   ext2_ino_t inode)
488{
489#ifdef EXT2FS_DEBUG_FAST_OPS
490	if ((inode < bitmap->start) || (inode > bitmap->end)) {
491		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
492				   inode, bitmap->description);
493		return 0;
494	}
495#endif
496	return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
497}
498
499_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
500{
501	return bitmap->start;
502}
503
504_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
505{
506	return bitmap->start;
507}
508
509_INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
510{
511	return bitmap->end;
512}
513
514_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
515{
516	return bitmap->end;
517}
518
519_INLINE_ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
520					    blk_t block, int num)
521{
522	int	i;
523
524	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
525		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
526				   block, bitmap->description);
527		return 0;
528	}
529	for (i=0; i < num; i++) {
530		if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
531			return 0;
532	}
533	return 1;
534}
535
536_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
537						 blk_t block, int num)
538{
539	int	i;
540
541#ifdef EXT2FS_DEBUG_FAST_OPS
542	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
543		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
544				   block, bitmap->description);
545		return 0;
546	}
547#endif
548	for (i=0; i < num; i++) {
549		if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
550			return 0;
551	}
552	return 1;
553}
554
555_INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
556					     blk_t block, int num)
557{
558	int	i;
559
560	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
561		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
562				   bitmap->description);
563		return;
564	}
565	for (i=0; i < num; i++)
566		ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
567}
568
569_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
570						  blk_t block, int num)
571{
572	int	i;
573
574#ifdef EXT2FS_DEBUG_FAST_OPS
575	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
576		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
577				   bitmap->description);
578		return;
579	}
580#endif
581	for (i=0; i < num; i++)
582		ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
583}
584
585_INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
586					       blk_t block, int num)
587{
588	int	i;
589
590	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
591		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
592				   bitmap->description);
593		return;
594	}
595	for (i=0; i < num; i++)
596		ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
597}
598
599_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
600						    blk_t block, int num)
601{
602	int	i;
603
604#ifdef EXT2FS_DEBUG_FAST_OPS
605	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
606		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
607				   bitmap->description);
608		return;
609	}
610#endif
611	for (i=0; i < num; i++)
612		ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
613}
614#undef _INLINE_
615#endif
616
617