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