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