1 /* 2 * resize2fs.c --- ext2 main routine 3 * 4 * Copyright (C) 1997, 1998 by Theodore Ts'o and 5 * PowerQuest, Inc. 6 * 7 * Copyright (C) 1999, 2000 by Theosore Ts'o 8 * 9 * %Begin-Header% 10 * This file may be redistributed under the terms of the GNU Public 11 * License. 12 * %End-Header% 13 */ 14 15 /* 16 * Resizing a filesystem consists of the following phases: 17 * 18 * 1. Adjust superblock and write out new parts of the inode 19 * table 20 * 2. Determine blocks which need to be relocated, and copy the 21 * contents of blocks from their old locations to the new ones. 22 * 3. Scan the inode table, doing the following: 23 * a. If blocks have been moved, update the block 24 * pointers in the inodes and indirect blocks to 25 * point at the new block locations. 26 * b. If parts of the inode table need to be evacuated, 27 * copy inodes from their old locations to their 28 * new ones. 29 * c. If (b) needs to be done, note which blocks contain 30 * directory information, since we will need to 31 * update the directory information. 32 * 4. Update the directory blocks with the new inode locations. 33 * 5. Move the inode tables, if necessary. 34 */ 35 36 #include "resize2fs.h" 37 #include <time.h> 38 39 #ifdef __linux__ /* Kludge for debugging */ 40 #define RESIZE2FS_DEBUG 41 #endif 42 43 static void fix_uninit_block_bitmaps(ext2_filsys fs); 44 static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size); 45 static errcode_t blocks_to_move(ext2_resize_t rfs); 46 static errcode_t block_mover(ext2_resize_t rfs); 47 static errcode_t inode_scan_and_fix(ext2_resize_t rfs); 48 static errcode_t inode_ref_fix(ext2_resize_t rfs); 49 static errcode_t move_itables(ext2_resize_t rfs); 50 static errcode_t fix_resize_inode(ext2_filsys fs); 51 static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs); 52 static errcode_t fix_sb_journal_backup(ext2_filsys fs); 53 static errcode_t mark_table_blocks(ext2_filsys fs, 54 ext2fs_block_bitmap bmap); 55 56 /* 57 * Some helper CPP macros 58 */ 59 #define IS_BLOCK_BM(fs, i, blk) ((blk) == ext2fs_block_bitmap_loc((fs),(i))) 60 #define IS_INODE_BM(fs, i, blk) ((blk) == ext2fs_inode_bitmap_loc((fs),(i))) 61 62 #define IS_INODE_TB(fs, i, blk) (((blk) >= ext2fs_inode_table_loc((fs), (i))) && \ 63 ((blk) < (ext2fs_inode_table_loc((fs), (i)) + \ 64 (fs)->inode_blocks_per_group))) 65 66 /* Some bigalloc helper macros which are more succint... */ 67 #define B2C(x) EXT2FS_B2C(fs, (x)) 68 #define C2B(x) EXT2FS_C2B(fs, (x)) 69 #define EQ_CLSTR(x, y) (B2C(x) == B2C(y)) 70 #define LE_CLSTR(x, y) (B2C(x) <= B2C(y)) 71 #define LT_CLSTR(x, y) (B2C(x) < B2C(y)) 72 #define GE_CLSTR(x, y) (B2C(x) >= B2C(y)) 73 #define GT_CLSTR(x, y) (B2C(x) > B2C(y)) 74 75 static int lazy_itable_init; 76 77 /* 78 * This is the top-level routine which does the dirty deed.... 79 */ 80 errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags, 81 errcode_t (*progress)(ext2_resize_t rfs, int pass, 82 unsigned long cur, 83 unsigned long max_val)) 84 { 85 ext2_resize_t rfs; 86 errcode_t retval; 87 struct resource_track rtrack, overall_track; 88 89 /* 90 * Create the data structure 91 */ 92 retval = ext2fs_get_mem(sizeof(struct ext2_resize_struct), &rfs); 93 if (retval) 94 return retval; 95 96 memset(rfs, 0, sizeof(struct ext2_resize_struct)); 97 fs->priv_data = rfs; 98 rfs->old_fs = fs; 99 rfs->flags = flags; 100 rfs->itable_buf = 0; 101 rfs->progress = progress; 102 103 init_resource_track(&overall_track, "overall resize2fs", fs->io); 104 init_resource_track(&rtrack, "read_bitmaps", fs->io); 105 retval = ext2fs_read_bitmaps(fs); 106 if (retval) 107 goto errout; 108 print_resource_track(rfs, &rtrack, fs->io); 109 110 fs->super->s_state |= EXT2_ERROR_FS; 111 ext2fs_mark_super_dirty(fs); 112 ext2fs_flush(fs); 113 114 init_resource_track(&rtrack, "fix_uninit_block_bitmaps 1", fs->io); 115 fix_uninit_block_bitmaps(fs); 116 print_resource_track(rfs, &rtrack, fs->io); 117 retval = ext2fs_dup_handle(fs, &rfs->new_fs); 118 if (retval) 119 goto errout; 120 121 init_resource_track(&rtrack, "adjust_superblock", fs->io); 122 retval = adjust_superblock(rfs, *new_size); 123 if (retval) 124 goto errout; 125 print_resource_track(rfs, &rtrack, fs->io); 126 127 128 init_resource_track(&rtrack, "fix_uninit_block_bitmaps 2", fs->io); 129 fix_uninit_block_bitmaps(rfs->new_fs); 130 print_resource_track(rfs, &rtrack, fs->io); 131 /* Clear the block bitmap uninit flag for the last block group */ 132 ext2fs_bg_flags_clear(rfs->new_fs, rfs->new_fs->group_desc_count - 1, 133 EXT2_BG_BLOCK_UNINIT); 134 135 *new_size = ext2fs_blocks_count(rfs->new_fs->super); 136 137 init_resource_track(&rtrack, "blocks_to_move", fs->io); 138 retval = blocks_to_move(rfs); 139 if (retval) 140 goto errout; 141 print_resource_track(rfs, &rtrack, fs->io); 142 143 #ifdef RESIZE2FS_DEBUG 144 if (rfs->flags & RESIZE_DEBUG_BMOVE) 145 printf("Number of free blocks: %llu/%llu, Needed: %llu\n", 146 ext2fs_free_blocks_count(rfs->old_fs->super), 147 ext2fs_free_blocks_count(rfs->new_fs->super), 148 rfs->needed_blocks); 149 #endif 150 151 init_resource_track(&rtrack, "block_mover", fs->io); 152 retval = block_mover(rfs); 153 if (retval) 154 goto errout; 155 print_resource_track(rfs, &rtrack, fs->io); 156 157 init_resource_track(&rtrack, "inode_scan_and_fix", fs->io); 158 retval = inode_scan_and_fix(rfs); 159 if (retval) 160 goto errout; 161 print_resource_track(rfs, &rtrack, fs->io); 162 163 init_resource_track(&rtrack, "inode_ref_fix", fs->io); 164 retval = inode_ref_fix(rfs); 165 if (retval) 166 goto errout; 167 print_resource_track(rfs, &rtrack, fs->io); 168 169 init_resource_track(&rtrack, "move_itables", fs->io); 170 retval = move_itables(rfs); 171 if (retval) 172 goto errout; 173 print_resource_track(rfs, &rtrack, fs->io); 174 175 init_resource_track(&rtrack, "calculate_summary_stats", fs->io); 176 retval = ext2fs_calculate_summary_stats(rfs->new_fs); 177 if (retval) 178 goto errout; 179 print_resource_track(rfs, &rtrack, fs->io); 180 181 init_resource_track(&rtrack, "fix_resize_inode", fs->io); 182 retval = fix_resize_inode(rfs->new_fs); 183 if (retval) 184 goto errout; 185 print_resource_track(rfs, &rtrack, fs->io); 186 187 init_resource_track(&rtrack, "fix_sb_journal_backup", fs->io); 188 retval = fix_sb_journal_backup(rfs->new_fs); 189 if (retval) 190 goto errout; 191 print_resource_track(rfs, &rtrack, fs->io); 192 193 rfs->new_fs->super->s_state &= ~EXT2_ERROR_FS; 194 rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 195 196 print_resource_track(rfs, &overall_track, fs->io); 197 retval = ext2fs_close(rfs->new_fs); 198 if (retval) 199 goto errout; 200 201 rfs->flags = flags; 202 203 ext2fs_free(rfs->old_fs); 204 if (rfs->itable_buf) 205 ext2fs_free_mem(&rfs->itable_buf); 206 if (rfs->reserve_blocks) 207 ext2fs_free_block_bitmap(rfs->reserve_blocks); 208 if (rfs->move_blocks) 209 ext2fs_free_block_bitmap(rfs->move_blocks); 210 ext2fs_free_mem(&rfs); 211 212 return 0; 213 214 errout: 215 if (rfs->new_fs) 216 ext2fs_free(rfs->new_fs); 217 if (rfs->itable_buf) 218 ext2fs_free_mem(&rfs->itable_buf); 219 ext2fs_free_mem(&rfs); 220 return retval; 221 } 222 223 /* 224 * Clean up the bitmaps for unitialized bitmaps 225 */ 226 static void fix_uninit_block_bitmaps(ext2_filsys fs) 227 { 228 blk64_t blk, lblk; 229 dgrp_t g; 230 int i; 231 232 if (!(EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 233 EXT4_FEATURE_RO_COMPAT_GDT_CSUM))) 234 return; 235 236 for (g=0; g < fs->group_desc_count; g++) { 237 if (!(ext2fs_bg_flags_test(fs, g, EXT2_BG_BLOCK_UNINIT))) 238 continue; 239 240 blk = ext2fs_group_first_block2(fs, g); 241 lblk = ext2fs_group_last_block2(fs, g); 242 ext2fs_unmark_block_bitmap_range2(fs->block_map, blk, 243 lblk - blk + 1); 244 245 ext2fs_reserve_super_and_bgd(fs, g, fs->block_map); 246 ext2fs_mark_block_bitmap2(fs->block_map, 247 ext2fs_block_bitmap_loc(fs, g)); 248 ext2fs_mark_block_bitmap2(fs->block_map, 249 ext2fs_inode_bitmap_loc(fs, g)); 250 for (i = 0, blk = ext2fs_inode_table_loc(fs, g); 251 i < (unsigned int) fs->inode_blocks_per_group; 252 i++, blk++) 253 ext2fs_mark_block_bitmap2(fs->block_map, blk); 254 } 255 } 256 257 /* -------------------------------------------------------------------- 258 * 259 * Resize processing, phase 1. 260 * 261 * In this phase we adjust the in-memory superblock information, and 262 * initialize any new parts of the inode table. The new parts of the 263 * inode table are created in virgin disk space, so we can abort here 264 * without any side effects. 265 * -------------------------------------------------------------------- 266 */ 267 268 /* 269 * If the group descriptor's bitmap and inode table blocks are valid, 270 * release them in the new filesystem data structure, and mark them as 271 * reserved so the old inode table blocks don't get overwritten. 272 */ 273 static void free_gdp_blocks(ext2_filsys fs, 274 ext2fs_block_bitmap reserve_blocks, 275 ext2_filsys old_fs, 276 dgrp_t group) 277 { 278 blk64_t blk; 279 int j; 280 281 blk = ext2fs_block_bitmap_loc(old_fs, group); 282 if (blk && 283 (blk < ext2fs_blocks_count(fs->super))) { 284 ext2fs_block_alloc_stats2(fs, blk, -1); 285 ext2fs_mark_block_bitmap2(reserve_blocks, blk); 286 } 287 288 blk = ext2fs_inode_bitmap_loc(old_fs, group); 289 if (blk && 290 (blk < ext2fs_blocks_count(fs->super))) { 291 ext2fs_block_alloc_stats2(fs, blk, -1); 292 ext2fs_mark_block_bitmap2(reserve_blocks, blk); 293 } 294 295 blk = ext2fs_inode_table_loc(old_fs, group); 296 if (blk == 0 || 297 (blk >= ext2fs_blocks_count(fs->super))) 298 return; 299 300 for (j = 0; 301 j < fs->inode_blocks_per_group; j++, blk++) { 302 if (blk >= ext2fs_blocks_count(fs->super)) 303 break; 304 ext2fs_block_alloc_stats2(fs, blk, -1); 305 ext2fs_mark_block_bitmap2(reserve_blocks, blk); 306 } 307 } 308 309 /* 310 * This routine is shared by the online and offline resize routines. 311 * All of the information which is adjusted in memory is done here. 312 */ 313 errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs, 314 ext2fs_block_bitmap reserve_blocks, blk64_t new_size) 315 { 316 errcode_t retval; 317 blk64_t overhead = 0; 318 blk64_t rem; 319 blk64_t blk, group_block; 320 blk64_t real_end; 321 blk64_t old_numblocks, numblocks, adjblocks; 322 unsigned long i, j, old_desc_blocks; 323 unsigned int meta_bg, meta_bg_size; 324 int has_super, csum_flag; 325 unsigned long long new_inodes; /* u64 to check for overflow */ 326 double percent; 327 328 ext2fs_blocks_count_set(fs->super, new_size); 329 330 retry: 331 fs->group_desc_count = ext2fs_div64_ceil(ext2fs_blocks_count(fs->super) - 332 fs->super->s_first_data_block, 333 EXT2_BLOCKS_PER_GROUP(fs->super)); 334 if (fs->group_desc_count == 0) 335 return EXT2_ET_TOOSMALL; 336 fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count, 337 EXT2_DESC_PER_BLOCK(fs->super)); 338 339 /* 340 * Overhead is the number of bookkeeping blocks per group. It 341 * includes the superblock backup, the group descriptor 342 * backups, the inode bitmap, the block bitmap, and the inode 343 * table. 344 */ 345 overhead = (int) (2 + fs->inode_blocks_per_group); 346 347 if (ext2fs_bg_has_super(fs, fs->group_desc_count - 1)) 348 overhead += 1 + fs->desc_blocks + 349 fs->super->s_reserved_gdt_blocks; 350 351 /* 352 * See if the last group is big enough to support the 353 * necessary data structures. If not, we need to get rid of 354 * it. 355 */ 356 rem = (ext2fs_blocks_count(fs->super) - fs->super->s_first_data_block) % 357 fs->super->s_blocks_per_group; 358 if ((fs->group_desc_count == 1) && rem && (rem < overhead)) 359 return EXT2_ET_TOOSMALL; 360 if ((fs->group_desc_count > 1) && rem && (rem < overhead+50)) { 361 ext2fs_blocks_count_set(fs->super, 362 ext2fs_blocks_count(fs->super) - rem); 363 goto retry; 364 } 365 /* 366 * Adjust the number of inodes 367 */ 368 new_inodes =(unsigned long long) fs->super->s_inodes_per_group * fs->group_desc_count; 369 if (new_inodes > ~0U) { 370 fprintf(stderr, _("inodes (%llu) must be less than %u"), 371 new_inodes, ~0U); 372 return EXT2_ET_TOO_MANY_INODES; 373 } 374 fs->super->s_inodes_count = fs->super->s_inodes_per_group * 375 fs->group_desc_count; 376 377 /* 378 * Adjust the number of free blocks 379 */ 380 blk = ext2fs_blocks_count(old_fs->super); 381 if (blk > ext2fs_blocks_count(fs->super)) 382 ext2fs_free_blocks_count_set(fs->super, 383 ext2fs_free_blocks_count(fs->super) - 384 (blk - ext2fs_blocks_count(fs->super))); 385 else 386 ext2fs_free_blocks_count_set(fs->super, 387 ext2fs_free_blocks_count(fs->super) + 388 (ext2fs_blocks_count(fs->super) - blk)); 389 390 /* 391 * Adjust the number of reserved blocks 392 */ 393 percent = (ext2fs_r_blocks_count(old_fs->super) * 100.0) / 394 ext2fs_blocks_count(old_fs->super); 395 ext2fs_r_blocks_count_set(fs->super, 396 (percent * ext2fs_blocks_count(fs->super) / 397 100.0)); 398 399 /* 400 * Adjust the bitmaps for size 401 */ 402 retval = ext2fs_resize_inode_bitmap2(fs->super->s_inodes_count, 403 fs->super->s_inodes_count, 404 fs->inode_map); 405 if (retval) goto errout; 406 407 real_end = (((blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super) * 408 fs->group_desc_count)) - 1 + 409 fs->super->s_first_data_block; 410 retval = ext2fs_resize_block_bitmap2(new_size - 1, 411 real_end, fs->block_map); 412 if (retval) goto errout; 413 414 /* 415 * If we are growing the file system, also grow the size of 416 * the reserve_blocks bitmap 417 */ 418 if (reserve_blocks && new_size > ext2fs_blocks_count(old_fs->super)) { 419 retval = ext2fs_resize_block_bitmap2(new_size - 1, 420 real_end, reserve_blocks); 421 if (retval) goto errout; 422 } 423 424 /* 425 * Reallocate the group descriptors as necessary. 426 */ 427 if (old_fs->desc_blocks != fs->desc_blocks) { 428 retval = ext2fs_resize_mem(old_fs->desc_blocks * 429 fs->blocksize, 430 fs->desc_blocks * fs->blocksize, 431 &fs->group_desc); 432 if (retval) 433 goto errout; 434 if (fs->desc_blocks > old_fs->desc_blocks) 435 memset((char *) fs->group_desc + 436 (old_fs->desc_blocks * fs->blocksize), 0, 437 (fs->desc_blocks - old_fs->desc_blocks) * 438 fs->blocksize); 439 } 440 441 /* 442 * If the resize_inode feature is set, and we are changing the 443 * number of descriptor blocks, then adjust 444 * s_reserved_gdt_blocks if possible to avoid needing to move 445 * the inode table either now or in the future. 446 */ 447 if ((fs->super->s_feature_compat & 448 EXT2_FEATURE_COMPAT_RESIZE_INODE) && 449 (old_fs->desc_blocks != fs->desc_blocks)) { 450 int new; 451 452 new = ((int) fs->super->s_reserved_gdt_blocks) + 453 (old_fs->desc_blocks - fs->desc_blocks); 454 if (new < 0) 455 new = 0; 456 if (new > (int) fs->blocksize/4) 457 new = fs->blocksize/4; 458 fs->super->s_reserved_gdt_blocks = new; 459 } 460 461 /* 462 * If we are shrinking the number of block groups, we're done 463 * and can exit now. 464 */ 465 if (old_fs->group_desc_count > fs->group_desc_count) { 466 /* 467 * Check the block groups that we are chopping off 468 * and free any blocks associated with their metadata 469 */ 470 for (i = fs->group_desc_count; 471 i < old_fs->group_desc_count; i++) 472 free_gdp_blocks(fs, reserve_blocks, old_fs, i); 473 retval = 0; 474 goto errout; 475 } 476 477 /* 478 * Fix the count of the last (old) block group 479 */ 480 old_numblocks = (ext2fs_blocks_count(old_fs->super) - 481 old_fs->super->s_first_data_block) % 482 old_fs->super->s_blocks_per_group; 483 if (!old_numblocks) 484 old_numblocks = old_fs->super->s_blocks_per_group; 485 if (old_fs->group_desc_count == fs->group_desc_count) { 486 numblocks = (ext2fs_blocks_count(fs->super) - 487 fs->super->s_first_data_block) % 488 fs->super->s_blocks_per_group; 489 if (!numblocks) 490 numblocks = fs->super->s_blocks_per_group; 491 } else 492 numblocks = fs->super->s_blocks_per_group; 493 i = old_fs->group_desc_count - 1; 494 ext2fs_bg_free_blocks_count_set(fs, i, ext2fs_bg_free_blocks_count(fs, i) + (numblocks - old_numblocks)); 495 ext2fs_group_desc_csum_set(fs, i); 496 497 /* 498 * If the number of block groups is staying the same, we're 499 * done and can exit now. (If the number block groups is 500 * shrinking, we had exited earlier.) 501 */ 502 if (old_fs->group_desc_count >= fs->group_desc_count) { 503 retval = 0; 504 goto errout; 505 } 506 507 /* 508 * Initialize the new block group descriptors 509 */ 510 group_block = ext2fs_group_first_block2(fs, 511 old_fs->group_desc_count); 512 csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 513 EXT4_FEATURE_RO_COMPAT_GDT_CSUM); 514 if (access("/sys/fs/ext4/features/lazy_itable_init", F_OK) == 0) 515 lazy_itable_init = 1; 516 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) 517 old_desc_blocks = fs->super->s_first_meta_bg; 518 else 519 old_desc_blocks = fs->desc_blocks + 520 fs->super->s_reserved_gdt_blocks; 521 522 /* 523 * If we changed the number of block_group descriptor blocks, 524 * we need to make sure they are all marked as reserved in the 525 * file systems's block allocation map. 526 */ 527 for (i = 0; i < old_fs->group_desc_count; i++) 528 ext2fs_reserve_super_and_bgd(fs, i, fs->block_map); 529 530 for (i = old_fs->group_desc_count; 531 i < fs->group_desc_count; i++) { 532 memset(ext2fs_group_desc(fs, fs->group_desc, i), 0, 533 sizeof(struct ext2_group_desc)); 534 adjblocks = 0; 535 536 ext2fs_bg_flags_zap(fs, i); 537 if (csum_flag) { 538 ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT); 539 if (!lazy_itable_init) 540 ext2fs_bg_flags_set(fs, i, 541 EXT2_BG_INODE_ZEROED); 542 ext2fs_bg_itable_unused_set(fs, i, 543 fs->super->s_inodes_per_group); 544 } 545 546 numblocks = ext2fs_group_blocks_count(fs, i); 547 if ((i < fs->group_desc_count - 1) && csum_flag) 548 ext2fs_bg_flags_set(fs, i, EXT2_BG_BLOCK_UNINIT); 549 550 has_super = ext2fs_bg_has_super(fs, i); 551 if (has_super) { 552 ext2fs_block_alloc_stats2(fs, group_block, +1); 553 adjblocks++; 554 } 555 meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super); 556 meta_bg = i / meta_bg_size; 557 if (!(fs->super->s_feature_incompat & 558 EXT2_FEATURE_INCOMPAT_META_BG) || 559 (meta_bg < fs->super->s_first_meta_bg)) { 560 if (has_super) { 561 for (j=0; j < old_desc_blocks; j++) 562 ext2fs_block_alloc_stats2(fs, 563 group_block + 1 + j, +1); 564 adjblocks += old_desc_blocks; 565 } 566 } else { 567 if (has_super) 568 has_super = 1; 569 if (((i % meta_bg_size) == 0) || 570 ((i % meta_bg_size) == 1) || 571 ((i % meta_bg_size) == (meta_bg_size-1))) 572 ext2fs_block_alloc_stats2(fs, 573 group_block + has_super, +1); 574 } 575 576 adjblocks += 2 + fs->inode_blocks_per_group; 577 578 numblocks -= adjblocks; 579 ext2fs_free_blocks_count_set(fs->super, 580 ext2fs_free_blocks_count(fs->super) - adjblocks); 581 fs->super->s_free_inodes_count += 582 fs->super->s_inodes_per_group; 583 ext2fs_bg_free_blocks_count_set(fs, i, numblocks); 584 ext2fs_bg_free_inodes_count_set(fs, i, 585 fs->super->s_inodes_per_group); 586 ext2fs_bg_used_dirs_count_set(fs, i, 0); 587 ext2fs_group_desc_csum_set(fs, i); 588 589 retval = ext2fs_allocate_group_table(fs, i, 0); 590 if (retval) goto errout; 591 592 group_block += fs->super->s_blocks_per_group; 593 } 594 retval = 0; 595 596 /* 597 * Mark all of the metadata blocks as reserved so they won't 598 * get allocated by the call to ext2fs_allocate_group_table() 599 * in blocks_to_move(), where we allocate new blocks to 600 * replace those allocation bitmap and inode table blocks 601 * which have to get relocated to make space for an increased 602 * number of the block group descriptors. 603 */ 604 if (reserve_blocks) 605 mark_table_blocks(fs, reserve_blocks); 606 607 errout: 608 return (retval); 609 } 610 611 /* 612 * This routine adjusts the superblock and other data structures, both 613 * in disk as well as in memory... 614 */ 615 static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size) 616 { 617 ext2_filsys fs; 618 int adj = 0; 619 errcode_t retval; 620 blk64_t group_block; 621 unsigned long i; 622 unsigned long max_group; 623 624 fs = rfs->new_fs; 625 ext2fs_mark_super_dirty(fs); 626 ext2fs_mark_bb_dirty(fs); 627 ext2fs_mark_ib_dirty(fs); 628 629 retval = ext2fs_allocate_block_bitmap(fs, _("reserved blocks"), 630 &rfs->reserve_blocks); 631 if (retval) 632 return retval; 633 634 retval = adjust_fs_info(fs, rfs->old_fs, rfs->reserve_blocks, new_size); 635 if (retval) 636 goto errout; 637 638 /* 639 * Check to make sure there are enough inodes 640 */ 641 if ((rfs->old_fs->super->s_inodes_count - 642 rfs->old_fs->super->s_free_inodes_count) > 643 rfs->new_fs->super->s_inodes_count) { 644 retval = ENOSPC; 645 goto errout; 646 } 647 648 /* 649 * If we are shrinking the number block groups, we're done and 650 * can exit now. 651 */ 652 if (rfs->old_fs->group_desc_count > fs->group_desc_count) { 653 retval = 0; 654 goto errout; 655 } 656 657 /* 658 * If the number of block groups is staying the same, we're 659 * done and can exit now. (If the number block groups is 660 * shrinking, we had exited earlier.) 661 */ 662 if (rfs->old_fs->group_desc_count >= fs->group_desc_count) { 663 retval = 0; 664 goto errout; 665 } 666 667 /* 668 * If we are using uninit_bg (aka GDT_CSUM) and the kernel 669 * supports lazy inode initialization, we can skip 670 * initializing the inode table. 671 */ 672 if (lazy_itable_init && 673 EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 674 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { 675 retval = 0; 676 goto errout; 677 } 678 679 /* 680 * Initialize the inode table 681 */ 682 retval = ext2fs_get_array(fs->blocksize, fs->inode_blocks_per_group, 683 &rfs->itable_buf); 684 if (retval) 685 goto errout; 686 687 memset(rfs->itable_buf, 0, fs->blocksize * fs->inode_blocks_per_group); 688 group_block = ext2fs_group_first_block2(fs, 689 rfs->old_fs->group_desc_count); 690 adj = rfs->old_fs->group_desc_count; 691 max_group = fs->group_desc_count - adj; 692 if (rfs->progress) { 693 retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS, 694 0, max_group); 695 if (retval) 696 goto errout; 697 } 698 for (i = rfs->old_fs->group_desc_count; 699 i < fs->group_desc_count; i++) { 700 /* 701 * Write out the new inode table 702 */ 703 retval = io_channel_write_blk64(fs->io, 704 ext2fs_inode_table_loc(fs, i), 705 fs->inode_blocks_per_group, 706 rfs->itable_buf); 707 if (retval) goto errout; 708 709 io_channel_flush(fs->io); 710 if (rfs->progress) { 711 retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS, 712 i - adj + 1, max_group); 713 if (retval) 714 goto errout; 715 } 716 group_block += fs->super->s_blocks_per_group; 717 } 718 io_channel_flush(fs->io); 719 retval = 0; 720 721 errout: 722 return retval; 723 } 724 725 /* -------------------------------------------------------------------- 726 * 727 * Resize processing, phase 2. 728 * 729 * In this phase we adjust determine which blocks need to be moved, in 730 * blocks_to_move(). We then copy the blocks to their ultimate new 731 * destinations using block_mover(). Since we are copying blocks to 732 * their new locations, again during this pass we can abort without 733 * any problems. 734 * -------------------------------------------------------------------- 735 */ 736 737 /* 738 * This helper function creates a block bitmap with all of the 739 * filesystem meta-data blocks. 740 */ 741 static errcode_t mark_table_blocks(ext2_filsys fs, 742 ext2fs_block_bitmap bmap) 743 { 744 dgrp_t i; 745 blk64_t blk; 746 747 for (i = 0; i < fs->group_desc_count; i++) { 748 ext2fs_reserve_super_and_bgd(fs, i, bmap); 749 750 /* 751 * Mark the blocks used for the inode table 752 */ 753 blk = ext2fs_inode_table_loc(fs, i); 754 if (blk) 755 ext2fs_mark_block_bitmap_range2(bmap, blk, 756 fs->inode_blocks_per_group); 757 758 /* 759 * Mark block used for the block bitmap 760 */ 761 blk = ext2fs_block_bitmap_loc(fs, i); 762 if (blk) 763 ext2fs_mark_block_bitmap2(bmap, blk); 764 765 /* 766 * Mark block used for the inode bitmap 767 */ 768 blk = ext2fs_inode_bitmap_loc(fs, i); 769 if (blk) 770 ext2fs_mark_block_bitmap2(bmap, blk); 771 } 772 return 0; 773 } 774 775 /* 776 * This function checks to see if a particular block (either a 777 * superblock or a block group descriptor) overlaps with an inode or 778 * block bitmap block, or with the inode table. 779 */ 780 static void mark_fs_metablock(ext2_resize_t rfs, 781 ext2fs_block_bitmap meta_bmap, 782 int group, blk64_t blk) 783 { 784 ext2_filsys fs = rfs->new_fs; 785 786 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 787 ext2fs_block_alloc_stats2(fs, blk, +1); 788 789 /* 790 * Check to see if we overlap with the inode or block bitmap, 791 * or the inode tables. If not, and the block is in use, then 792 * mark it as a block to be moved. 793 */ 794 if (IS_BLOCK_BM(fs, group, blk)) { 795 ext2fs_block_bitmap_loc_set(fs, group, 0); 796 rfs->needed_blocks++; 797 return; 798 } 799 if (IS_INODE_BM(fs, group, blk)) { 800 ext2fs_inode_bitmap_loc_set(fs, group, 0); 801 rfs->needed_blocks++; 802 return; 803 } 804 if (IS_INODE_TB(fs, group, blk)) { 805 ext2fs_inode_table_loc_set(fs, group, 0); 806 rfs->needed_blocks++; 807 return; 808 } 809 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) { 810 dgrp_t i; 811 812 for (i=0; i < rfs->old_fs->group_desc_count; i++) { 813 if (IS_BLOCK_BM(fs, i, blk)) { 814 ext2fs_block_bitmap_loc_set(fs, i, 0); 815 rfs->needed_blocks++; 816 return; 817 } 818 if (IS_INODE_BM(fs, i, blk)) { 819 ext2fs_inode_bitmap_loc_set(fs, i, 0); 820 rfs->needed_blocks++; 821 return; 822 } 823 if (IS_INODE_TB(fs, i, blk)) { 824 ext2fs_inode_table_loc_set(fs, i, 0); 825 rfs->needed_blocks++; 826 return; 827 } 828 } 829 } 830 if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 831 EXT4_FEATURE_RO_COMPAT_GDT_CSUM) && 832 (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT))) { 833 /* 834 * If the block bitmap is uninitialized, which means 835 * nothing other than standard metadata in use. 836 */ 837 return; 838 } else if (ext2fs_test_block_bitmap2(rfs->old_fs->block_map, blk) && 839 !ext2fs_test_block_bitmap2(meta_bmap, blk)) { 840 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk); 841 rfs->needed_blocks++; 842 } 843 } 844 845 846 /* 847 * This routine marks and unmarks reserved blocks in the new block 848 * bitmap. It also determines which blocks need to be moved and 849 * places this information into the move_blocks bitmap. 850 */ 851 static errcode_t blocks_to_move(ext2_resize_t rfs) 852 { 853 int j, has_super; 854 dgrp_t i, max_groups, g; 855 blk64_t blk, group_blk; 856 blk64_t old_blocks, new_blocks; 857 blk64_t new_size; 858 unsigned int meta_bg, meta_bg_size; 859 errcode_t retval; 860 ext2_filsys fs, old_fs; 861 ext2fs_block_bitmap meta_bmap; 862 int flex_bg; 863 864 fs = rfs->new_fs; 865 old_fs = rfs->old_fs; 866 if (ext2fs_blocks_count(old_fs->super) > ext2fs_blocks_count(fs->super)) 867 fs = rfs->old_fs; 868 869 retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"), 870 &rfs->move_blocks); 871 if (retval) 872 return retval; 873 874 retval = ext2fs_allocate_block_bitmap(fs, _("meta-data blocks"), 875 &meta_bmap); 876 if (retval) 877 return retval; 878 879 retval = mark_table_blocks(old_fs, meta_bmap); 880 if (retval) 881 return retval; 882 883 fs = rfs->new_fs; 884 885 /* 886 * If we're shrinking the filesystem, we need to move any 887 * group's metadata blocks (either allocation bitmaps or the 888 * inode table) which are beyond the end of the new 889 * filesystem. 890 */ 891 new_size = ext2fs_blocks_count(fs->super); 892 if (new_size < ext2fs_blocks_count(old_fs->super)) { 893 for (g = 0; g < fs->group_desc_count; g++) { 894 int realloc = 0; 895 /* 896 * ext2fs_allocate_group_table will re-allocate any 897 * metadata blocks whose location is set to zero. 898 */ 899 if (ext2fs_block_bitmap_loc(fs, g) >= new_size) { 900 ext2fs_block_bitmap_loc_set(fs, g, 0); 901 realloc = 1; 902 } 903 if (ext2fs_inode_bitmap_loc(fs, g) >= new_size) { 904 ext2fs_inode_bitmap_loc_set(fs, g, 0); 905 realloc = 1; 906 } 907 if ((ext2fs_inode_table_loc(fs, g) + 908 fs->inode_blocks_per_group) > new_size) { 909 ext2fs_inode_table_loc_set(fs, g, 0); 910 realloc = 1; 911 } 912 913 if (realloc) { 914 retval = ext2fs_allocate_group_table(fs, g, 0); 915 if (retval) 916 return retval; 917 } 918 } 919 } 920 921 /* 922 * If we're shrinking the filesystem, we need to move all of 923 * the blocks that don't fit any more 924 */ 925 for (blk = ext2fs_blocks_count(fs->super); 926 blk < ext2fs_blocks_count(old_fs->super); blk++) { 927 g = ext2fs_group_of_blk2(fs, blk); 928 if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 929 EXT4_FEATURE_RO_COMPAT_GDT_CSUM) && 930 ext2fs_bg_flags_test(old_fs, g, EXT2_BG_BLOCK_UNINIT)) { 931 /* 932 * The block bitmap is uninitialized, so skip 933 * to the next block group. 934 */ 935 blk = ext2fs_group_first_block2(fs, g+1) - 1; 936 continue; 937 } 938 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 939 !ext2fs_test_block_bitmap2(meta_bmap, blk)) { 940 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk); 941 rfs->needed_blocks++; 942 } 943 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 944 } 945 946 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) { 947 old_blocks = old_fs->super->s_first_meta_bg; 948 new_blocks = fs->super->s_first_meta_bg; 949 } else { 950 old_blocks = old_fs->desc_blocks + old_fs->super->s_reserved_gdt_blocks; 951 new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks; 952 } 953 954 if (old_blocks == new_blocks) { 955 retval = 0; 956 goto errout; 957 } 958 959 max_groups = fs->group_desc_count; 960 if (max_groups > old_fs->group_desc_count) 961 max_groups = old_fs->group_desc_count; 962 group_blk = old_fs->super->s_first_data_block; 963 /* 964 * If we're reducing the number of descriptor blocks, this 965 * makes life easy. :-) We just have to mark some extra 966 * blocks as free. 967 */ 968 if (old_blocks > new_blocks) { 969 for (i = 0; i < max_groups; i++) { 970 if (!ext2fs_bg_has_super(fs, i)) { 971 group_blk += fs->super->s_blocks_per_group; 972 continue; 973 } 974 for (blk = group_blk+1+new_blocks; 975 blk < group_blk+1+old_blocks; blk++) { 976 ext2fs_block_alloc_stats2(fs, blk, -1); 977 rfs->needed_blocks--; 978 } 979 group_blk += fs->super->s_blocks_per_group; 980 } 981 retval = 0; 982 goto errout; 983 } 984 /* 985 * If we're increasing the number of descriptor blocks, life 986 * gets interesting.... 987 */ 988 meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super); 989 flex_bg = fs->super->s_feature_incompat & 990 EXT4_FEATURE_INCOMPAT_FLEX_BG; 991 /* first reserve all of the existing fs meta blocks */ 992 for (i = 0; i < max_groups; i++) { 993 has_super = ext2fs_bg_has_super(fs, i); 994 if (has_super) 995 mark_fs_metablock(rfs, meta_bmap, i, group_blk); 996 997 meta_bg = i / meta_bg_size; 998 if (!(fs->super->s_feature_incompat & 999 EXT2_FEATURE_INCOMPAT_META_BG) || 1000 (meta_bg < fs->super->s_first_meta_bg)) { 1001 if (has_super) { 1002 for (blk = group_blk+1; 1003 blk < group_blk + 1 + new_blocks; blk++) 1004 mark_fs_metablock(rfs, meta_bmap, 1005 i, blk); 1006 } 1007 } else { 1008 if (has_super) 1009 has_super = 1; 1010 if (((i % meta_bg_size) == 0) || 1011 ((i % meta_bg_size) == 1) || 1012 ((i % meta_bg_size) == (meta_bg_size-1))) 1013 mark_fs_metablock(rfs, meta_bmap, i, 1014 group_blk + has_super); 1015 } 1016 1017 /* 1018 * Reserve the existing meta blocks that we know 1019 * aren't to be moved. 1020 * 1021 * For flex_bg file systems, in order to avoid 1022 * overwriting fs metadata (especially inode table 1023 * blocks) belonging to a different block group when 1024 * we are relocating the inode tables, we need to 1025 * reserve all existing fs metadata blocks. 1026 */ 1027 if (ext2fs_block_bitmap_loc(fs, i)) 1028 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1029 ext2fs_block_bitmap_loc(fs, i)); 1030 else if (flex_bg && i < old_fs->group_desc_count) 1031 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1032 ext2fs_block_bitmap_loc(old_fs, i)); 1033 1034 if (ext2fs_inode_bitmap_loc(fs, i)) 1035 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1036 ext2fs_inode_bitmap_loc(fs, i)); 1037 else if (flex_bg && i < old_fs->group_desc_count) 1038 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1039 ext2fs_inode_bitmap_loc(old_fs, i)); 1040 1041 if (ext2fs_inode_table_loc(fs, i)) 1042 ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks, 1043 ext2fs_inode_table_loc(fs, i), 1044 fs->inode_blocks_per_group); 1045 else if (flex_bg && i < old_fs->group_desc_count) 1046 ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks, 1047 ext2fs_inode_table_loc(old_fs, i), 1048 old_fs->inode_blocks_per_group); 1049 1050 group_blk += rfs->new_fs->super->s_blocks_per_group; 1051 } 1052 1053 /* Allocate the missing data structures */ 1054 for (i = 0; i < max_groups; i++) { 1055 if (ext2fs_inode_table_loc(fs, i) && 1056 ext2fs_inode_bitmap_loc(fs, i) && 1057 ext2fs_block_bitmap_loc(fs, i)) 1058 continue; 1059 1060 retval = ext2fs_allocate_group_table(fs, i, 1061 rfs->reserve_blocks); 1062 if (retval) 1063 goto errout; 1064 1065 /* 1066 * For those structures that have changed, we need to 1067 * do bookkeepping. 1068 */ 1069 if (ext2fs_block_bitmap_loc(old_fs, i) != 1070 (blk = ext2fs_block_bitmap_loc(fs, i))) { 1071 ext2fs_block_alloc_stats2(fs, blk, +1); 1072 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1073 !ext2fs_test_block_bitmap2(meta_bmap, blk)) 1074 ext2fs_mark_block_bitmap2(rfs->move_blocks, 1075 blk); 1076 } 1077 if (ext2fs_inode_bitmap_loc(old_fs, i) != 1078 (blk = ext2fs_inode_bitmap_loc(fs, i))) { 1079 ext2fs_block_alloc_stats2(fs, blk, +1); 1080 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1081 !ext2fs_test_block_bitmap2(meta_bmap, blk)) 1082 ext2fs_mark_block_bitmap2(rfs->move_blocks, 1083 blk); 1084 } 1085 1086 /* 1087 * The inode table, if we need to relocate it, is 1088 * handled specially. We have to reserve the blocks 1089 * for both the old and the new inode table, since we 1090 * can't have the inode table be destroyed during the 1091 * block relocation phase. 1092 */ 1093 if (ext2fs_inode_table_loc(fs, i) == ext2fs_inode_table_loc(old_fs, i)) 1094 continue; /* inode table not moved */ 1095 1096 rfs->needed_blocks += fs->inode_blocks_per_group; 1097 1098 /* 1099 * Mark the new inode table as in use in the new block 1100 * allocation bitmap, and move any blocks that might 1101 * be necessary. 1102 */ 1103 for (blk = ext2fs_inode_table_loc(fs, i), j=0; 1104 j < fs->inode_blocks_per_group ; j++, blk++) { 1105 ext2fs_block_alloc_stats2(fs, blk, +1); 1106 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1107 !ext2fs_test_block_bitmap2(meta_bmap, blk)) 1108 ext2fs_mark_block_bitmap2(rfs->move_blocks, 1109 blk); 1110 } 1111 1112 /* 1113 * Make sure the old inode table is reserved in the 1114 * block reservation bitmap. 1115 */ 1116 for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0; 1117 j < fs->inode_blocks_per_group ; j++, blk++) 1118 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 1119 } 1120 retval = 0; 1121 1122 errout: 1123 if (meta_bmap) 1124 ext2fs_free_block_bitmap(meta_bmap); 1125 1126 return retval; 1127 } 1128 1129 /* 1130 * This helper function tries to allocate a new block. We try to 1131 * avoid hitting the original group descriptor blocks at least at 1132 * first, since we want to make it possible to recover from a badly 1133 * aborted resize operation as much as possible. 1134 * 1135 * In the future, I may further modify this routine to balance out 1136 * where we get the new blocks across the various block groups. 1137 * Ideally we would allocate blocks that corresponded with the block 1138 * group of the containing inode, and keep contiguous blocks 1139 * together. However, this very difficult to do efficiently, since we 1140 * don't have the necessary information up front. 1141 */ 1142 1143 #define AVOID_OLD 1 1144 #define DESPERATION 2 1145 1146 static void init_block_alloc(ext2_resize_t rfs) 1147 { 1148 rfs->alloc_state = AVOID_OLD; 1149 rfs->new_blk = rfs->new_fs->super->s_first_data_block; 1150 #if 0 1151 /* HACK for testing */ 1152 if (ext2fs_blocks_count(rfs->new_fs->super) > 1153 ext2fs_blocks_count(rfs->old_fs->super)) 1154 rfs->new_blk = ext2fs_blocks_count(rfs->old_fs->super); 1155 #endif 1156 } 1157 1158 static blk64_t get_new_block(ext2_resize_t rfs) 1159 { 1160 ext2_filsys fs = rfs->new_fs; 1161 1162 while (1) { 1163 if (rfs->new_blk >= ext2fs_blocks_count(fs->super)) { 1164 if (rfs->alloc_state == DESPERATION) 1165 return 0; 1166 1167 #ifdef RESIZE2FS_DEBUG 1168 if (rfs->flags & RESIZE_DEBUG_BMOVE) 1169 printf("Going into desperation mode " 1170 "for block allocations\n"); 1171 #endif 1172 rfs->alloc_state = DESPERATION; 1173 rfs->new_blk = fs->super->s_first_data_block; 1174 continue; 1175 } 1176 if (ext2fs_test_block_bitmap2(fs->block_map, rfs->new_blk) || 1177 ext2fs_test_block_bitmap2(rfs->reserve_blocks, 1178 rfs->new_blk) || 1179 ((rfs->alloc_state == AVOID_OLD) && 1180 (rfs->new_blk < ext2fs_blocks_count(rfs->old_fs->super)) && 1181 ext2fs_test_block_bitmap2(rfs->old_fs->block_map, 1182 rfs->new_blk))) { 1183 rfs->new_blk++; 1184 continue; 1185 } 1186 return rfs->new_blk; 1187 } 1188 } 1189 1190 static errcode_t resize2fs_get_alloc_block(ext2_filsys fs, blk64_t goal, 1191 blk64_t *ret) 1192 { 1193 ext2_resize_t rfs = (ext2_resize_t) fs->priv_data; 1194 blk64_t blk; 1195 1196 blk = get_new_block(rfs); 1197 if (!blk) 1198 return ENOSPC; 1199 1200 #ifdef RESIZE2FS_DEBUG 1201 if (rfs->flags & 0xF) 1202 printf("get_alloc_block allocating %llu\n", blk); 1203 #endif 1204 1205 ext2fs_mark_block_bitmap2(rfs->old_fs->block_map, blk); 1206 ext2fs_mark_block_bitmap2(rfs->new_fs->block_map, blk); 1207 *ret = (blk64_t) blk; 1208 return 0; 1209 } 1210 1211 static errcode_t block_mover(ext2_resize_t rfs) 1212 { 1213 blk64_t blk, old_blk, new_blk; 1214 ext2_filsys fs = rfs->new_fs; 1215 ext2_filsys old_fs = rfs->old_fs; 1216 errcode_t retval; 1217 __u64 size; 1218 int c; 1219 int to_move, moved; 1220 ext2_badblocks_list badblock_list = 0; 1221 int bb_modified = 0; 1222 1223 fs->get_alloc_block = resize2fs_get_alloc_block; 1224 old_fs->get_alloc_block = resize2fs_get_alloc_block; 1225 1226 retval = ext2fs_read_bb_inode(old_fs, &badblock_list); 1227 if (retval) 1228 return retval; 1229 1230 new_blk = fs->super->s_first_data_block; 1231 if (!rfs->itable_buf) { 1232 retval = ext2fs_get_array(fs->blocksize, 1233 fs->inode_blocks_per_group, 1234 &rfs->itable_buf); 1235 if (retval) 1236 return retval; 1237 } 1238 retval = ext2fs_create_extent_table(&rfs->bmap, 0); 1239 if (retval) 1240 return retval; 1241 1242 /* 1243 * The first step is to figure out where all of the blocks 1244 * will go. 1245 */ 1246 to_move = moved = 0; 1247 init_block_alloc(rfs); 1248 for (blk = B2C(old_fs->super->s_first_data_block); 1249 blk < ext2fs_blocks_count(old_fs->super); 1250 blk += EXT2FS_CLUSTER_RATIO(fs)) { 1251 if (!ext2fs_test_block_bitmap2(old_fs->block_map, blk)) 1252 continue; 1253 if (!ext2fs_test_block_bitmap2(rfs->move_blocks, blk)) 1254 continue; 1255 if (ext2fs_badblocks_list_test(badblock_list, blk)) { 1256 ext2fs_badblocks_list_del(badblock_list, blk); 1257 bb_modified++; 1258 continue; 1259 } 1260 1261 new_blk = get_new_block(rfs); 1262 if (!new_blk) { 1263 retval = ENOSPC; 1264 goto errout; 1265 } 1266 ext2fs_block_alloc_stats2(fs, new_blk, +1); 1267 ext2fs_add_extent_entry(rfs->bmap, B2C(blk), B2C(new_blk)); 1268 to_move++; 1269 } 1270 1271 if (to_move == 0) { 1272 if (rfs->bmap) { 1273 ext2fs_free_extent_table(rfs->bmap); 1274 rfs->bmap = 0; 1275 } 1276 retval = 0; 1277 goto errout; 1278 } 1279 1280 /* 1281 * Step two is to actually move the blocks 1282 */ 1283 retval = ext2fs_iterate_extent(rfs->bmap, 0, 0, 0); 1284 if (retval) goto errout; 1285 1286 if (rfs->progress) { 1287 retval = (rfs->progress)(rfs, E2_RSZ_BLOCK_RELOC_PASS, 1288 0, to_move); 1289 if (retval) 1290 goto errout; 1291 } 1292 while (1) { 1293 retval = ext2fs_iterate_extent(rfs->bmap, &old_blk, &new_blk, &size); 1294 if (retval) goto errout; 1295 if (!size) 1296 break; 1297 old_blk = C2B(old_blk); 1298 new_blk = C2B(new_blk); 1299 size = C2B(size); 1300 #ifdef RESIZE2FS_DEBUG 1301 if (rfs->flags & RESIZE_DEBUG_BMOVE) 1302 printf("Moving %llu blocks %llu->%llu\n", 1303 size, old_blk, new_blk); 1304 #endif 1305 do { 1306 c = size; 1307 if (c > fs->inode_blocks_per_group) 1308 c = fs->inode_blocks_per_group; 1309 retval = io_channel_read_blk64(fs->io, old_blk, c, 1310 rfs->itable_buf); 1311 if (retval) goto errout; 1312 retval = io_channel_write_blk64(fs->io, new_blk, c, 1313 rfs->itable_buf); 1314 if (retval) goto errout; 1315 size -= c; 1316 new_blk += c; 1317 old_blk += c; 1318 moved += c; 1319 if (rfs->progress) { 1320 io_channel_flush(fs->io); 1321 retval = (rfs->progress)(rfs, 1322 E2_RSZ_BLOCK_RELOC_PASS, 1323 moved, to_move); 1324 if (retval) 1325 goto errout; 1326 } 1327 } while (size > 0); 1328 io_channel_flush(fs->io); 1329 } 1330 1331 errout: 1332 if (badblock_list) { 1333 if (!retval && bb_modified) 1334 retval = ext2fs_update_bb_inode(old_fs, 1335 badblock_list); 1336 ext2fs_badblocks_list_free(badblock_list); 1337 } 1338 return retval; 1339 } 1340 1341 1342 /* -------------------------------------------------------------------- 1343 * 1344 * Resize processing, phase 3 1345 * 1346 * -------------------------------------------------------------------- 1347 */ 1348 1349 1350 /* 1351 * The extent translation table is stored in clusters so we need to 1352 * take special care when mapping a source block number to its 1353 * destination block number. 1354 */ 1355 static __u64 extent_translate(ext2_filsys fs, ext2_extent extent, __u64 old_loc) 1356 { 1357 __u64 new_block = C2B(ext2fs_extent_translate(extent, B2C(old_loc))); 1358 1359 if (new_block != 0) 1360 new_block += old_loc & (EXT2FS_CLUSTER_RATIO(fs) - 1); 1361 return new_block; 1362 } 1363 1364 struct process_block_struct { 1365 ext2_resize_t rfs; 1366 ext2_ino_t ino; 1367 struct ext2_inode * inode; 1368 errcode_t error; 1369 int is_dir; 1370 int changed; 1371 }; 1372 1373 static int process_block(ext2_filsys fs, blk64_t *block_nr, 1374 e2_blkcnt_t blockcnt, 1375 blk64_t ref_block EXT2FS_ATTR((unused)), 1376 int ref_offset EXT2FS_ATTR((unused)), void *priv_data) 1377 { 1378 struct process_block_struct *pb; 1379 errcode_t retval; 1380 blk64_t block, new_block; 1381 int ret = 0; 1382 1383 pb = (struct process_block_struct *) priv_data; 1384 block = *block_nr; 1385 if (pb->rfs->bmap) { 1386 new_block = extent_translate(fs, pb->rfs->bmap, block); 1387 if (new_block) { 1388 *block_nr = new_block; 1389 ret |= BLOCK_CHANGED; 1390 pb->changed = 1; 1391 #ifdef RESIZE2FS_DEBUG 1392 if (pb->rfs->flags & RESIZE_DEBUG_BMOVE) 1393 printf("ino=%u, blockcnt=%lld, %llu->%llu\n", 1394 pb->ino, blockcnt, block, new_block); 1395 #endif 1396 block = new_block; 1397 } 1398 } 1399 if (pb->is_dir) { 1400 retval = ext2fs_add_dir_block2(fs->dblist, pb->ino, 1401 block, (int) blockcnt); 1402 if (retval) { 1403 pb->error = retval; 1404 ret |= BLOCK_ABORT; 1405 } 1406 } 1407 return ret; 1408 } 1409 1410 /* 1411 * Progress callback 1412 */ 1413 static errcode_t progress_callback(ext2_filsys fs, 1414 ext2_inode_scan scan EXT2FS_ATTR((unused)), 1415 dgrp_t group, void * priv_data) 1416 { 1417 ext2_resize_t rfs = (ext2_resize_t) priv_data; 1418 errcode_t retval; 1419 1420 /* 1421 * This check is to protect against old ext2 libraries. It 1422 * shouldn't be needed against new libraries. 1423 */ 1424 if ((group+1) == 0) 1425 return 0; 1426 1427 if (rfs->progress) { 1428 io_channel_flush(fs->io); 1429 retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS, 1430 group+1, fs->group_desc_count); 1431 if (retval) 1432 return retval; 1433 } 1434 1435 return 0; 1436 } 1437 1438 static errcode_t inode_scan_and_fix(ext2_resize_t rfs) 1439 { 1440 struct process_block_struct pb; 1441 ext2_ino_t ino, new_inode; 1442 struct ext2_inode *inode = NULL; 1443 ext2_inode_scan scan = NULL; 1444 errcode_t retval; 1445 char *block_buf = 0; 1446 ext2_ino_t start_to_move; 1447 blk64_t orig_size; 1448 blk64_t new_block; 1449 int inode_size; 1450 1451 if ((rfs->old_fs->group_desc_count <= 1452 rfs->new_fs->group_desc_count) && 1453 !rfs->bmap) 1454 return 0; 1455 1456 /* 1457 * Save the original size of the old filesystem, and 1458 * temporarily set the size to be the new size if the new size 1459 * is larger. We need to do this to avoid catching an error 1460 * by the block iterator routines 1461 */ 1462 orig_size = ext2fs_blocks_count(rfs->old_fs->super); 1463 if (orig_size < ext2fs_blocks_count(rfs->new_fs->super)) 1464 ext2fs_blocks_count_set(rfs->old_fs->super, 1465 ext2fs_blocks_count(rfs->new_fs->super)); 1466 1467 retval = ext2fs_open_inode_scan(rfs->old_fs, 0, &scan); 1468 if (retval) goto errout; 1469 1470 retval = ext2fs_init_dblist(rfs->old_fs, 0); 1471 if (retval) goto errout; 1472 retval = ext2fs_get_array(rfs->old_fs->blocksize, 3, &block_buf); 1473 if (retval) goto errout; 1474 1475 start_to_move = (rfs->new_fs->group_desc_count * 1476 rfs->new_fs->super->s_inodes_per_group); 1477 1478 if (rfs->progress) { 1479 retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS, 1480 0, rfs->old_fs->group_desc_count); 1481 if (retval) 1482 goto errout; 1483 } 1484 ext2fs_set_inode_callback(scan, progress_callback, (void *) rfs); 1485 pb.rfs = rfs; 1486 pb.inode = inode; 1487 pb.error = 0; 1488 new_inode = EXT2_FIRST_INODE(rfs->new_fs->super); 1489 inode_size = EXT2_INODE_SIZE(rfs->new_fs->super); 1490 inode = malloc(inode_size); 1491 if (!inode) { 1492 retval = ENOMEM; 1493 goto errout; 1494 } 1495 /* 1496 * First, copy all of the inodes that need to be moved 1497 * elsewhere in the inode table 1498 */ 1499 while (1) { 1500 retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size); 1501 if (retval) goto errout; 1502 if (!ino) 1503 break; 1504 1505 if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO) 1506 continue; /* inode not in use */ 1507 1508 pb.is_dir = LINUX_S_ISDIR(inode->i_mode); 1509 pb.changed = 0; 1510 1511 if (ext2fs_file_acl_block(rfs->old_fs, inode) && rfs->bmap) { 1512 new_block = extent_translate(rfs->old_fs, rfs->bmap, 1513 ext2fs_file_acl_block(rfs->old_fs, inode)); 1514 if (new_block) { 1515 ext2fs_file_acl_block_set(rfs->old_fs, inode, 1516 new_block); 1517 retval = ext2fs_write_inode_full(rfs->old_fs, 1518 ino, inode, inode_size); 1519 if (retval) goto errout; 1520 } 1521 } 1522 1523 if (ext2fs_inode_has_valid_blocks2(rfs->old_fs, inode) && 1524 (rfs->bmap || pb.is_dir)) { 1525 pb.ino = ino; 1526 retval = ext2fs_block_iterate3(rfs->old_fs, 1527 ino, 0, block_buf, 1528 process_block, &pb); 1529 if (retval) 1530 goto errout; 1531 if (pb.error) { 1532 retval = pb.error; 1533 goto errout; 1534 } 1535 } 1536 1537 if (ino <= start_to_move) 1538 continue; /* Don't need to move it. */ 1539 1540 /* 1541 * Find a new inode 1542 */ 1543 retval = ext2fs_new_inode(rfs->new_fs, 0, 0, 0, &new_inode); 1544 if (retval) 1545 goto errout; 1546 1547 ext2fs_inode_alloc_stats2(rfs->new_fs, new_inode, +1, 1548 pb.is_dir); 1549 if (pb.changed) { 1550 /* Get the new version of the inode */ 1551 retval = ext2fs_read_inode_full(rfs->old_fs, ino, 1552 inode, inode_size); 1553 if (retval) goto errout; 1554 } 1555 inode->i_ctime = time(0); 1556 retval = ext2fs_write_inode_full(rfs->old_fs, new_inode, 1557 inode, inode_size); 1558 if (retval) goto errout; 1559 1560 #ifdef RESIZE2FS_DEBUG 1561 if (rfs->flags & RESIZE_DEBUG_INODEMAP) 1562 printf("Inode moved %u->%u\n", ino, new_inode); 1563 #endif 1564 if (!rfs->imap) { 1565 retval = ext2fs_create_extent_table(&rfs->imap, 0); 1566 if (retval) 1567 goto errout; 1568 } 1569 ext2fs_add_extent_entry(rfs->imap, ino, new_inode); 1570 } 1571 io_channel_flush(rfs->old_fs->io); 1572 1573 errout: 1574 ext2fs_blocks_count_set(rfs->old_fs->super, orig_size); 1575 if (rfs->bmap) { 1576 ext2fs_free_extent_table(rfs->bmap); 1577 rfs->bmap = 0; 1578 } 1579 if (scan) 1580 ext2fs_close_inode_scan(scan); 1581 if (block_buf) 1582 ext2fs_free_mem(&block_buf); 1583 free(inode); 1584 return retval; 1585 } 1586 1587 /* -------------------------------------------------------------------- 1588 * 1589 * Resize processing, phase 4. 1590 * 1591 * -------------------------------------------------------------------- 1592 */ 1593 1594 struct istruct { 1595 ext2_resize_t rfs; 1596 errcode_t err; 1597 unsigned int max_dirs; 1598 unsigned int num; 1599 }; 1600 1601 static int check_and_change_inodes(ext2_ino_t dir, 1602 int entry EXT2FS_ATTR((unused)), 1603 struct ext2_dir_entry *dirent, int offset, 1604 int blocksize EXT2FS_ATTR((unused)), 1605 char *buf EXT2FS_ATTR((unused)), 1606 void *priv_data) 1607 { 1608 struct istruct *is = (struct istruct *) priv_data; 1609 struct ext2_inode inode; 1610 ext2_ino_t new_inode; 1611 errcode_t retval; 1612 1613 if (is->rfs->progress && offset == 0) { 1614 io_channel_flush(is->rfs->old_fs->io); 1615 is->err = (is->rfs->progress)(is->rfs, 1616 E2_RSZ_INODE_REF_UPD_PASS, 1617 ++is->num, is->max_dirs); 1618 if (is->err) 1619 return DIRENT_ABORT; 1620 } 1621 1622 if (!dirent->inode) 1623 return 0; 1624 1625 new_inode = ext2fs_extent_translate(is->rfs->imap, dirent->inode); 1626 1627 if (!new_inode) 1628 return 0; 1629 #ifdef RESIZE2FS_DEBUG 1630 if (is->rfs->flags & RESIZE_DEBUG_INODEMAP) 1631 printf("Inode translate (dir=%u, name=%.*s, %u->%u)\n", 1632 dir, dirent->name_len&0xFF, dirent->name, 1633 dirent->inode, new_inode); 1634 #endif 1635 1636 dirent->inode = new_inode; 1637 1638 /* Update the directory mtime and ctime */ 1639 retval = ext2fs_read_inode(is->rfs->old_fs, dir, &inode); 1640 if (retval == 0) { 1641 inode.i_mtime = inode.i_ctime = time(0); 1642 is->err = ext2fs_write_inode(is->rfs->old_fs, dir, &inode); 1643 if (is->err) 1644 return DIRENT_ABORT; 1645 } 1646 1647 return DIRENT_CHANGED; 1648 } 1649 1650 static errcode_t inode_ref_fix(ext2_resize_t rfs) 1651 { 1652 errcode_t retval; 1653 struct istruct is; 1654 1655 if (!rfs->imap) 1656 return 0; 1657 1658 /* 1659 * Now, we iterate over all of the directories to update the 1660 * inode references 1661 */ 1662 is.num = 0; 1663 is.max_dirs = ext2fs_dblist_count2(rfs->old_fs->dblist); 1664 is.rfs = rfs; 1665 is.err = 0; 1666 1667 if (rfs->progress) { 1668 retval = (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS, 1669 0, is.max_dirs); 1670 if (retval) 1671 goto errout; 1672 } 1673 1674 retval = ext2fs_dblist_dir_iterate(rfs->old_fs->dblist, 1675 DIRENT_FLAG_INCLUDE_EMPTY, 0, 1676 check_and_change_inodes, &is); 1677 if (retval) 1678 goto errout; 1679 if (is.err) { 1680 retval = is.err; 1681 goto errout; 1682 } 1683 1684 if (rfs->progress && (is.num < is.max_dirs)) 1685 (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS, 1686 is.max_dirs, is.max_dirs); 1687 1688 errout: 1689 ext2fs_free_extent_table(rfs->imap); 1690 rfs->imap = 0; 1691 return retval; 1692 } 1693 1694 1695 /* -------------------------------------------------------------------- 1696 * 1697 * Resize processing, phase 5. 1698 * 1699 * In this phase we actually move the inode table around, and then 1700 * update the summary statistics. This is scary, since aborting here 1701 * will potentially scramble the filesystem. (We are moving the 1702 * inode tables around in place, and so the potential for lost data, 1703 * or at the very least scrambling the mapping between filenames and 1704 * inode numbers is very high in case of a power failure here.) 1705 * -------------------------------------------------------------------- 1706 */ 1707 1708 1709 /* 1710 * A very scary routine --- this one moves the inode table around!!! 1711 * 1712 * After this you have to use the rfs->new_fs file handle to read and 1713 * write inodes. 1714 */ 1715 static errcode_t move_itables(ext2_resize_t rfs) 1716 { 1717 int n, num, size; 1718 long long diff; 1719 dgrp_t i, max_groups; 1720 ext2_filsys fs = rfs->new_fs; 1721 char *cp; 1722 blk64_t old_blk, new_blk, blk; 1723 errcode_t retval; 1724 int j, to_move, moved; 1725 1726 max_groups = fs->group_desc_count; 1727 if (max_groups > rfs->old_fs->group_desc_count) 1728 max_groups = rfs->old_fs->group_desc_count; 1729 1730 size = fs->blocksize * fs->inode_blocks_per_group; 1731 if (!rfs->itable_buf) { 1732 retval = ext2fs_get_mem(size, &rfs->itable_buf); 1733 if (retval) 1734 return retval; 1735 } 1736 1737 /* 1738 * Figure out how many inode tables we need to move 1739 */ 1740 to_move = moved = 0; 1741 for (i=0; i < max_groups; i++) 1742 if (ext2fs_inode_table_loc(rfs->old_fs, i) != 1743 ext2fs_inode_table_loc(fs, i)) 1744 to_move++; 1745 1746 if (to_move == 0) 1747 return 0; 1748 1749 if (rfs->progress) { 1750 retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS, 1751 0, to_move); 1752 if (retval) 1753 goto errout; 1754 } 1755 1756 rfs->old_fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; 1757 1758 for (i=0; i < max_groups; i++) { 1759 old_blk = ext2fs_inode_table_loc(rfs->old_fs, i); 1760 new_blk = ext2fs_inode_table_loc(fs, i); 1761 diff = new_blk - old_blk; 1762 1763 #ifdef RESIZE2FS_DEBUG 1764 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 1765 printf("Itable move group %d block %llu->%llu (diff %lld)\n", 1766 i, old_blk, new_blk, diff); 1767 #endif 1768 1769 if (!diff) 1770 continue; 1771 1772 retval = io_channel_read_blk64(fs->io, old_blk, 1773 fs->inode_blocks_per_group, 1774 rfs->itable_buf); 1775 if (retval) 1776 goto errout; 1777 /* 1778 * The end of the inode table segment often contains 1779 * all zeros, and we're often only moving the inode 1780 * table down a block or two. If so, we can optimize 1781 * things by not rewriting blocks that we know to be zero 1782 * already. 1783 */ 1784 for (cp = rfs->itable_buf+size-1, n=0; n < size; n++, cp--) 1785 if (*cp) 1786 break; 1787 n = n >> EXT2_BLOCK_SIZE_BITS(fs->super); 1788 #ifdef RESIZE2FS_DEBUG 1789 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 1790 printf("%d blocks of zeros...\n", n); 1791 #endif 1792 num = fs->inode_blocks_per_group; 1793 if (n > diff) 1794 num -= n; 1795 1796 retval = io_channel_write_blk64(fs->io, new_blk, 1797 num, rfs->itable_buf); 1798 if (retval) { 1799 io_channel_write_blk64(fs->io, old_blk, 1800 num, rfs->itable_buf); 1801 goto errout; 1802 } 1803 if (n > diff) { 1804 retval = io_channel_write_blk64(fs->io, 1805 old_blk + fs->inode_blocks_per_group, 1806 diff, (rfs->itable_buf + 1807 (fs->inode_blocks_per_group - diff) * 1808 fs->blocksize)); 1809 if (retval) 1810 goto errout; 1811 } 1812 1813 for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0; 1814 j < fs->inode_blocks_per_group ; j++, blk++) 1815 ext2fs_block_alloc_stats2(fs, blk, -1); 1816 1817 ext2fs_inode_table_loc_set(rfs->old_fs, i, new_blk); 1818 ext2fs_group_desc_csum_set(rfs->old_fs, i); 1819 ext2fs_mark_super_dirty(rfs->old_fs); 1820 ext2fs_flush(rfs->old_fs); 1821 1822 if (rfs->progress) { 1823 retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS, 1824 ++moved, to_move); 1825 if (retval) 1826 goto errout; 1827 } 1828 } 1829 mark_table_blocks(fs, fs->block_map); 1830 ext2fs_flush(fs); 1831 #ifdef RESIZE2FS_DEBUG 1832 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 1833 printf("Inode table move finished.\n"); 1834 #endif 1835 return 0; 1836 1837 errout: 1838 return retval; 1839 } 1840 1841 /* 1842 * Fix the resize inode 1843 */ 1844 static errcode_t fix_resize_inode(ext2_filsys fs) 1845 { 1846 struct ext2_inode inode; 1847 errcode_t retval; 1848 char *block_buf = NULL; 1849 1850 if (!(fs->super->s_feature_compat & 1851 EXT2_FEATURE_COMPAT_RESIZE_INODE)) 1852 return 0; 1853 1854 retval = ext2fs_get_mem(fs->blocksize, &block_buf); 1855 if (retval) goto errout; 1856 1857 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode); 1858 if (retval) goto errout; 1859 1860 ext2fs_iblk_set(fs, &inode, 1); 1861 1862 retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode); 1863 if (retval) goto errout; 1864 1865 if (!inode.i_block[EXT2_DIND_BLOCK]) { 1866 /* 1867 * Avoid zeroing out block #0; that's rude. This 1868 * should never happen anyway since the filesystem 1869 * should be fsck'ed and we assume it is consistent. 1870 */ 1871 fprintf(stderr, "%s", 1872 _("Should never happen: resize inode corrupt!\n")); 1873 exit(1); 1874 } 1875 1876 memset(block_buf, 0, fs->blocksize); 1877 1878 retval = io_channel_write_blk64(fs->io, inode.i_block[EXT2_DIND_BLOCK], 1879 1, block_buf); 1880 if (retval) goto errout; 1881 1882 retval = ext2fs_create_resize_inode(fs); 1883 if (retval) 1884 goto errout; 1885 1886 errout: 1887 if (block_buf) 1888 ext2fs_free_mem(&block_buf); 1889 return retval; 1890 } 1891 1892 /* 1893 * Finally, recalculate the summary information 1894 */ 1895 static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs) 1896 { 1897 blk64_t blk; 1898 ext2_ino_t ino; 1899 unsigned int group = 0; 1900 unsigned int count = 0; 1901 blk64_t total_blocks_free = 0; 1902 int total_inodes_free = 0; 1903 int group_free = 0; 1904 int uninit = 0; 1905 blk64_t super_blk, old_desc_blk, new_desc_blk; 1906 int old_desc_blocks; 1907 1908 /* 1909 * First calculate the block statistics 1910 */ 1911 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT); 1912 ext2fs_super_and_bgd_loc2(fs, group, &super_blk, &old_desc_blk, 1913 &new_desc_blk, 0); 1914 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) 1915 old_desc_blocks = fs->super->s_first_meta_bg; 1916 else 1917 old_desc_blocks = fs->desc_blocks + 1918 fs->super->s_reserved_gdt_blocks; 1919 for (blk = B2C(fs->super->s_first_data_block); 1920 blk < ext2fs_blocks_count(fs->super); 1921 blk += EXT2FS_CLUSTER_RATIO(fs)) { 1922 if ((uninit && 1923 !(EQ_CLSTR(blk, super_blk) || 1924 ((old_desc_blk && old_desc_blocks && 1925 GE_CLSTR(blk, old_desc_blk) && 1926 LT_CLSTR(blk, old_desc_blk + old_desc_blocks))) || 1927 ((new_desc_blk && EQ_CLSTR(blk, new_desc_blk))) || 1928 EQ_CLSTR(blk, ext2fs_block_bitmap_loc(fs, group)) || 1929 EQ_CLSTR(blk, ext2fs_inode_bitmap_loc(fs, group)) || 1930 ((GE_CLSTR(blk, ext2fs_inode_table_loc(fs, group)) && 1931 LT_CLSTR(blk, ext2fs_inode_table_loc(fs, group) 1932 + fs->inode_blocks_per_group))))) || 1933 (!ext2fs_fast_test_block_bitmap2(fs->block_map, blk))) { 1934 group_free++; 1935 total_blocks_free++; 1936 } 1937 count++; 1938 if ((count == fs->super->s_clusters_per_group) || 1939 EQ_CLSTR(blk, ext2fs_blocks_count(fs->super)-1)) { 1940 ext2fs_bg_free_blocks_count_set(fs, group, group_free); 1941 ext2fs_group_desc_csum_set(fs, group); 1942 group++; 1943 if (group >= fs->group_desc_count) 1944 break; 1945 count = 0; 1946 group_free = 0; 1947 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT); 1948 ext2fs_super_and_bgd_loc2(fs, group, &super_blk, 1949 &old_desc_blk, 1950 &new_desc_blk, 0); 1951 if (fs->super->s_feature_incompat & 1952 EXT2_FEATURE_INCOMPAT_META_BG) 1953 old_desc_blocks = fs->super->s_first_meta_bg; 1954 else 1955 old_desc_blocks = fs->desc_blocks + 1956 fs->super->s_reserved_gdt_blocks; 1957 } 1958 } 1959 total_blocks_free = C2B(total_blocks_free); 1960 ext2fs_free_blocks_count_set(fs->super, total_blocks_free); 1961 1962 /* 1963 * Next, calculate the inode statistics 1964 */ 1965 group_free = 0; 1966 count = 0; 1967 group = 0; 1968 1969 /* Protect loop from wrap-around if s_inodes_count maxed */ 1970 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT); 1971 for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) { 1972 if (uninit || 1973 !ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino)) { 1974 group_free++; 1975 total_inodes_free++; 1976 } 1977 count++; 1978 if ((count == fs->super->s_inodes_per_group) || 1979 (ino == fs->super->s_inodes_count)) { 1980 ext2fs_bg_free_inodes_count_set(fs, group, group_free); 1981 ext2fs_group_desc_csum_set(fs, group); 1982 group++; 1983 if (group >= fs->group_desc_count) 1984 break; 1985 count = 0; 1986 group_free = 0; 1987 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT); 1988 } 1989 } 1990 fs->super->s_free_inodes_count = total_inodes_free; 1991 ext2fs_mark_super_dirty(fs); 1992 return 0; 1993 } 1994 1995 /* 1996 * Journal may have been relocated; update the backup journal blocks 1997 * in the superblock. 1998 */ 1999 static errcode_t fix_sb_journal_backup(ext2_filsys fs) 2000 { 2001 errcode_t retval; 2002 struct ext2_inode inode; 2003 2004 if (!(fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) 2005 return 0; 2006 2007 /* External journal? Nothing to do. */ 2008 if (fs->super->s_journal_dev && !fs->super->s_journal_inum) 2009 return 0; 2010 2011 retval = ext2fs_read_inode(fs, fs->super->s_journal_inum, &inode); 2012 if (retval) 2013 return retval; 2014 memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4); 2015 fs->super->s_jnl_blocks[15] = inode.i_size_high; 2016 fs->super->s_jnl_blocks[16] = inode.i_size; 2017 fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS; 2018 ext2fs_mark_super_dirty(fs); 2019 return 0; 2020 } 2021 2022 static int calc_group_overhead(ext2_filsys fs, blk64_t grp, 2023 int old_desc_blocks) 2024 { 2025 blk64_t super_blk, old_desc_blk, new_desc_blk; 2026 int overhead; 2027 2028 /* inode table blocks plus allocation bitmaps */ 2029 overhead = fs->inode_blocks_per_group + 2; 2030 2031 ext2fs_super_and_bgd_loc2(fs, grp, &super_blk, 2032 &old_desc_blk, &new_desc_blk, 0); 2033 if ((grp == 0) || super_blk) 2034 overhead++; 2035 if (old_desc_blk) 2036 overhead += old_desc_blocks; 2037 else if (new_desc_blk) 2038 overhead++; 2039 return overhead; 2040 } 2041 2042 2043 /* 2044 * calcluate the minimum number of blocks the given fs can be resized to 2045 */ 2046 blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags) 2047 { 2048 ext2_ino_t inode_count; 2049 dgrp_t groups; 2050 blk64_t blks_needed, data_blocks; 2051 blk64_t grp, data_needed, last_start; 2052 blk64_t overhead = 0; 2053 int old_desc_blocks; 2054 int extra_groups = 0; 2055 int flexbg_size = 1 << fs->super->s_log_groups_per_flex; 2056 2057 /* 2058 * first figure out how many group descriptors we need to 2059 * handle the number of inodes we have 2060 */ 2061 inode_count = fs->super->s_inodes_count - 2062 fs->super->s_free_inodes_count; 2063 blks_needed = ext2fs_div_ceil(inode_count, 2064 fs->super->s_inodes_per_group) * 2065 EXT2_BLOCKS_PER_GROUP(fs->super); 2066 groups = ext2fs_div64_ceil(blks_needed, 2067 EXT2_BLOCKS_PER_GROUP(fs->super)); 2068 #ifdef RESIZE2FS_DEBUG 2069 if (flags & RESIZE_DEBUG_MIN_CALC) 2070 printf("fs has %d inodes, %d groups required.\n", 2071 inode_count, groups); 2072 #endif 2073 2074 /* 2075 * number of old-style block group descriptor blocks 2076 */ 2077 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) 2078 old_desc_blocks = fs->super->s_first_meta_bg; 2079 else 2080 old_desc_blocks = fs->desc_blocks + 2081 fs->super->s_reserved_gdt_blocks; 2082 2083 /* calculate how many blocks are needed for data */ 2084 data_needed = ext2fs_blocks_count(fs->super) - 2085 ext2fs_free_blocks_count(fs->super); 2086 2087 for (grp = 0; grp < fs->group_desc_count; grp++) 2088 data_needed -= calc_group_overhead(fs, grp, old_desc_blocks); 2089 #ifdef RESIZE2FS_DEBUG 2090 if (flags & RESIZE_DEBUG_MIN_CALC) 2091 printf("fs requires %llu data blocks.\n", data_needed); 2092 #endif 2093 2094 /* 2095 * For ext4 we need to allow for up to a flex_bg worth of 2096 * inode tables of slack space so the resize operation can be 2097 * guaranteed to finish. 2098 */ 2099 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) { 2100 extra_groups = flexbg_size - (groups & (flexbg_size - 1)); 2101 data_needed += fs->inode_blocks_per_group * extra_groups; 2102 extra_groups = groups % flexbg_size; 2103 } 2104 2105 /* 2106 * figure out how many data blocks we have given the number of groups 2107 * we need for our inodes 2108 */ 2109 data_blocks = groups * EXT2_BLOCKS_PER_GROUP(fs->super); 2110 last_start = 0; 2111 for (grp = 0; grp < groups; grp++) { 2112 overhead = calc_group_overhead(fs, grp, old_desc_blocks); 2113 2114 /* 2115 * we want to keep track of how much data we can store in 2116 * the groups leading up to the last group so we can determine 2117 * how big the last group needs to be 2118 */ 2119 if (grp != (groups - 1)) 2120 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) - 2121 overhead; 2122 2123 data_blocks -= overhead; 2124 } 2125 #ifdef RESIZE2FS_DEBUG 2126 if (flags & RESIZE_DEBUG_MIN_CALC) 2127 printf("With %d group(s), we have %llu blocks available.\n", 2128 groups, data_blocks); 2129 #endif 2130 2131 /* 2132 * if we need more group descriptors in order to accomodate our data 2133 * then we need to add them here 2134 */ 2135 while (data_needed > data_blocks) { 2136 blk64_t remainder = data_needed - data_blocks; 2137 dgrp_t extra_grps; 2138 2139 /* figure out how many more groups we need for the data */ 2140 extra_grps = ext2fs_div64_ceil(remainder, 2141 EXT2_BLOCKS_PER_GROUP(fs->super)); 2142 2143 data_blocks += extra_grps * EXT2_BLOCKS_PER_GROUP(fs->super); 2144 2145 /* ok we have to account for the last group */ 2146 overhead = calc_group_overhead(fs, groups-1, old_desc_blocks); 2147 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) - overhead; 2148 2149 for (grp = groups; grp < groups+extra_grps; grp++) { 2150 overhead = calc_group_overhead(fs, grp, 2151 old_desc_blocks); 2152 2153 /* 2154 * again, we need to see how much data we cram into 2155 * all of the groups leading up to the last group 2156 */ 2157 if (grp != (groups + extra_grps - 1)) 2158 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) 2159 - overhead; 2160 2161 data_blocks -= overhead; 2162 } 2163 2164 groups += extra_grps; 2165 extra_groups += extra_grps; 2166 if (fs->super->s_feature_incompat 2167 & EXT4_FEATURE_INCOMPAT_FLEX_BG 2168 && extra_groups > flexbg_size) { 2169 /* 2170 * For ext4 we need to allow for up to a flex_bg worth 2171 * of inode tables of slack space so the resize 2172 * operation can be guaranteed to finish. 2173 */ 2174 extra_groups = flexbg_size - 2175 (groups & (flexbg_size - 1)); 2176 data_needed += (fs->inode_blocks_per_group * 2177 extra_groups); 2178 extra_groups = groups % flexbg_size; 2179 } 2180 #ifdef RESIZE2FS_DEBUG 2181 if (flags & RESIZE_DEBUG_MIN_CALC) 2182 printf("Added %d extra group(s), " 2183 "data_needed %llu, data_blocks %llu, " 2184 "last_start %llu\n", 2185 extra_grps, data_needed, data_blocks, 2186 last_start); 2187 #endif 2188 } 2189 2190 /* now for the fun voodoo */ 2191 overhead = calc_group_overhead(fs, groups-1, old_desc_blocks); 2192 #ifdef RESIZE2FS_DEBUG 2193 if (flags & RESIZE_DEBUG_MIN_CALC) 2194 printf("Last group's overhead is %llu\n", overhead); 2195 #endif 2196 2197 /* 2198 * if this is the case then the last group is going to have data in it 2199 * so we need to adjust the size of the last group accordingly 2200 */ 2201 if (last_start < data_needed) { 2202 blk64_t remainder = data_needed - last_start; 2203 2204 #ifdef RESIZE2FS_DEBUG 2205 if (flags & RESIZE_DEBUG_MIN_CALC) 2206 printf("Need %llu data blocks in last group\n", 2207 remainder); 2208 #endif 2209 /* 2210 * 50 is a magic number that mkfs/resize uses to see if its 2211 * even worth making/resizing the fs. basically you need to 2212 * have at least 50 blocks in addition to the blocks needed 2213 * for the metadata in the last group 2214 */ 2215 if (remainder > 50) 2216 overhead += remainder; 2217 else 2218 overhead += 50; 2219 } else 2220 overhead += 50; 2221 2222 overhead += fs->super->s_first_data_block; 2223 #ifdef RESIZE2FS_DEBUG 2224 if (flags & RESIZE_DEBUG_MIN_CALC) 2225 printf("Final size of last group is %lld\n", overhead); 2226 #endif 2227 2228 /* 2229 * since our last group doesn't have to be BLOCKS_PER_GROUP large, we 2230 * only do groups-1, and then add the number of blocks needed to 2231 * handle the group descriptor metadata+data that we need 2232 */ 2233 blks_needed = (groups-1) * EXT2_BLOCKS_PER_GROUP(fs->super); 2234 blks_needed += overhead; 2235 2236 /* 2237 * Make sure blks_needed covers the end of the inode table in 2238 * the last block group. 2239 */ 2240 overhead = ext2fs_inode_table_loc(fs, groups-1) + 2241 fs->inode_blocks_per_group; 2242 if (blks_needed < overhead) 2243 blks_needed = overhead; 2244 2245 #ifdef RESIZE2FS_DEBUG 2246 if (flags & RESIZE_DEBUG_MIN_CALC) 2247 printf("Estimated blocks needed: %llu\n", blks_needed); 2248 #endif 2249 2250 /* 2251 * If at this point we've already added up more "needed" than 2252 * the current size, just return current size as minimum. 2253 */ 2254 if (blks_needed >= ext2fs_blocks_count(fs->super)) 2255 return ext2fs_blocks_count(fs->super); 2256 /* 2257 * We need to reserve a few extra blocks if extents are 2258 * enabled, in case we need to grow the extent tree. The more 2259 * we shrink the file system, the more space we need. 2260 */ 2261 if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) { 2262 blk64_t safe_margin = (ext2fs_blocks_count(fs->super) - 2263 blks_needed)/500; 2264 #ifdef RESIZE2FS_DEBUG 2265 if (flags & RESIZE_DEBUG_MIN_CALC) 2266 printf("Extents safety margin: %llu\n", safe_margin); 2267 #endif 2268 blks_needed += safe_margin; 2269 } 2270 2271 return blks_needed; 2272 } 2273