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 32void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap) 33{ 34 ext2fs_free_generic_bmap(bitmap); 35} 36 37void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap) 38{ 39 ext2fs_free_generic_bmap(bitmap); 40} 41 42errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src, 43 ext2fs_generic_bitmap *dest) 44{ 45 return (ext2fs_copy_generic_bmap(src, dest)); 46} 47void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map) 48{ 49 ext2fs_set_generic_bmap_padding(map); 50} 51 52errcode_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 84errcode_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 */ 121errcode_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 154int 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 164errcode_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 178errcode_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 187errcode_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 195void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap) 196{ 197 ext2fs_clear_generic_bmap(bitmap); 198} 199 200void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap) 201{ 202 ext2fs_clear_generic_bmap(bitmap); 203} 204 205errcode_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 212errcode_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 218errcode_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 225errcode_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 231errcode_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 238errcode_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 245errcode_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 254errcode_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 261errcode_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 270errcode_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 277errcode_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 286errcode_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 293errcode_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 302errcode_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