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 Library 9 * General Public License, version 2. 10 * %End-Header% 11 */ 12 13 #include "config.h" 14 #include <stdio.h> 15 #include <string.h> 16 #if HAVE_UNISTD_H 17 #include <unistd.h> 18 #endif 19 #include <fcntl.h> 20 #include <time.h> 21 #if HAVE_SYS_STAT_H 22 #include <sys/stat.h> 23 #endif 24 #if HAVE_SYS_TYPES_H 25 #include <sys/types.h> 26 #endif 27 28 #include "ext2_fs.h" 29 #include "ext2fs.h" 30 #include "ext2fsP.h" 31 #include "bmap64.h" 32 33 void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap) 34 { 35 ext2fs_free_generic_bmap(bitmap); 36 } 37 38 void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap) 39 { 40 ext2fs_free_generic_bmap(bitmap); 41 } 42 43 errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src, 44 ext2fs_generic_bitmap *dest) 45 { 46 return (ext2fs_copy_generic_bmap(src, dest)); 47 } 48 void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map) 49 { 50 ext2fs_set_generic_bmap_padding(map); 51 } 52 53 errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs, 54 const char *descr, 55 ext2fs_inode_bitmap *ret) 56 { 57 __u64 start, end, real_end; 58 59 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 60 61 fs->write_bitmaps = ext2fs_write_bitmaps; 62 63 start = 1; 64 end = fs->super->s_inodes_count; 65 real_end = (__u64)EXT2_INODES_PER_GROUP(fs->super) * 66 fs->group_desc_count; 67 68 /* Are we permitted to use new-style bitmaps? */ 69 if (fs->flags & EXT2_FLAG_64BITS) 70 return (ext2fs_alloc_generic_bmap(fs, 71 EXT2_ET_MAGIC_INODE_BITMAP64, 72 fs->default_bitmap_type, 73 start, end, real_end, descr, ret)); 74 75 /* Otherwise, check to see if the file system is small enough 76 * to use old-style 32-bit bitmaps */ 77 if ((end > ~0U) || (real_end > ~0U)) 78 return EXT2_ET_CANT_USE_LEGACY_BITMAPS; 79 80 return (ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_INODE_BITMAP, fs, 81 start, end, real_end, 82 descr, 0, 83 (ext2fs_generic_bitmap *) ret)); 84 } 85 86 errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs, 87 const char *descr, 88 ext2fs_block_bitmap *ret) 89 { 90 __u64 start, end, real_end; 91 92 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 93 94 fs->write_bitmaps = ext2fs_write_bitmaps; 95 96 start = EXT2FS_B2C(fs, fs->super->s_first_data_block); 97 end = EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1); 98 real_end = ((__u64) EXT2_CLUSTERS_PER_GROUP(fs->super) 99 * (__u64) fs->group_desc_count)-1 + start; 100 101 if (fs->flags & EXT2_FLAG_64BITS) 102 return (ext2fs_alloc_generic_bmap(fs, 103 EXT2_ET_MAGIC_BLOCK_BITMAP64, 104 fs->default_bitmap_type, 105 start, end, real_end, descr, ret)); 106 107 if ((end > ~0U) || (real_end > ~0U)) 108 return EXT2_ET_CANT_USE_LEGACY_BITMAPS; 109 110 return (ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, fs, 111 start, end, real_end, 112 descr, 0, 113 (ext2fs_generic_bitmap *) ret)); 114 } 115 116 /* 117 * ext2fs_allocate_block_bitmap() really allocates a per-cluster 118 * bitmap for backwards compatibility. This function allocates a 119 * block bitmap which is truly per-block, even if clusters/bigalloc 120 * are enabled. mke2fs and e2fsck need this for tracking the 121 * allocation of the file system metadata blocks. 122 */ 123 errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs, 124 const char *descr, 125 ext2fs_block_bitmap *ret) 126 { 127 __u64 start, end, real_end; 128 ext2fs_generic_bitmap bmap; 129 ext2fs_generic_bitmap_64 bmap64; 130 errcode_t retval; 131 132 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 133 134 fs->write_bitmaps = ext2fs_write_bitmaps; 135 136 if (!fs->cluster_ratio_bits) 137 return ext2fs_allocate_block_bitmap(fs, descr, ret); 138 139 if ((fs->flags & EXT2_FLAG_64BITS) == 0) 140 return EXT2_ET_CANT_USE_LEGACY_BITMAPS; 141 142 start = fs->super->s_first_data_block; 143 end = ext2fs_blocks_count(fs->super)-1; 144 real_end = ((__u64) EXT2_BLOCKS_PER_GROUP(fs->super) 145 * (__u64) fs->group_desc_count)-1 + start; 146 147 retval = ext2fs_alloc_generic_bmap(fs, EXT2_ET_MAGIC_BLOCK_BITMAP64, 148 fs->default_bitmap_type, start, 149 end, real_end, descr, &bmap); 150 if (retval) 151 return retval; 152 bmap64 = (ext2fs_generic_bitmap_64) bmap; 153 bmap64->cluster_bits = 0; 154 *ret = bmap; 155 return 0; 156 } 157 158 int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap) 159 { 160 ext2fs_generic_bitmap_64 bmap = (ext2fs_generic_bitmap_64) bitmap; 161 162 if (!EXT2FS_IS_64_BITMAP(bmap)) 163 return 0; 164 165 return bmap->cluster_bits; 166 } 167 168 errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap, 169 ext2_ino_t end, ext2_ino_t *oend) 170 { 171 __u64 tmp_oend; 172 int retval; 173 174 retval = ext2fs_fudge_generic_bmap_end((ext2fs_generic_bitmap) bitmap, 175 EXT2_ET_FUDGE_INODE_BITMAP_END, 176 end, &tmp_oend); 177 if (oend) 178 *oend = tmp_oend; 179 return retval; 180 } 181 182 errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap, 183 blk_t end, blk_t *oend) 184 { 185 return (ext2fs_fudge_generic_bitmap_end(bitmap, 186 EXT2_ET_MAGIC_BLOCK_BITMAP, 187 EXT2_ET_FUDGE_BLOCK_BITMAP_END, 188 end, oend)); 189 } 190 191 errcode_t ext2fs_fudge_block_bitmap_end2(ext2fs_block_bitmap bitmap, 192 blk64_t end, blk64_t *oend) 193 { 194 return (ext2fs_fudge_generic_bmap_end(bitmap, 195 EXT2_ET_FUDGE_BLOCK_BITMAP_END, 196 end, oend)); 197 } 198 199 void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap) 200 { 201 ext2fs_clear_generic_bmap(bitmap); 202 } 203 204 void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap) 205 { 206 ext2fs_clear_generic_bmap(bitmap); 207 } 208 209 errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end, 210 ext2fs_inode_bitmap bmap) 211 { 212 return (ext2fs_resize_generic_bitmap(EXT2_ET_MAGIC_INODE_BITMAP, 213 new_end, new_real_end, bmap)); 214 } 215 216 errcode_t ext2fs_resize_inode_bitmap2(__u64 new_end, __u64 new_real_end, 217 ext2fs_inode_bitmap bmap) 218 { 219 return (ext2fs_resize_generic_bmap(bmap, new_end, new_real_end)); 220 } 221 222 errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end, 223 ext2fs_block_bitmap bmap) 224 { 225 return (ext2fs_resize_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, 226 new_end, new_real_end, bmap)); 227 } 228 229 errcode_t ext2fs_resize_block_bitmap2(__u64 new_end, __u64 new_real_end, 230 ext2fs_block_bitmap bmap) 231 { 232 return (ext2fs_resize_generic_bmap(bmap, new_end, new_real_end)); 233 } 234 235 errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1, 236 ext2fs_block_bitmap bm2) 237 { 238 return (ext2fs_compare_generic_bmap(EXT2_ET_NEQ_BLOCK_BITMAP, 239 bm1, bm2)); 240 } 241 242 errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1, 243 ext2fs_inode_bitmap bm2) 244 { 245 return (ext2fs_compare_generic_bmap(EXT2_ET_NEQ_INODE_BITMAP, 246 bm1, bm2)); 247 } 248 249 errcode_t ext2fs_set_inode_bitmap_range(ext2fs_inode_bitmap bmap, 250 ext2_ino_t start, unsigned int num, 251 void *in) 252 { 253 return (ext2fs_set_generic_bitmap_range(bmap, 254 EXT2_ET_MAGIC_INODE_BITMAP, 255 start, num, in)); 256 } 257 258 errcode_t ext2fs_set_inode_bitmap_range2(ext2fs_inode_bitmap bmap, 259 __u64 start, size_t num, 260 void *in) 261 { 262 return (ext2fs_set_generic_bmap_range(bmap, start, num, in)); 263 } 264 265 errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap, 266 ext2_ino_t start, unsigned int num, 267 void *out) 268 { 269 return (ext2fs_get_generic_bitmap_range(bmap, 270 EXT2_ET_MAGIC_INODE_BITMAP, 271 start, num, out)); 272 } 273 274 errcode_t ext2fs_get_inode_bitmap_range2(ext2fs_inode_bitmap bmap, 275 __u64 start, size_t num, 276 void *out) 277 { 278 return (ext2fs_get_generic_bmap_range(bmap, start, num, out)); 279 } 280 281 errcode_t ext2fs_set_block_bitmap_range(ext2fs_block_bitmap bmap, 282 blk_t start, unsigned int num, 283 void *in) 284 { 285 return (ext2fs_set_generic_bitmap_range(bmap, 286 EXT2_ET_MAGIC_BLOCK_BITMAP, 287 start, num, in)); 288 } 289 290 errcode_t ext2fs_set_block_bitmap_range2(ext2fs_block_bitmap bmap, 291 blk64_t start, size_t num, 292 void *in) 293 { 294 return (ext2fs_set_generic_bmap_range(bmap, start, num, in)); 295 } 296 297 errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap, 298 blk_t start, unsigned int num, 299 void *out) 300 { 301 return (ext2fs_get_generic_bitmap_range(bmap, 302 EXT2_ET_MAGIC_BLOCK_BITMAP, 303 start, num, out)); 304 } 305 306 errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap, 307 blk64_t start, size_t num, 308 void *out) 309 { 310 return (ext2fs_get_generic_bmap_range(bmap, start, num, out)); 311 }