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 33void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap) 34{ 35 ext2fs_free_generic_bmap(bitmap); 36} 37 38void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap) 39{ 40 ext2fs_free_generic_bmap(bitmap); 41} 42 43errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src, 44 ext2fs_generic_bitmap *dest) 45{ 46 return (ext2fs_copy_generic_bmap(src, dest)); 47} 48void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map) 49{ 50 ext2fs_set_generic_bmap_padding(map); 51} 52 53errcode_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 85errcode_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 */ 122errcode_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 155int 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 165errcode_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 179errcode_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 188errcode_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 196void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap) 197{ 198 ext2fs_clear_generic_bmap(bitmap); 199} 200 201void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap) 202{ 203 ext2fs_clear_generic_bmap(bitmap); 204} 205 206errcode_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 213errcode_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 219errcode_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 226errcode_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 232errcode_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 239errcode_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 246errcode_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 255errcode_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 262errcode_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 271errcode_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 278errcode_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 287errcode_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 294errcode_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 303errcode_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