1 /* This file manages the super block structure. 2 * 3 * The entry points into this file are 4 * get_super: search the 'superblock' table for a device 5 * read_super: read a superblock 6 * 7 * Created (MFS based): 8 * February 2010 (Evgeniy Ivanov) 9 */ 10 11 #include "fs.h" 12 #include <string.h> 13 #include <stdlib.h> 14 #include <assert.h> 15 #include <minix/com.h> 16 #include <minix/u64.h> 17 #include <minix/bdev.h> 18 #include <machine/param.h> 19 #include <machine/vmparam.h> 20 #include "buf.h" 21 #include "inode.h" 22 #include "super.h" 23 #include "const.h" 24 25 static off_t ext2_max_size(int block_size); 26 static u32_t ext2_count_dirs(struct super_block *sp); 27 28 static void super_copy(register struct super_block *dest, register 29 struct super_block *source); 30 static void copy_group_descriptors(register struct group_desc 31 *dest_array, register struct group_desc *source_array, unsigned int 32 ngroups); 33 34 static off_t super_block_offset; 35 36 37 /*===========================================================================* 38 * get_super * 39 *===========================================================================*/ 40 struct super_block *get_super( 41 dev_t dev /* device number whose super_block is sought */ 42 ) 43 { 44 if (dev == NO_DEV) 45 panic("request for super_block of NO_DEV"); 46 if (superblock->s_dev != dev) 47 panic("wrong superblock: 0x%x", (int) dev); 48 49 return(superblock); 50 } 51 52 53 /*===========================================================================* 54 * get_block_size * 55 *===========================================================================*/ 56 unsigned int get_block_size(dev_t dev) 57 { 58 if (dev == NO_DEV) 59 panic("request for block size of NO_DEV"); 60 return(lmfs_fs_block_size()); 61 } 62 63 static struct group_desc *ondisk_group_descs; 64 65 /*===========================================================================* 66 * read_super * 67 *===========================================================================*/ 68 int read_super(sp) 69 register struct super_block *sp; /* pointer to a superblock */ 70 { 71 /* Read a superblock. */ 72 dev_t dev; 73 int r; 74 /* group descriptors, sp->s_group_desc points to this. */ 75 static struct group_desc *group_descs; 76 char *buf; 77 block_t gd_size; /* group descriptors table size in blocks */ 78 int gdt_position; 79 static char superblock_buf[1024]; 80 81 ondisk_superblock = (struct super_block *) superblock_buf; 82 83 dev = sp->s_dev; /* save device (will be overwritten by copy) */ 84 if (dev == NO_DEV) 85 panic("request for super_block of NO_DEV"); 86 87 if (opt.block_with_super == 0) { 88 super_block_offset = SUPER_BLOCK_BYTES; 89 } else { 90 /* The block number here uses 1k units */ 91 super_block_offset = opt.block_with_super * 1024; 92 } 93 94 r = bdev_read(dev, ((u64_t)(super_block_offset)), (char*) ondisk_superblock, 95 sizeof(superblock_buf), BDEV_NOFLAGS); 96 97 if (r != sizeof(superblock_buf)) 98 return(EINVAL); 99 100 super_copy(sp, ondisk_superblock); 101 102 sp->s_dev = NO_DEV; /* restore later */ 103 104 if (sp->s_magic != SUPER_MAGIC) 105 return(EINVAL); 106 107 sp->s_block_size = 1024*(1<<sp->s_log_block_size); 108 109 if (sp->s_block_size < PAGE_SIZE) { 110 printf("data block size (%u) is invalid\n", sp->s_block_size); 111 return(EINVAL); 112 } 113 114 if ((sp->s_block_size % 512) != 0) 115 return(EINVAL); 116 117 if (SUPER_SIZE_D > sp->s_block_size) 118 return(EINVAL); 119 120 /* Variable added for convinience (i_blocks counts 512-byte blocks). */ 121 sp->s_sectors_in_block = sp->s_block_size / 512; 122 123 /* TODO: this code is for revision 1 (but bw compatible with 0) 124 * inode must be power of 2 and smaller, than block size. 125 */ 126 if ((EXT2_INODE_SIZE(sp) & (EXT2_INODE_SIZE(sp) - 1)) != 0 127 || EXT2_INODE_SIZE(sp) > sp->s_block_size) { 128 printf("superblock->s_inode_size is incorrect...\n"); 129 return(EINVAL); 130 } 131 132 sp->s_blocksize_bits = sp->s_log_block_size + 10; 133 sp->s_max_size = ext2_max_size(sp->s_block_size); 134 sp->s_inodes_per_block = sp->s_block_size / EXT2_INODE_SIZE(sp); 135 if (sp->s_inodes_per_block == 0 || sp->s_inodes_per_group == 0) { 136 printf("either inodes_per_block or inodes_per_group count is 0\n"); 137 return(EINVAL); 138 } 139 140 sp->s_itb_per_group = sp->s_inodes_per_group / sp->s_inodes_per_block; 141 sp->s_desc_per_block = sp->s_block_size / sizeof(struct group_desc); 142 143 sp->s_groups_count = ((sp->s_blocks_count - sp->s_first_data_block - 1) 144 / sp->s_blocks_per_group) + 1; 145 146 /* ceil(groups_count/desc_per_block) */ 147 sp->s_gdb_count = (sp->s_groups_count + sp->s_desc_per_block - 1) 148 / sp->s_desc_per_block; 149 150 gd_size = sp->s_gdb_count * sp->s_block_size; 151 152 buf = 0; 153 STATICINIT(buf, gd_size); 154 group_descs = (struct group_desc *) buf; 155 156 buf = 0; 157 STATICINIT(buf, gd_size); 158 ondisk_group_descs = (struct group_desc *) buf; 159 160 if (!group_descs || !ondisk_group_descs) 161 panic("can't allocate memory for gdt buffer"); 162 163 /* s_first_data_block (block number, where superblock is stored) 164 * is 1 for 1Kb blocks and 0 for larger blocks. 165 * For fs with 1024-byte blocks first 1024 bytes (block0) used by MBR, 166 * and block1 stores superblock. When block size is larger, block0 stores 167 * both MBR and superblock, but gdt lives in next block anyway. 168 * If sb=N was specified, then gdt is stored in N+1 block, the block number 169 * here uses 1k units. 170 * 171 */ 172 if (opt.block_with_super == 0) { 173 gdt_position = (sp->s_first_data_block + 1) * sp->s_block_size; 174 } else { 175 gdt_position = (opt.block_with_super + 1) * 1024; 176 } 177 178 r = bdev_read(dev, ((u64_t)(gdt_position)), (char*) ondisk_group_descs, 179 gd_size, BDEV_NOFLAGS); 180 if (r != (ssize_t) gd_size) { 181 printf("Can not read group descriptors\n"); 182 return(EINVAL); 183 } 184 185 /* TODO: check descriptors we just read */ 186 187 copy_group_descriptors(group_descs, ondisk_group_descs, sp->s_groups_count); 188 sp->s_group_desc = group_descs; 189 190 /* Make a few basic checks to see if super block looks reasonable. */ 191 if (sp->s_inodes_count < 1 || sp->s_blocks_count < 1) { 192 printf("not enough inodes or data blocks, \n"); 193 return(EINVAL); 194 } 195 196 sp->s_dirs_counter = ext2_count_dirs(sp); 197 198 /* Start block search from this block. 199 * We skip superblock (1 block), group descriptors blocks (sp->s_gdb_count) 200 * block and inode bitmaps (2 blocks) and inode table. 201 */ 202 sp->s_bsearch = sp->s_first_data_block + 1 + sp->s_gdb_count + 2 203 + sp->s_itb_per_group; 204 205 sp->s_igsearch = 0; 206 207 sp->s_dev = dev; /* restore device number */ 208 return(OK); 209 } 210 211 212 /*===========================================================================* 213 * write_super * 214 *===========================================================================*/ 215 void write_super(sp) 216 struct super_block *sp; /* pointer to a superblock */ 217 { 218 /* Write a superblock and gdt. */ 219 int r; 220 block_t gd_size; /* group descriptors table size in blocks */ 221 int gdt_position; 222 223 if (sp->s_rd_only) 224 panic("can't write superblock on read-only filesys."); 225 226 if (sp->s_dev == NO_DEV) 227 panic("request to write super_block, but NO_DEV"); 228 229 super_copy(ondisk_superblock, sp); 230 231 r = bdev_write(sp->s_dev, ((u64_t)(super_block_offset)), (char *) sp, 232 SUPER_SIZE_D, BDEV_NOFLAGS); 233 if (r != SUPER_SIZE_D) 234 printf("ext2: Warning, failed to write superblock to the disk!\n"); 235 236 if (group_descriptors_dirty) { 237 /* Locate the appropriate super_block. */ 238 gd_size = sp->s_gdb_count * sp->s_block_size; 239 240 if (opt.block_with_super == 0) { 241 gdt_position = (sp->s_first_data_block + 1) * sp->s_block_size; 242 } else { 243 gdt_position = (opt.block_with_super + 1) * 1024; 244 } 245 246 copy_group_descriptors(ondisk_group_descs, sp->s_group_desc, 247 sp->s_groups_count); 248 249 r = bdev_write(sp->s_dev, ((u64_t)(gdt_position)), 250 (char*) ondisk_group_descs, gd_size, BDEV_NOFLAGS); 251 if (r != (ssize_t) gd_size) { 252 printf("Can not write group descriptors\n"); 253 } 254 group_descriptors_dirty = 0; 255 } 256 } 257 258 259 /*===========================================================================* 260 * get_group_desc * 261 *===========================================================================*/ 262 struct group_desc* get_group_desc(unsigned int bnum) 263 { 264 if (bnum >= superblock->s_groups_count) { 265 printf("ext2, get_group_desc: wrong bnum (%d) requested\n", bnum); 266 return NULL; 267 } 268 return &superblock->s_group_desc[bnum]; 269 } 270 271 272 static u32_t ext2_count_dirs(struct super_block *sp) 273 { 274 u32_t count = 0; 275 unsigned int i; 276 277 for (i = 0; i < sp->s_groups_count; i++) { 278 struct group_desc *desc = get_group_desc(i); 279 if (!desc) 280 continue; /* TODO: fail? */ 281 count += desc->used_dirs_count; 282 } 283 return count; 284 } 285 286 287 /*===========================================================================* 288 * ext2_max_size * 289 *===========================================================================*/ 290 /* There are several things, which affect max filesize: 291 * - inode.i_blocks (512-byte blocks) is limited to (2^32 - 1). 292 * - number of addressed direct, single, double and triple indirect blocks. 293 * Number of addressed blocks depends on block_size only, thus unlike in 294 * linux (ext2_max_size) we do not make calculations, but use constants 295 * for different block sizes. Calculations (gcc code) are commented. 296 * Note: linux ext2_max_size makes calculated based on shifting, not 297 * arithmetics. 298 * (!!!)Note: constants hardly tight to EXT2_NDIR_BLOCKS, but I doubt its value 299 * will be changed someday. So if it's changed, then just recalculate constatns. 300 * Anyway this function is safe for any change. 301 * Note: there is also limitation from VFS (to LONG_MAX, i.e. 2GB). 302 */ 303 static off_t ext2_max_size(int block_size) 304 { 305 /* 12 is EXT2_NDIR_BLOCKS used in calculations. */ 306 if (EXT2_NDIR_BLOCKS != 12) 307 panic("ext2_max_size needs modification!"); 308 switch(block_size) { 309 case 1024: return LONG_MAX; /* actually 17247252480 */ 310 case 2048: return LONG_MAX; /* 275415851008 */ 311 case 4096: return LONG_MAX; /* 2194719883264 */ 312 default: { 313 ext2_debug("ext2_max_size: Unsupported block_size! \ 314 Assuming bs is 1024 bytes\n"); 315 return 67383296L; 316 } 317 } 318 #if 0 319 long addr_in_block = block_size/4; /* 4 bytes per addr */ 320 long sectors_in_block = block_size/512; 321 long long meta_blocks; /* single, double and triple indirect blocks */ 322 unsigned long long out_range_s; /* max blocks addressed by inode */ 323 unsigned long long max_bytes; 324 unsigned long long upper_limit; 325 326 /* 1 indirect block, 1 + addr_in_block dindirect and 1 + addr_in_block + 327 * + addr_in_block*addr_in_block triple indirect blocks */ 328 meta_blocks = 2*addr_in_block + addr_in_block*addr_in_block + 3; 329 out_range_s = EXT2_NDIR_BLOCKS + addr_in_block + addr_in_block * addr_in_block 330 + addr_in_block * addr_in_block * addr_in_block; 331 max_bytes = out_range_s * block_size; 332 333 upper_limit = (1LL << 32) - 1; /* max 512-byte blocks by i_blocks */ 334 upper_limit /= sectors_in_block; /* total block_size blocks */ 335 upper_limit -= meta_blocks; /* total data blocks */ 336 upper_limit *= (long long)block_size; /* max size in bytes */ 337 338 if (max_bytes > upper_limit) 339 max_bytes = upper_limit; 340 341 /* Limit s_max_size to LONG_MAX */ 342 if (max_bytes > LONG_MAX) 343 max_bytes = LONG_MAX; 344 345 return max_bytes; 346 #endif 347 } 348 349 350 /*===========================================================================* 351 * super_copy * 352 *===========================================================================*/ 353 static void super_copy( 354 register struct super_block *dest, 355 register struct super_block *source 356 ) 357 /* Note: we don't convert stuff, used in ext3. */ 358 { 359 /* Copy super_block to the in-core table, swapping bytes if need be. */ 360 if (le_CPU) { 361 /* Just use memcpy */ 362 memcpy(dest, source, SUPER_SIZE_D); 363 return; 364 } 365 dest->s_inodes_count = conv4(le_CPU, source->s_inodes_count); 366 dest->s_blocks_count = conv4(le_CPU, source->s_blocks_count); 367 dest->s_r_blocks_count = conv4(le_CPU, source->s_r_blocks_count); 368 dest->s_free_blocks_count = conv4(le_CPU, source->s_free_blocks_count); 369 dest->s_free_inodes_count = conv4(le_CPU, source->s_free_inodes_count); 370 dest->s_first_data_block = conv4(le_CPU, source->s_first_data_block); 371 dest->s_log_block_size = conv4(le_CPU, source->s_log_block_size); 372 dest->s_log_frag_size = conv4(le_CPU, source->s_log_frag_size); 373 dest->s_blocks_per_group = conv4(le_CPU, source->s_blocks_per_group); 374 dest->s_frags_per_group = conv4(le_CPU, source->s_frags_per_group); 375 dest->s_inodes_per_group = conv4(le_CPU, source->s_inodes_per_group); 376 dest->s_mtime = conv4(le_CPU, source->s_mtime); 377 dest->s_wtime = conv4(le_CPU, source->s_wtime); 378 dest->s_mnt_count = conv2(le_CPU, source->s_mnt_count); 379 dest->s_max_mnt_count = conv2(le_CPU, source->s_max_mnt_count); 380 dest->s_magic = conv2(le_CPU, source->s_magic); 381 dest->s_state = conv2(le_CPU, source->s_state); 382 dest->s_errors = conv2(le_CPU, source->s_errors); 383 dest->s_minor_rev_level = conv2(le_CPU, source->s_minor_rev_level); 384 dest->s_lastcheck = conv4(le_CPU, source->s_lastcheck); 385 dest->s_checkinterval = conv4(le_CPU, source->s_checkinterval); 386 dest->s_creator_os = conv4(le_CPU, source->s_creator_os); 387 dest->s_rev_level = conv4(le_CPU, source->s_rev_level); 388 dest->s_def_resuid = conv2(le_CPU, source->s_def_resuid); 389 dest->s_def_resgid = conv2(le_CPU, source->s_def_resgid); 390 dest->s_first_ino = conv4(le_CPU, source->s_first_ino); 391 dest->s_inode_size = conv2(le_CPU, source->s_inode_size); 392 dest->s_block_group_nr = conv2(le_CPU, source->s_block_group_nr); 393 dest->s_feature_compat = conv4(le_CPU, source->s_feature_compat); 394 dest->s_feature_incompat = conv4(le_CPU, source->s_feature_incompat); 395 dest->s_feature_ro_compat = conv4(le_CPU, source->s_feature_ro_compat); 396 memcpy(dest->s_uuid, source->s_uuid, sizeof(dest->s_uuid)); 397 memcpy(dest->s_volume_name, source->s_volume_name, 398 sizeof(dest->s_volume_name)); 399 memcpy(dest->s_last_mounted, source->s_last_mounted, 400 sizeof(dest->s_last_mounted)); 401 dest->s_algorithm_usage_bitmap = 402 conv4(le_CPU, source->s_algorithm_usage_bitmap); 403 dest->s_prealloc_blocks = source->s_prealloc_blocks; 404 dest->s_prealloc_dir_blocks = source->s_prealloc_dir_blocks; 405 dest->s_padding1 = conv2(le_CPU, source->s_padding1); 406 } 407 408 409 /*===========================================================================* 410 * gd_copy * 411 *===========================================================================*/ 412 static void gd_copy( 413 register struct group_desc *dest, 414 register struct group_desc *source 415 ) 416 { 417 /* Copy super_block to the in-core table, swapping bytes if need be. */ 418 if (le_CPU) { 419 /* Just use memcpy */ 420 memcpy(dest, source, sizeof(struct group_desc)); 421 return; 422 } 423 dest->block_bitmap = conv4(le_CPU, source->block_bitmap); 424 dest->inode_bitmap = conv4(le_CPU, source->inode_bitmap); 425 dest->inode_table = conv4(le_CPU, source->inode_table); 426 dest->free_blocks_count = conv2(le_CPU, source->free_blocks_count); 427 dest->free_inodes_count = conv2(le_CPU, source->free_inodes_count); 428 dest->used_dirs_count = conv2(le_CPU, source->used_dirs_count); 429 } 430 431 432 /*===========================================================================* 433 * copy_group_descriptors * 434 *===========================================================================*/ 435 static void copy_group_descriptors( 436 register struct group_desc *dest_array, 437 register struct group_desc *source_array, 438 unsigned int ngroups 439 ) 440 { 441 unsigned int i; 442 for (i = 0; i < ngroups; i++) 443 gd_copy(&dest_array[i], &source_array[i]); 444 } 445