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