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