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