gen_bitmap.c revision 543547a52a20cb7e69d74921b2f691078fd55d83
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * gen_bitmap.c --- Generic (32-bit) bitmap routines
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2001 Theodore Ts'o.
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * %Begin-Header%
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This file may be redistributed under the terms of the GNU Library
85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) * General Public License, version 2.
95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) * %End-Header%
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stdio.h>
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string.h>
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if HAVE_UNISTD_H
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if HAVE_SYS_STAT_H
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if HAVE_SYS_TYPES_H
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ext2_fs.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ext2fs.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ext2fs_struct_generic_bitmap {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	errcode_t	magic;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ext2_filsys 	fs;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	__u32		start, end;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	__u32		real_end;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char	*	description;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char	*	bitmap;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	errcode_t	base_error_code;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	__u32		reserved[7];
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Used by previously inlined function, so we have to export this and
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * not change the function signature
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)			    int code, unsigned long arg)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef OMIT_COM_ERR
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	if (bitmap->description)
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)		com_err(0, bitmap->base_error_code+code,
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)			"#%lu for %s", arg, bitmap->description);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		com_err(0, bitmap->base_error_code + code, "#%lu", arg);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static errcode_t check_magic(ext2fs_generic_bitmap bitmap)
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles){
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!bitmap || !((bitmap->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) ||
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 (bitmap->magic == EXT2_ET_MAGIC_INODE_BITMAP) ||
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 (bitmap->magic == EXT2_ET_MAGIC_BLOCK_BITMAP)))
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		return EXT2_ET_MAGIC_GENERIC_BITMAP;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				     __u32 start, __u32 end, __u32 real_end,
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)				     const char *descr, char *init_map,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				     ext2fs_generic_bitmap *ret)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ext2fs_generic_bitmap	bitmap;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	errcode_t		retval;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t			size;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap),
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				&bitmap);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (retval)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return retval;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bitmap->magic = magic;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bitmap->fs = fs;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bitmap->start = start;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bitmap->end = end;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bitmap->real_end = real_end;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (magic) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case EXT2_ET_MAGIC_INODE_BITMAP:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case EXT2_ET_MAGIC_BLOCK_BITMAP:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (descr) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (retval) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ext2fs_free_mem(&bitmap);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return retval;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		strcpy(bitmap->description, descr);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bitmap->description = 0;
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Round up to allow for the BT x86 instruction */
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size = (size + 7) & ~3;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	retval = ext2fs_get_mem(size, &bitmap->bitmap);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (retval) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_free_mem(&bitmap->description);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_free_mem(&bitmap);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return retval;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (init_map)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		memcpy(bitmap->bitmap, init_map, size);
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	else
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		memset(bitmap->bitmap, 0, size);
119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch	*ret = bitmap;
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	return 0;
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)					 __u32 end,
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)					 __u32 real_end,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					 const char *descr,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					 ext2fs_generic_bitmap *ret)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_GENERIC_BITMAP, 0,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  start, end, real_end, descr, 0, ret);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				     ext2fs_generic_bitmap *dest)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (ext2fs_make_generic_bitmap(src->magic, src->fs,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   src->start, src->end,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   src->real_end,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   src->description, src->bitmap,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   dest));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (check_magic(bitmap))
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bitmap->magic = 0;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (bitmap->description) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_free_mem(&bitmap->description);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bitmap->description = 0;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (bitmap->bitmap) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_free_mem(&bitmap->bitmap);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bitmap->bitmap = 0;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ext2fs_free_mem(&bitmap);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					blk_t bitno)
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles){
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 0;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					 __u32 bitno)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 0;
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   blk_t bitno)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 0;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return bitmap->start;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return bitmap->end;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (check_magic(bitmap))
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memset(bitmap->bitmap, 0,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  errcode_t magic, errcode_t neq,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  ext2_ino_t end, ext2_ino_t *oend)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	EXT2_CHECK_MAGIC(bitmap, magic);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (end > bitmap->real_end)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return neq;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (oend)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*oend = bitmap->end;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bitmap->end = end;
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return 0;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				       __u32 new_end, __u32 new_real_end,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				       ext2fs_generic_bitmap bmap)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	errcode_t	retval;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t		size, new_size;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	__u32		bitno;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!bmap || (bmap->magic != magic))
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return magic;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * If we're expanding the bitmap, make sure all of the new
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * parts of the bitmap are zero.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (new_end > bmap->end) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bitno = bmap->real_end;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (bitno > new_end)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			bitno = new_end;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (; bitno > bmap->end; bitno--)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ext2fs_clear_bit(bitno - bmap->start, bmap->bitmap);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (new_real_end == bmap->real_end) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		bmap->end = new_end;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 0;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size = ((bmap->real_end - bmap->start) / 8) + 1;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	new_size = ((new_real_end - bmap->start) / 8) + 1;
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (size != new_size) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		retval = ext2fs_resize_mem(size, new_size, &bmap->bitmap);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (retval)
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)			return retval;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (new_size > size)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		memset(bmap->bitmap + size, 0, new_size - size);
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bmap->end = new_end;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bmap->real_end = new_real_end;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					ext2fs_generic_bitmap bm1,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					ext2fs_generic_bitmap bm2)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	blk_t	i;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!bm1 || bm1->magic != magic)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return magic;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!bm2 || bm2->magic != magic)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return magic;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((bm1->start != bm2->start) ||
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (bm1->end != bm2->end) ||
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (memcmp(bm1->bitmap, bm2->bitmap,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (size_t) (bm1->end - bm1->start)/8)))
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return neq;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ext2fs_fast_test_block_bitmap(bm1, i) !=
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ext2fs_fast_test_block_bitmap(bm2, i))
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return neq;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	__u32	i, j;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Protect loop from wrap-around if map->real_end is maxed */
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i=map->end+1, j = i - map->start;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     i <= map->real_end && i > map->end;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     i++, j++)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_set_bit(j, map->bitmap);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  errcode_t magic,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  __u32 start, __u32 num,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  void *out)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!bmap || (bmap->magic != magic))
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return magic;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((start < bmap->start) || (start+num-1 > bmap->real_end))
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return EXT2_ET_INVALID_ARGUMENT;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memcpy(out, bmap->bitmap + (start >> 3), (num+7) >> 3);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  errcode_t magic,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					  __u32 start, __u32 num,
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)					  void *in)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!bmap || (bmap->magic != magic))
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return magic;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	if ((start < bmap->start) || (start+num-1 > bmap->real_end))
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return EXT2_ET_INVALID_ARGUMENT;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	memcpy(bmap->bitmap + (start >> 3), in, (num+7) >> 3);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)/*
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Compare @mem to zero buffer by 256 bytes.
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * Return 1 if @mem is zeroed memory, otherwise return 0.
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) */
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int mem_is_zero(const char *mem, size_t len)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	static const char zero_buf[256];
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (len >= sizeof(zero_buf)) {
3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		if (memcmp(mem, zero_buf, sizeof(zero_buf)))
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return 0;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		len -= sizeof(zero_buf);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		mem += sizeof(zero_buf);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Deal with leftover bytes. */
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (len)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return !memcmp(mem, zero_buf, len);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 1;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)/*
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return true if all of the bits in a specified range are clear
3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) */
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap bitmap,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						  unsigned int start,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						  unsigned int len)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	size_t start_byte, len_byte = len >> 3;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int start_bit, len_bit = len % 8;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int first_bit = 0;
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	int last_bit  = 0;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int mark_count = 0;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int mark_bit = 0;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const char *ADDR = bitmap->bitmap;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	start -= bitmap->start;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	start_byte = start >> 3;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	start_bit = start % 8;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (start_bit != 0) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * The compared start block number or start inode number
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * is not the first bit in a byte.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		mark_count = 8 - start_bit;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (len < 8 - start_bit) {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			mark_count = (int)len;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			mark_bit = len + start_bit - 1;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			mark_bit = 7;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
384f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)		for (i = mark_count; i > 0; i--, mark_bit--)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			first_bit |= 1 << mark_bit;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * Compare blocks or inodes in the first byte.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * If there is any marked bit, this function returns 0.
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (first_bit & ADDR[start_byte])
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return 0;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else if (len <= 8 - start_bit)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return 1;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		start_byte++;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		len_bit = (len - mark_count) % 8;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		len_byte = (len - mark_count) >> 3;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * The compared start block number or start inode number is
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * the first bit in a byte.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	if (len_bit != 0) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * The compared end block number or end inode number is
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * not the last bit in a byte.
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (mark_bit = len_bit - 1; mark_bit >= 0; mark_bit--)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			last_bit |= 1 << mark_bit;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * Compare blocks or inodes in the last byte.
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * If there is any marked bit, this function returns 0.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (last_bit & ADDR[start_byte + len_byte])
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return 0;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else if (len_byte == 0)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return 1;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Check whether all bytes are 0 */
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return mem_is_zero(ADDR + start_byte, len_byte);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   blk_t block, int num)
4291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles){
4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	if ((block < bitmap->start) || (block+num-1 > bitmap->real_end)) {
4321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
4331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)				   block, bitmap->description);
4341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)		return 0;
4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	}
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)	return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						      bitmap, block, num);
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   ino_t inode, int num)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((inode < bitmap->start) || (inode+num-1 > bitmap->real_end)) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   inode, bitmap->description);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return 0;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						      bitmap, inode, num);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    blk_t block, int num)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int	i;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   bitmap->description);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i=0; i < num; i++)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					       blk_t block, int num)
469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int	i;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   bitmap->description);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)	for (i=0; i < num; i++)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ext2fs_fast_clear_bit(block + i - bitmap->start,
479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)				      bitmap->bitmap);
480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)