• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * gen_bitmap.c --- Generic (32-bit) bitmap routines
3  *
4  * Copyright (C) 2001 Theodore Ts'o.
5  *
6  * %Begin-Header%
7  * This file may be redistributed under the terms of the GNU Library
8  * General Public License, version 2.
9  * %End-Header%
10  */
11 
12 
13 #include "config.h"
14 #include <stdio.h>
15 #include <string.h>
16 #if HAVE_UNISTD_H
17 #include <unistd.h>
18 #endif
19 #include <fcntl.h>
20 #include <time.h>
21 #if HAVE_SYS_STAT_H
22 #include <sys/stat.h>
23 #endif
24 #if HAVE_SYS_TYPES_H
25 #include <sys/types.h>
26 #endif
27 
28 #include "ext2_fs.h"
29 #include "ext2fsP.h"
30 
31 struct ext2fs_struct_generic_bitmap {
32 	errcode_t	magic;
33 	ext2_filsys 	fs;
34 	__u32		start, end;
35 	__u32		real_end;
36 	char	*	description;
37 	char	*	bitmap;
38 	errcode_t	base_error_code;
39 	__u32		reserved[7];
40 };
41 
42 #define EXT2FS_IS_32_BITMAP(bmap) \
43 	(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
44 	 ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
45 	 ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP))
46 
47 #define EXT2FS_IS_64_BITMAP(bmap) \
48 	(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP64) || \
49 	 ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP64) || \
50 	 ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP64))
51 
52 /*
53  * Used by previously inlined function, so we have to export this and
54  * not change the function signature
55  */
ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,int code,unsigned long arg)56 void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
57 			    int code, unsigned long arg)
58 {
59 #ifndef OMIT_COM_ERR
60 	if (bitmap->description)
61 		com_err(0, bitmap->base_error_code+code,
62 			"#%lu for %s", arg, bitmap->description);
63 	else
64 		com_err(0, bitmap->base_error_code + code, "#%lu", arg);
65 #endif
66 }
67 
check_magic(ext2fs_generic_bitmap bitmap)68 static errcode_t check_magic(ext2fs_generic_bitmap bitmap)
69 {
70 	if (!bitmap || !((bitmap->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) ||
71 			 (bitmap->magic == EXT2_ET_MAGIC_INODE_BITMAP) ||
72 			 (bitmap->magic == EXT2_ET_MAGIC_BLOCK_BITMAP)))
73 		return EXT2_ET_MAGIC_GENERIC_BITMAP;
74 	return 0;
75 }
76 
ext2fs_make_generic_bitmap(errcode_t magic,ext2_filsys fs,__u32 start,__u32 end,__u32 real_end,const char * descr,char * init_map,ext2fs_generic_bitmap * ret)77 errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
78 				     __u32 start, __u32 end, __u32 real_end,
79 				     const char *descr, char *init_map,
80 				     ext2fs_generic_bitmap *ret)
81 {
82 	ext2fs_generic_bitmap	bitmap;
83 	errcode_t		retval;
84 	size_t			size;
85 
86 	retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap),
87 				&bitmap);
88 	if (retval)
89 		return retval;
90 
91 	bitmap->magic = magic;
92 	bitmap->fs = fs;
93 	bitmap->start = start;
94 	bitmap->end = end;
95 	bitmap->real_end = real_end;
96 	switch (magic) {
97 	case EXT2_ET_MAGIC_INODE_BITMAP:
98 		bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
99 		break;
100 	case EXT2_ET_MAGIC_BLOCK_BITMAP:
101 		bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
102 		break;
103 	default:
104 		bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
105 	}
106 	if (descr) {
107 		retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description);
108 		if (retval) {
109 			ext2fs_free_mem(&bitmap);
110 			return retval;
111 		}
112 		strcpy(bitmap->description, descr);
113 	} else
114 		bitmap->description = 0;
115 
116 	size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
117 	/* Round up to allow for the BT x86 instruction */
118 	size = (size + 7) & ~3;
119 	retval = ext2fs_get_mem(size, &bitmap->bitmap);
120 	if (retval) {
121 		ext2fs_free_mem(&bitmap->description);
122 		ext2fs_free_mem(&bitmap);
123 		return retval;
124 	}
125 
126 	if (init_map)
127 		memcpy(bitmap->bitmap, init_map, size);
128 	else
129 		memset(bitmap->bitmap, 0, size);
130 	*ret = bitmap;
131 	return 0;
132 }
133 
ext2fs_allocate_generic_bitmap(__u32 start,__u32 end,__u32 real_end,const char * descr,ext2fs_generic_bitmap * ret)134 errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
135 					 __u32 end,
136 					 __u32 real_end,
137 					 const char *descr,
138 					 ext2fs_generic_bitmap *ret)
139 {
140 	return ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_GENERIC_BITMAP, 0,
141 					  start, end, real_end, descr, 0, ret);
142 }
143 
ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,ext2fs_generic_bitmap * dest)144 errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,
145 				     ext2fs_generic_bitmap *dest)
146 {
147 	return (ext2fs_make_generic_bitmap(src->magic, src->fs,
148 					   src->start, src->end,
149 					   src->real_end,
150 					   src->description, src->bitmap,
151 					   dest));
152 }
153 
ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)154 void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
155 {
156 	if (check_magic(bitmap))
157 		return;
158 
159 	bitmap->magic = 0;
160 	if (bitmap->description) {
161 		ext2fs_free_mem(&bitmap->description);
162 		bitmap->description = 0;
163 	}
164 	if (bitmap->bitmap) {
165 		ext2fs_free_mem(&bitmap->bitmap);
166 		bitmap->bitmap = 0;
167 	}
168 	ext2fs_free_mem(&bitmap);
169 }
170 
ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,blk_t bitno)171 int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
172 					blk_t bitno)
173 {
174 	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
175 		if (EXT2FS_IS_64_BITMAP(bitmap)) {
176 			ext2fs_warn_bitmap32(bitmap, __func__);
177 			return ext2fs_test_generic_bmap(bitmap, bitno);
178 		}
179 #ifndef OMIT_COM_ERR
180 		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
181 			"test_bitmap(%lu)", (unsigned long) bitno);
182 #endif
183 		return 0;
184 	}
185 
186 	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
187 		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
188 		return 0;
189 	}
190 	return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
191 }
192 
ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,__u32 bitno)193 int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
194 					 __u32 bitno)
195 {
196 	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
197 		if (EXT2FS_IS_64_BITMAP(bitmap)) {
198 			ext2fs_warn_bitmap32(bitmap, __func__);
199 			return ext2fs_mark_generic_bmap(bitmap, bitno);
200 		}
201 #ifndef OMIT_COM_ERR
202 		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
203 			"mark_bitmap(%lu)", (unsigned long) bitno);
204 #endif
205 		return 0;
206 	}
207 
208 	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
209 		ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
210 		return 0;
211 	}
212 	return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
213 }
214 
ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,blk_t bitno)215 int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
216 					   blk_t bitno)
217 {
218 	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
219 		if (EXT2FS_IS_64_BITMAP(bitmap)) {
220 			ext2fs_warn_bitmap32(bitmap, __func__);
221 			return ext2fs_unmark_generic_bmap(bitmap, bitno);
222 		}
223 #ifndef OMIT_COM_ERR
224 		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
225 			"mark_bitmap(%lu)", (unsigned long) bitno);
226 #endif
227 		return 0;
228 	}
229 
230 	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
231 		ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
232 		return 0;
233 	}
234 	return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
235 }
236 
ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)237 __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)
238 {
239 	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
240 		if (EXT2FS_IS_64_BITMAP(bitmap)) {
241 			ext2fs_warn_bitmap32(bitmap, __func__);
242 			return ext2fs_get_generic_bmap_start(bitmap);
243 		}
244 #ifndef OMIT_COM_ERR
245 		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
246 			"get_bitmap_start");
247 #endif
248 		return 0;
249 	}
250 
251 	return bitmap->start;
252 }
253 
ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)254 __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)
255 {
256 	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
257 		if (EXT2FS_IS_64_BITMAP(bitmap)) {
258 			ext2fs_warn_bitmap32(bitmap, __func__);
259 			return ext2fs_get_generic_bmap_end(bitmap);
260 		}
261 #ifndef OMIT_COM_ERR
262 		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
263 			"get_bitmap_end");
264 #endif
265 		return 0;
266 	}
267 	return bitmap->end;
268 }
269 
ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)270 void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)
271 {
272 	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
273 		if (EXT2FS_IS_64_BITMAP(bitmap)) {
274 			ext2fs_warn_bitmap32(bitmap, __func__);
275 			ext2fs_clear_generic_bmap(bitmap);
276 			return;
277 		}
278 #ifndef OMIT_COM_ERR
279 		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
280 			"clear_generic_bitmap");
281 #endif
282 		return;
283 	}
284 
285 	memset(bitmap->bitmap, 0,
286 	       (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
287 }
288 
ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,errcode_t magic,errcode_t neq,ext2_ino_t end,ext2_ino_t * oend)289 errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
290 					  errcode_t magic, errcode_t neq,
291 					  ext2_ino_t end, ext2_ino_t *oend)
292 {
293 	EXT2_CHECK_MAGIC(bitmap, magic);
294 
295 	if (end > bitmap->real_end)
296 		return neq;
297 	if (oend)
298 		*oend = bitmap->end;
299 	bitmap->end = end;
300 	return 0;
301 }
302 
ext2fs_resize_generic_bitmap(errcode_t magic,__u32 new_end,__u32 new_real_end,ext2fs_generic_bitmap bmap)303 errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
304 				       __u32 new_end, __u32 new_real_end,
305 				       ext2fs_generic_bitmap bmap)
306 {
307 	errcode_t	retval;
308 	size_t		size, new_size;
309 	__u32		bitno;
310 
311 	if (!bmap || (bmap->magic != magic))
312 		return magic;
313 
314 	/*
315 	 * If we're expanding the bitmap, make sure all of the new
316 	 * parts of the bitmap are zero.
317 	 */
318 	if (new_end > bmap->end) {
319 		bitno = bmap->real_end;
320 		if (bitno > new_end)
321 			bitno = new_end;
322 		for (; bitno > bmap->end; bitno--)
323 			ext2fs_clear_bit(bitno - bmap->start, bmap->bitmap);
324 	}
325 	if (new_real_end == bmap->real_end) {
326 		bmap->end = new_end;
327 		return 0;
328 	}
329 
330 	size = ((bmap->real_end - bmap->start) / 8) + 1;
331 	new_size = ((new_real_end - bmap->start) / 8) + 1;
332 
333 	if (size != new_size) {
334 		retval = ext2fs_resize_mem(size, new_size, &bmap->bitmap);
335 		if (retval)
336 			return retval;
337 	}
338 	if (new_size > size)
339 		memset(bmap->bitmap + size, 0, new_size - size);
340 
341 	bmap->end = new_end;
342 	bmap->real_end = new_real_end;
343 	return 0;
344 }
345 
ext2fs_compare_generic_bitmap(errcode_t magic,errcode_t neq,ext2fs_generic_bitmap bm1,ext2fs_generic_bitmap bm2)346 errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
347 					ext2fs_generic_bitmap bm1,
348 					ext2fs_generic_bitmap bm2)
349 {
350 	blk_t	i;
351 
352 	if (!bm1 || bm1->magic != magic)
353 		return magic;
354 	if (!bm2 || bm2->magic != magic)
355 		return magic;
356 
357 	if ((bm1->start != bm2->start) ||
358 	    (bm1->end != bm2->end) ||
359 	    (memcmp(bm1->bitmap, bm2->bitmap,
360 		    (size_t) (bm1->end - bm1->start)/8)))
361 		return neq;
362 
363 	for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
364 		if (ext2fs_fast_test_block_bitmap(bm1, i) !=
365 		    ext2fs_fast_test_block_bitmap(bm2, i))
366 			return neq;
367 
368 	return 0;
369 }
370 
ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map)371 void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map)
372 {
373 	__u32	i, j;
374 
375 	/* Protect loop from wrap-around if map->real_end is maxed */
376 	for (i=map->end+1, j = i - map->start;
377 	     i <= map->real_end && i > map->end;
378 	     i++, j++)
379 		ext2fs_set_bit(j, map->bitmap);
380 }
381 
ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,errcode_t magic,__u32 start,__u32 num,void * out)382 errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
383 					  errcode_t magic,
384 					  __u32 start, __u32 num,
385 					  void *out)
386 {
387 	if (!bmap || (bmap->magic != magic))
388 		return magic;
389 
390 	if ((start < bmap->start) || (start+num-1 > bmap->real_end))
391 		return EXT2_ET_INVALID_ARGUMENT;
392 
393 	memcpy(out, bmap->bitmap + (start >> 3), (num+7) >> 3);
394 	return 0;
395 }
396 
ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap,errcode_t magic,__u32 start,__u32 num,void * in)397 errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap,
398 					  errcode_t magic,
399 					  __u32 start, __u32 num,
400 					  void *in)
401 {
402 	if (!bmap || (bmap->magic != magic))
403 		return magic;
404 
405 	if ((start < bmap->start) || (start+num-1 > bmap->real_end))
406 		return EXT2_ET_INVALID_ARGUMENT;
407 
408 	memcpy(bmap->bitmap + (start >> 3), in, (num+7) >> 3);
409 	return 0;
410 }
411 
412 /*
413  * Compare @mem to zero buffer by 256 bytes.
414  * Return 1 if @mem is zeroed memory, otherwise return 0.
415  */
ext2fs_mem_is_zero(const char * mem,size_t len)416 int ext2fs_mem_is_zero(const char *mem, size_t len)
417 {
418 	static const char zero_buf[256];
419 
420 	while (len >= sizeof(zero_buf)) {
421 		if (memcmp(mem, zero_buf, sizeof(zero_buf)))
422 			return 0;
423 		len -= sizeof(zero_buf);
424 		mem += sizeof(zero_buf);
425 	}
426 	/* Deal with leftover bytes. */
427 	if (len)
428 		return !memcmp(mem, zero_buf, len);
429 	return 1;
430 }
431 
432 /*
433  * Return true if all of the bits in a specified range are clear
434  */
ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap bitmap,unsigned int start,unsigned int len)435 static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap bitmap,
436 						  unsigned int start,
437 						  unsigned int len)
438 {
439 	size_t start_byte, len_byte = len >> 3;
440 	unsigned int start_bit, len_bit = len % 8;
441 	int first_bit = 0;
442 	int last_bit  = 0;
443 	int mark_count = 0;
444 	int mark_bit = 0;
445 	int i;
446 	const char *ADDR = bitmap->bitmap;
447 
448 	start -= bitmap->start;
449 	start_byte = start >> 3;
450 	start_bit = start % 8;
451 
452 	if (start_bit != 0) {
453 		/*
454 		 * The compared start block number or start inode number
455 		 * is not the first bit in a byte.
456 		 */
457 		mark_count = 8 - start_bit;
458 		if (len < 8 - start_bit) {
459 			mark_count = (int)len;
460 			mark_bit = len + start_bit - 1;
461 		} else
462 			mark_bit = 7;
463 
464 		for (i = mark_count; i > 0; i--, mark_bit--)
465 			first_bit |= 1 << mark_bit;
466 
467 		/*
468 		 * Compare blocks or inodes in the first byte.
469 		 * If there is any marked bit, this function returns 0.
470 		 */
471 		if (first_bit & ADDR[start_byte])
472 			return 0;
473 		else if (len <= 8 - start_bit)
474 			return 1;
475 
476 		start_byte++;
477 		len_bit = (len - mark_count) % 8;
478 		len_byte = (len - mark_count) >> 3;
479 	}
480 
481 	/*
482 	 * The compared start block number or start inode number is
483 	 * the first bit in a byte.
484 	 */
485 	if (len_bit != 0) {
486 		/*
487 		 * The compared end block number or end inode number is
488 		 * not the last bit in a byte.
489 		 */
490 		for (mark_bit = len_bit - 1; mark_bit >= 0; mark_bit--)
491 			last_bit |= 1 << mark_bit;
492 
493 		/*
494 		 * Compare blocks or inodes in the last byte.
495 		 * If there is any marked bit, this function returns 0.
496 		 */
497 		if (last_bit & ADDR[start_byte + len_byte])
498 			return 0;
499 		else if (len_byte == 0)
500 			return 1;
501 	}
502 
503 	/* Check whether all bytes are 0 */
504 	return ext2fs_mem_is_zero(ADDR + start_byte, len_byte);
505 }
506 
ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,__u32 start,__u32 end,__u32 * out)507 errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,
508 						__u32 start, __u32 end,
509 						__u32 *out)
510 {
511 	blk_t b;
512 
513 	if (start < bitmap->start || end > bitmap->end || start > end) {
514 		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
515 		return EINVAL;
516 	}
517 
518 	while (start <= end) {
519 		b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap);
520 		if (!b) {
521 			*out = start;
522 			return 0;
523 		}
524 		start++;
525 	}
526 
527 	return ENOENT;
528 }
529 
ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitmap,__u32 start,__u32 end,__u32 * out)530 errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitmap,
531 					       __u32 start, __u32 end,
532 					       __u32 *out)
533 {
534 	blk_t b;
535 
536 	if (start < bitmap->start || end > bitmap->end || start > end) {
537 		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
538 		return EINVAL;
539 	}
540 
541 	while (start <= end) {
542 		b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap);
543 		if (b) {
544 			*out = start;
545 			return 0;
546 		}
547 		start++;
548 	}
549 
550 	return ENOENT;
551 }
552 
ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,blk_t block,int num)553 int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
554 				   blk_t block, int num)
555 {
556 	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
557 	if ((block < bitmap->start) || (block+num-1 > bitmap->real_end)) {
558 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
559 				   block, bitmap->description);
560 		return 0;
561 	}
562 	return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap)
563 						      bitmap, block, num);
564 }
565 
ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,ext2_ino_t inode,int num)566 int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
567 				   ext2_ino_t inode, int num)
568 {
569 	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
570 	if ((inode < bitmap->start) || (inode+num-1 > bitmap->real_end)) {
571 		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
572 				   inode, bitmap->description);
573 		return 0;
574 	}
575 	return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap)
576 						      bitmap, inode, num);
577 }
578 
ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,blk_t block,int num)579 void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
580 				    blk_t block, int num)
581 {
582 	int	i;
583 
584 	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
585 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
586 				   bitmap->description);
587 		return;
588 	}
589 	for (i=0; i < num; i++)
590 		ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
591 }
592 
ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,blk_t block,int num)593 void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
594 					       blk_t block, int num)
595 {
596 	int	i;
597 
598 	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
599 		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
600 				   bitmap->description);
601 		return;
602 	}
603 	for (i=0; i < num; i++)
604 		ext2fs_fast_clear_bit(block + i - bitmap->start,
605 				      bitmap->bitmap);
606 }
607 
608