1/* vi: set sw=4 ts=4: */ 2/* 3 * bitmaps.c --- routines to read, write, and manipulate the inode and 4 * block bitmaps. 5 * 6 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. 7 * 8 * %Begin-Header% 9 * This file may be redistributed under the terms of the GNU Public 10 * License. 11 * %End-Header% 12 */ 13 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 "ext2fs.h" 30 31static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end, 32 const char *descr, char *init_map, 33 ext2fs_generic_bitmap *ret) 34{ 35 ext2fs_generic_bitmap bitmap; 36 errcode_t retval; 37 size_t size; 38 39 retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap), 40 &bitmap); 41 if (retval) 42 return retval; 43 44 bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP; 45 bitmap->fs = NULL; 46 bitmap->start = start; 47 bitmap->end = end; 48 bitmap->real_end = real_end; 49 bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK; 50 if (descr) { 51 retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description); 52 if (retval) { 53 ext2fs_free_mem(&bitmap); 54 return retval; 55 } 56 strcpy(bitmap->description, descr); 57 } else 58 bitmap->description = 0; 59 60 size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1); 61 retval = ext2fs_get_mem(size, &bitmap->bitmap); 62 if (retval) { 63 ext2fs_free_mem(&bitmap->description); 64 ext2fs_free_mem(&bitmap); 65 return retval; 66 } 67 68 if (init_map) 69 memcpy(bitmap->bitmap, init_map, size); 70 else 71 memset(bitmap->bitmap, 0, size); 72 *ret = bitmap; 73 return 0; 74} 75 76errcode_t ext2fs_allocate_generic_bitmap(__u32 start, 77 __u32 end, 78 __u32 real_end, 79 const char *descr, 80 ext2fs_generic_bitmap *ret) 81{ 82 return make_bitmap(start, end, real_end, descr, 0, ret); 83} 84 85errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src, 86 ext2fs_generic_bitmap *dest) 87{ 88 errcode_t retval; 89 ext2fs_generic_bitmap new_map; 90 91 retval = make_bitmap(src->start, src->end, src->real_end, 92 src->description, src->bitmap, &new_map); 93 if (retval) 94 return retval; 95 new_map->magic = src->magic; 96 new_map->fs = src->fs; 97 new_map->base_error_code = src->base_error_code; 98 *dest = new_map; 99 return 0; 100} 101 102void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map) 103{ 104 __u32 i, j; 105 106 for (i=map->end+1, j = i - map->start; i <= map->real_end; i++, j++) 107 ext2fs_set_bit(j, map->bitmap); 108} 109 110errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs, 111 const char *descr, 112 ext2fs_inode_bitmap *ret) 113{ 114 ext2fs_inode_bitmap bitmap; 115 errcode_t retval; 116 __u32 start, end, real_end; 117 118 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 119 120 fs->write_bitmaps = ext2fs_write_bitmaps; 121 122 start = 1; 123 end = fs->super->s_inodes_count; 124 real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count); 125 126 retval = ext2fs_allocate_generic_bitmap(start, end, real_end, 127 descr, &bitmap); 128 if (retval) 129 return retval; 130 131 bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP; 132 bitmap->fs = fs; 133 bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK; 134 135 *ret = bitmap; 136 return 0; 137} 138 139errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs, 140 const char *descr, 141 ext2fs_block_bitmap *ret) 142{ 143 ext2fs_block_bitmap bitmap; 144 errcode_t retval; 145 __u32 start, end, real_end; 146 147 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 148 149 fs->write_bitmaps = ext2fs_write_bitmaps; 150 151 start = fs->super->s_first_data_block; 152 end = fs->super->s_blocks_count-1; 153 real_end = (EXT2_BLOCKS_PER_GROUP(fs->super) 154 * fs->group_desc_count)-1 + start; 155 156 retval = ext2fs_allocate_generic_bitmap(start, end, real_end, 157 descr, &bitmap); 158 if (retval) 159 return retval; 160 161 bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP; 162 bitmap->fs = fs; 163 bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK; 164 165 *ret = bitmap; 166 return 0; 167} 168 169errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap, 170 ext2_ino_t end, ext2_ino_t *oend) 171{ 172 EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP); 173 174 if (end > bitmap->real_end) 175 return EXT2_ET_FUDGE_INODE_BITMAP_END; 176 if (oend) 177 *oend = bitmap->end; 178 bitmap->end = end; 179 return 0; 180} 181 182errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap, 183 blk_t end, blk_t *oend) 184{ 185 EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP); 186 187 if (end > bitmap->real_end) 188 return EXT2_ET_FUDGE_BLOCK_BITMAP_END; 189 if (oend) 190 *oend = bitmap->end; 191 bitmap->end = end; 192 return 0; 193} 194 195void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap) 196{ 197 if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP)) 198 return; 199 200 memset(bitmap->bitmap, 0, 201 (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1)); 202} 203 204void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap) 205{ 206 if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP)) 207 return; 208 209 memset(bitmap->bitmap, 0, 210 (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1)); 211} 212