13034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o/* 2a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o * gen_bitmap.c --- Generic (32-bit) bitmap routines 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 43034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o * Copyright (C) 2001 Theodore Ts'o. 53034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o * 63034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 93034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o * %End-Header% 103034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o */ 113034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o 123034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o 133034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#include <stdio.h> 143034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#include <string.h> 153034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#if HAVE_UNISTD_H 163034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#include <unistd.h> 173034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#endif 183034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#include <fcntl.h> 193034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#include <time.h> 203034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#if HAVE_SYS_STAT_H 213034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#include <sys/stat.h> 223034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#endif 233034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#if HAVE_SYS_TYPES_H 243034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#include <sys/types.h> 253034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#endif 263034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o 273034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o#include "ext2_fs.h" 28e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include "ext2fsP.h" 293034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o 30f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'ostruct ext2fs_struct_generic_bitmap { 31f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o errcode_t magic; 32f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o ext2_filsys fs; 33f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o __u32 start, end; 34f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o __u32 real_end; 35f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o char * description; 36f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o char * bitmap; 37f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o errcode_t base_error_code; 38f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o __u32 reserved[7]; 39f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o}; 40f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o 41e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#define EXT2FS_IS_32_BITMAP(bmap) \ 42e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall (((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \ 43e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \ 44e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP)) 45e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 46e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#define EXT2FS_IS_64_BITMAP(bmap) \ 47e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall (((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP64) || \ 48e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP64) || \ 49e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP64)) 50e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 51efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o/* 52a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o * Used by previously inlined function, so we have to export this and 53a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o * not change the function signature 54a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o */ 55a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'ovoid ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap, 56a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o int code, unsigned long arg) 57a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o{ 58a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o#ifndef OMIT_COM_ERR 59a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (bitmap->description) 60a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o com_err(0, bitmap->base_error_code+code, 61a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o "#%lu for %s", arg, bitmap->description); 62a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o else 63a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o com_err(0, bitmap->base_error_code + code, "#%lu", arg); 64a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o#endif 65a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o} 66a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 67a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'ostatic errcode_t check_magic(ext2fs_generic_bitmap bitmap) 68a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o{ 69a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (!bitmap || !((bitmap->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || 70a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o (bitmap->magic == EXT2_ET_MAGIC_INODE_BITMAP) || 71a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o (bitmap->magic == EXT2_ET_MAGIC_BLOCK_BITMAP))) 72a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return EXT2_ET_MAGIC_GENERIC_BITMAP; 73a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return 0; 74a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o} 75a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 76efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs, 77a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o __u32 start, __u32 end, __u32 real_end, 78a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o const char *descr, char *init_map, 79a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_generic_bitmap *ret) 80a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o{ 81a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_generic_bitmap bitmap; 82a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o errcode_t retval; 83a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o size_t size; 84a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 85efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap), 86a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o &bitmap); 87a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (retval) 88a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return retval; 89a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 90a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->magic = magic; 91a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->fs = fs; 92a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->start = start; 93a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->end = end; 94a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->real_end = real_end; 95a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o switch (magic) { 96a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o case EXT2_ET_MAGIC_INODE_BITMAP: 97a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK; 98a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o break; 99a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o case EXT2_ET_MAGIC_BLOCK_BITMAP: 100a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK; 101a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o break; 102a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o default: 103a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK; 104a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o } 105a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (descr) { 106a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description); 107a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (retval) { 108a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_free_mem(&bitmap); 109a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return retval; 110a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o } 111a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o strcpy(bitmap->description, descr); 112a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o } else 113a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->description = 0; 114a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 115a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1); 11651e64594919c986f87267b895504322a38ec4facTheodore Ts'o /* Round up to allow for the BT x86 instruction */ 11751e64594919c986f87267b895504322a38ec4facTheodore Ts'o size = (size + 7) & ~3; 118a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o retval = ext2fs_get_mem(size, &bitmap->bitmap); 119a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (retval) { 120a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_free_mem(&bitmap->description); 121a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_free_mem(&bitmap); 122a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return retval; 123a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o } 124a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 125a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (init_map) 126a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o memcpy(bitmap->bitmap, init_map, size); 127a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o else 128a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o memset(bitmap->bitmap, 0, size); 129a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o *ret = bitmap; 130a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return 0; 131a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o} 132a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 133a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'oerrcode_t ext2fs_allocate_generic_bitmap(__u32 start, 134a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o __u32 end, 135a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o __u32 real_end, 136a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o const char *descr, 137a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_generic_bitmap *ret) 138a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o{ 139efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o return ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_GENERIC_BITMAP, 0, 140a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o start, end, real_end, descr, 0, ret); 141a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o} 142a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 143a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'oerrcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src, 144a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_generic_bitmap *dest) 145a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o{ 146a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return (ext2fs_make_generic_bitmap(src->magic, src->fs, 147efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o src->start, src->end, 148a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o src->real_end, 149a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o src->description, src->bitmap, 150a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o dest)); 151a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o} 152a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 153a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'ovoid ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap) 154a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o{ 155a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (check_magic(bitmap)) 156a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return; 157a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 158a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->magic = 0; 159a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (bitmap->description) { 160a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_free_mem(&bitmap->description); 161a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->description = 0; 162a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o } 163a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (bitmap->bitmap) { 164a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_free_mem(&bitmap->bitmap); 165a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->bitmap = 0; 166a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o } 167a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_free_mem(&bitmap); 168a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o} 169a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 170b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'oint ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap, 171b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'o blk_t bitno) 172b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'o{ 173e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!EXT2FS_IS_32_BITMAP(bitmap)) { 174e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (EXT2FS_IS_64_BITMAP(bitmap)) { 175e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_warn_bitmap32(bitmap, __func__); 176e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ext2fs_test_generic_bmap(bitmap, bitno); 177e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 178e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifndef OMIT_COM_ERR 179e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, 180e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "test_bitmap(%lu)", (unsigned long) bitno); 181e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 182e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 183e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 184e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 185b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'o if ((bitno < bitmap->start) || (bitno > bitmap->end)) { 186b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'o ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno); 187b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'o return 0; 188b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'o } 189b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'o return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap); 190b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'o} 191b15beaaf386a13d9fbaf716aac2df44748261af1Theodore Ts'o 1923034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'oint ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap, 1933034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o __u32 bitno) 1943034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o{ 195e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!EXT2FS_IS_32_BITMAP(bitmap)) { 196e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (EXT2FS_IS_64_BITMAP(bitmap)) { 197e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_warn_bitmap32(bitmap, __func__); 198e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ext2fs_mark_generic_bmap(bitmap, bitno); 199e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 200e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifndef OMIT_COM_ERR 201e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, 202e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "mark_bitmap(%lu)", (unsigned long) bitno); 203e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 204e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 205e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 206e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 2073034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o if ((bitno < bitmap->start) || (bitno > bitmap->end)) { 2083034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno); 2093034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o return 0; 2103034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o } 2113034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap); 2123034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o} 2133034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o 2143034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'oint ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap, 2153034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o blk_t bitno) 2163034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o{ 217e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!EXT2FS_IS_32_BITMAP(bitmap)) { 218e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (EXT2FS_IS_64_BITMAP(bitmap)) { 219e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_warn_bitmap32(bitmap, __func__); 220e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ext2fs_unmark_generic_bmap(bitmap, bitno); 221e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 222e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifndef OMIT_COM_ERR 223e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, 224e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "mark_bitmap(%lu)", (unsigned long) bitno); 225e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 226e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 227e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 228e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 2293034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o if ((bitno < bitmap->start) || (bitno > bitmap->end)) { 2303034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno); 2313034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o return 0; 2323034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o } 2333034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap); 2343034f62a0f9c31e6dce8bd1237cffd3851847250Theodore Ts'o} 2358df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o 236271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o__u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap) 237271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o{ 238e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!EXT2FS_IS_32_BITMAP(bitmap)) { 239e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (EXT2FS_IS_64_BITMAP(bitmap)) { 240e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_warn_bitmap32(bitmap, __func__); 241e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ext2fs_get_generic_bmap_start(bitmap); 242e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 243e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifndef OMIT_COM_ERR 244e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, 245e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "get_bitmap_start"); 246e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 247e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 248e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 249e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 250271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o return bitmap->start; 251271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o} 252271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o 253271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o__u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap) 254271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o{ 255e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!EXT2FS_IS_32_BITMAP(bitmap)) { 256e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (EXT2FS_IS_64_BITMAP(bitmap)) { 257e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_warn_bitmap32(bitmap, __func__); 258e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ext2fs_get_generic_bmap_end(bitmap); 259e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 260e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifndef OMIT_COM_ERR 261e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, 262e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "get_bitmap_end"); 263e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 264e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 265e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 266271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o return bitmap->end; 267271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o} 268271a375b596240866b4a2967e3b6f38ff7cecdf8Theodore Ts'o 269a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'ovoid ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap) 270a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o{ 271e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!EXT2FS_IS_32_BITMAP(bitmap)) { 272e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (EXT2FS_IS_64_BITMAP(bitmap)) { 273e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_warn_bitmap32(bitmap, __func__); 274e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_clear_generic_bmap(bitmap); 275e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return; 276e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 277e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifndef OMIT_COM_ERR 278e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP, 279e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "clear_generic_bitmap"); 280e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 281a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return; 282e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 283a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 284a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o memset(bitmap->bitmap, 0, 285a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1)); 286a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o} 287a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 288a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'oerrcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap, 289a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o errcode_t magic, errcode_t neq, 290a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2_ino_t end, ext2_ino_t *oend) 291a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o{ 292a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o EXT2_CHECK_MAGIC(bitmap, magic); 293efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 294a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (end > bitmap->real_end) 295a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return neq; 296a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o if (oend) 297a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o *oend = bitmap->end; 298a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o bitmap->end = end; 299a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o return 0; 300a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o} 301a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 30250448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'oerrcode_t ext2fs_resize_generic_bitmap(errcode_t magic, 30350448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o __u32 new_end, __u32 new_real_end, 30450448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o ext2fs_generic_bitmap bmap) 30550448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o{ 30650448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o errcode_t retval; 30750448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o size_t size, new_size; 30850448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o __u32 bitno; 30950448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o 31050448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (!bmap || (bmap->magic != magic)) 31150448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o return magic; 31250448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o 31350448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o /* 31450448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o * If we're expanding the bitmap, make sure all of the new 31550448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o * parts of the bitmap are zero. 31650448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o */ 31750448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (new_end > bmap->end) { 31850448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o bitno = bmap->real_end; 31950448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (bitno > new_end) 32050448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o bitno = new_end; 32150448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o for (; bitno > bmap->end; bitno--) 32250448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o ext2fs_clear_bit(bitno - bmap->start, bmap->bitmap); 32350448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o } 32450448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (new_real_end == bmap->real_end) { 32550448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o bmap->end = new_end; 32650448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o return 0; 32750448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o } 328efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 32950448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o size = ((bmap->real_end - bmap->start) / 8) + 1; 33050448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o new_size = ((new_real_end - bmap->start) / 8) + 1; 33150448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o 33250448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (size != new_size) { 33350448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o retval = ext2fs_resize_mem(size, new_size, &bmap->bitmap); 33450448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (retval) 33550448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o return retval; 33650448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o } 33750448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (new_size > size) 33850448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o memset(bmap->bitmap + size, 0, new_size - size); 33950448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o 34050448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o bmap->end = new_end; 34150448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o bmap->real_end = new_real_end; 34250448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o return 0; 34350448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o} 34450448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o 34550448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'oerrcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq, 34650448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o ext2fs_generic_bitmap bm1, 34750448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o ext2fs_generic_bitmap bm2) 34850448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o{ 34950448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o blk_t i; 350efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 35150448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (!bm1 || bm1->magic != magic) 35250448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o return magic; 35350448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (!bm2 || bm2->magic != magic) 35450448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o return magic; 35550448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o 35650448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if ((bm1->start != bm2->start) || 35750448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o (bm1->end != bm2->end) || 35850448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o (memcmp(bm1->bitmap, bm2->bitmap, 35950448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o (size_t) (bm1->end - bm1->start)/8))) 36050448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o return neq; 36150448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o 36250448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++) 36350448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o if (ext2fs_fast_test_block_bitmap(bm1, i) != 36450448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o ext2fs_fast_test_block_bitmap(bm2, i)) 36550448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o return neq; 36650448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o 36750448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o return 0; 36850448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o} 36950448d3dffc66f86592ee0d4b16e4bbe9d08449eTheodore Ts'o 370a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'ovoid ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map) 371a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o{ 372a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o __u32 i, j; 373a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 374a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o /* Protect loop from wrap-around if map->real_end is maxed */ 375efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o for (i=map->end+1, j = i - map->start; 376efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o i <= map->real_end && i > map->end; 377a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o i++, j++) 378a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o ext2fs_set_bit(j, map->bitmap); 379f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o} 380f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o 381f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'oerrcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap, 382f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o errcode_t magic, 383f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o __u32 start, __u32 num, 384f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o void *out) 385f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o{ 386f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o if (!bmap || (bmap->magic != magic)) 387f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o return magic; 388f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o 389f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o if ((start < bmap->start) || (start+num-1 > bmap->real_end)) 390f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o return EXT2_ET_INVALID_ARGUMENT; 391f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o 392f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o memcpy(out, bmap->bitmap + (start >> 3), (num+7) >> 3); 393f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o return 0; 394f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o} 395f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o 396f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'oerrcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap, 397f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o errcode_t magic, 398f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o __u32 start, __u32 num, 399f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o void *in) 400f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o{ 401f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o if (!bmap || (bmap->magic != magic)) 402f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o return magic; 403f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o 404f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o if ((start < bmap->start) || (start+num-1 > bmap->real_end)) 405f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o return EXT2_ET_INVALID_ARGUMENT; 406f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o 407f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o memcpy(bmap->bitmap + (start >> 3), in, (num+7) >> 3); 408f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o return 0; 409f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o} 410a0553c9d6e8dd6f538f18ae447c45e52f3c40eb6Theodore Ts'o 411ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o/* 412ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * Compare @mem to zero buffer by 256 bytes. 413ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * Return 1 if @mem is zeroed memory, otherwise return 0. 414ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o */ 415e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallint ext2fs_mem_is_zero(const char *mem, size_t len) 416ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o{ 417ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o static const char zero_buf[256]; 418ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 419ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o while (len >= sizeof(zero_buf)) { 420ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o if (memcmp(mem, zero_buf, sizeof(zero_buf))) 421ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return 0; 422ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o len -= sizeof(zero_buf); 423ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o mem += sizeof(zero_buf); 424ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o } 425ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o /* Deal with leftover bytes. */ 426ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o if (len) 427ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return !memcmp(mem, zero_buf, len); 428ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return 1; 429ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o} 430ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 431ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o/* 432ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * Return true if all of the bits in a specified range are clear 433ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o */ 434ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'ostatic int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap bitmap, 435ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o unsigned int start, 436ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o unsigned int len) 437ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o{ 438ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o size_t start_byte, len_byte = len >> 3; 43925c7e0c3042cb92a71d25cb3c2709a55b9f120a6Theodore Ts'o unsigned int start_bit, len_bit = len % 8; 440ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o int first_bit = 0; 441ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o int last_bit = 0; 442ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o int mark_count = 0; 443ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o int mark_bit = 0; 444ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o int i; 445ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o const char *ADDR = bitmap->bitmap; 446ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 447ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o start -= bitmap->start; 448ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o start_byte = start >> 3; 449ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o start_bit = start % 8; 450ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 451ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o if (start_bit != 0) { 452ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o /* 453ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * The compared start block number or start inode number 454ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * is not the first bit in a byte. 455ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o */ 456ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o mark_count = 8 - start_bit; 457ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o if (len < 8 - start_bit) { 458ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o mark_count = (int)len; 459ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o mark_bit = len + start_bit - 1; 460ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o } else 461ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o mark_bit = 7; 462ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 463ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o for (i = mark_count; i > 0; i--, mark_bit--) 464ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o first_bit |= 1 << mark_bit; 465ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 466ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o /* 467ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * Compare blocks or inodes in the first byte. 468ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * If there is any marked bit, this function returns 0. 469ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o */ 470ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o if (first_bit & ADDR[start_byte]) 471ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return 0; 472ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o else if (len <= 8 - start_bit) 473ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return 1; 474ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 475ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o start_byte++; 476ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o len_bit = (len - mark_count) % 8; 477ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o len_byte = (len - mark_count) >> 3; 478ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o } 479ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 480ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o /* 481ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * The compared start block number or start inode number is 482ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * the first bit in a byte. 483ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o */ 484ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o if (len_bit != 0) { 485ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o /* 486ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * The compared end block number or end inode number is 487ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * not the last bit in a byte. 488ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o */ 489ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o for (mark_bit = len_bit - 1; mark_bit >= 0; mark_bit--) 490ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o last_bit |= 1 << mark_bit; 491ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 492ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o /* 493ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * Compare blocks or inodes in the last byte. 494ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o * If there is any marked bit, this function returns 0. 495ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o */ 496ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o if (last_bit & ADDR[start_byte + len_byte]) 497ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return 0; 498ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o else if (len_byte == 0) 499ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return 1; 500ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o } 501ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 502ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o /* Check whether all bytes are 0 */ 503e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ext2fs_mem_is_zero(ADDR + start_byte, len_byte); 504ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o} 505ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 506e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap, 507e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall __u32 start, __u32 end, 508e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall __u32 *out) 509e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 510e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk_t b; 511e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 512e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (start < bitmap->start || end > bitmap->end || start > end) { 513e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start); 514e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return EINVAL; 515e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 516e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 517e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall while (start <= end) { 518e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap); 519e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!b) { 520e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *out = start; 521e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 522e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 523e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall start++; 524e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 525e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 526e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ENOENT; 527e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 528e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 529e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 5308df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'oint ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap, 5318df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o blk_t block, int num) 5328df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o{ 533ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP); 534f1f115a78f5ea599fc5f8815a741d43fedd5840dTheodore Ts'o if ((block < bitmap->start) || (block+num-1 > bitmap->real_end)) { 5358df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, 5368df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o block, bitmap->description); 5378df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o return 0; 5388df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o } 539ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap) 540ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o bitmap, block, num); 541ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o} 542ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o 543ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'oint ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap, 544ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o ino_t inode, int num) 545ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o{ 546ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP); 547ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o if ((inode < bitmap->start) || (inode+num-1 > bitmap->real_end)) { 548ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST, 549ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o inode, bitmap->description); 550ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return 0; 5518df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o } 552ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap) 553ef1a526dfbe663bb80ab75c2e7985ae8d9021b76Theodore Ts'o bitmap, inode, num); 5548df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o} 5558df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o 5568df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'ovoid ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap, 5578df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o blk_t block, int num) 5588df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o{ 5598df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o int i; 560efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 5618df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { 5628df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, 5638df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o bitmap->description); 5648df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o return; 5658df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o } 5668df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o for (i=0; i < num; i++) 5678df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap); 5688df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o} 5698df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o 5708df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'ovoid ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap, 5718df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o blk_t block, int num) 5728df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o{ 5738df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o int i; 574efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 5758df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { 5768df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block, 5778df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o bitmap->description); 5788df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o return; 5798df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o } 5808df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o for (i=0; i < num; i++) 581efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o ext2fs_fast_clear_bit(block + i - bitmap->start, 5828df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o bitmap->bitmap); 5838df1827b55f11321bfe508c89b94591bdb97c3a6Theodore Ts'o} 584e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 585