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 Theodore 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 44 static void fix_uninit_block_bitmaps(ext2_filsys fs); 45 static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size); 46 static errcode_t blocks_to_move(ext2_resize_t rfs); 47 static errcode_t block_mover(ext2_resize_t rfs); 48 static errcode_t inode_scan_and_fix(ext2_resize_t rfs); 49 static errcode_t inode_ref_fix(ext2_resize_t rfs); 50 static errcode_t move_itables(ext2_resize_t rfs); 51 static errcode_t fix_resize_inode(ext2_filsys fs); 52 static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs); 53 static errcode_t fix_sb_journal_backup(ext2_filsys fs); 54 static errcode_t mark_table_blocks(ext2_filsys fs, 55 ext2fs_block_bitmap bmap); 56 static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs); 57 static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs, 58 ext2fs_block_bitmap meta_bmap); 59 static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size); 60 static errcode_t move_bg_metadata(ext2_resize_t rfs); 61 static errcode_t zero_high_bits_in_inodes(ext2_resize_t rfs); 62 63 /* 64 * Some helper functions to check if a block is in a metadata area 65 */ 66 static inline int is_block_bm(ext2_filsys fs, unsigned int grp, blk64_t blk) 67 { 68 return blk == ext2fs_block_bitmap_loc(fs, grp); 69 } 70 71 static inline int is_inode_bm(ext2_filsys fs, unsigned int grp, blk64_t blk) 72 { 73 return blk == ext2fs_inode_bitmap_loc(fs, grp); 74 } 75 76 static int is_inode_tb(ext2_filsys fs, unsigned int grp, blk64_t blk) 77 { 78 return blk >= ext2fs_inode_table_loc(fs, grp) && 79 blk < (ext2fs_inode_table_loc(fs, grp) + 80 fs->inode_blocks_per_group); 81 } 82 83 /* Some bigalloc helper macros which are more succinct... */ 84 #define B2C(x) EXT2FS_B2C(fs, (x)) 85 #define C2B(x) EXT2FS_C2B(fs, (x)) 86 #define EQ_CLSTR(x, y) (B2C(x) == B2C(y)) 87 #define LE_CLSTR(x, y) (B2C(x) <= B2C(y)) 88 #define LT_CLSTR(x, y) (B2C(x) < B2C(y)) 89 #define GE_CLSTR(x, y) (B2C(x) >= B2C(y)) 90 #define GT_CLSTR(x, y) (B2C(x) > B2C(y)) 91 92 static int lazy_itable_init; 93 94 /* 95 * This is the top-level routine which does the dirty deed.... 96 */ 97 errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags, 98 errcode_t (*progress)(ext2_resize_t rfs, int pass, 99 unsigned long cur, 100 unsigned long max_val)) 101 { 102 ext2_resize_t rfs; 103 errcode_t retval; 104 struct resource_track rtrack, overall_track; 105 106 /* 107 * Create the data structure 108 */ 109 retval = ext2fs_get_mem(sizeof(struct ext2_resize_struct), &rfs); 110 if (retval) 111 return retval; 112 113 memset(rfs, 0, sizeof(struct ext2_resize_struct)); 114 fs->priv_data = rfs; 115 rfs->old_fs = fs; 116 rfs->flags = flags; 117 rfs->itable_buf = 0; 118 rfs->progress = progress; 119 120 init_resource_track(&overall_track, "overall resize2fs", fs->io); 121 init_resource_track(&rtrack, "read_bitmaps", fs->io); 122 retval = ext2fs_read_bitmaps(fs); 123 if (retval) 124 goto errout; 125 print_resource_track(rfs, &rtrack, fs->io); 126 127 fs->super->s_state |= EXT2_ERROR_FS; 128 ext2fs_mark_super_dirty(fs); 129 ext2fs_flush(fs); 130 131 init_resource_track(&rtrack, "fix_uninit_block_bitmaps 1", fs->io); 132 fix_uninit_block_bitmaps(fs); 133 print_resource_track(rfs, &rtrack, fs->io); 134 retval = ext2fs_dup_handle(fs, &rfs->new_fs); 135 if (retval) 136 goto errout; 137 138 init_resource_track(&rtrack, "resize_group_descriptors", fs->io); 139 retval = resize_group_descriptors(rfs, *new_size); 140 if (retval) 141 goto errout; 142 print_resource_track(rfs, &rtrack, fs->io); 143 144 init_resource_track(&rtrack, "move_bg_metadata", fs->io); 145 retval = move_bg_metadata(rfs); 146 if (retval) 147 goto errout; 148 print_resource_track(rfs, &rtrack, fs->io); 149 150 init_resource_track(&rtrack, "zero_high_bits_in_metadata", fs->io); 151 retval = zero_high_bits_in_inodes(rfs); 152 if (retval) 153 goto errout; 154 print_resource_track(rfs, &rtrack, fs->io); 155 156 init_resource_track(&rtrack, "adjust_superblock", fs->io); 157 retval = adjust_superblock(rfs, *new_size); 158 if (retval) 159 goto errout; 160 print_resource_track(rfs, &rtrack, fs->io); 161 162 init_resource_track(&rtrack, "fix_uninit_block_bitmaps 2", fs->io); 163 fix_uninit_block_bitmaps(rfs->new_fs); 164 print_resource_track(rfs, &rtrack, fs->io); 165 /* Clear the block bitmap uninit flag for the last block group */ 166 ext2fs_bg_flags_clear(rfs->new_fs, rfs->new_fs->group_desc_count - 1, 167 EXT2_BG_BLOCK_UNINIT); 168 169 *new_size = ext2fs_blocks_count(rfs->new_fs->super); 170 171 init_resource_track(&rtrack, "blocks_to_move", fs->io); 172 retval = blocks_to_move(rfs); 173 if (retval) 174 goto errout; 175 print_resource_track(rfs, &rtrack, fs->io); 176 177 #ifdef RESIZE2FS_DEBUG 178 if (rfs->flags & RESIZE_DEBUG_BMOVE) 179 printf("Number of free blocks: %llu/%llu, Needed: %llu\n", 180 ext2fs_free_blocks_count(rfs->old_fs->super), 181 ext2fs_free_blocks_count(rfs->new_fs->super), 182 rfs->needed_blocks); 183 #endif 184 185 init_resource_track(&rtrack, "block_mover", fs->io); 186 retval = block_mover(rfs); 187 if (retval) 188 goto errout; 189 print_resource_track(rfs, &rtrack, fs->io); 190 191 init_resource_track(&rtrack, "inode_scan_and_fix", fs->io); 192 retval = inode_scan_and_fix(rfs); 193 if (retval) 194 goto errout; 195 print_resource_track(rfs, &rtrack, fs->io); 196 197 init_resource_track(&rtrack, "inode_ref_fix", fs->io); 198 retval = inode_ref_fix(rfs); 199 if (retval) 200 goto errout; 201 print_resource_track(rfs, &rtrack, fs->io); 202 203 init_resource_track(&rtrack, "move_itables", fs->io); 204 retval = move_itables(rfs); 205 if (retval) 206 goto errout; 207 print_resource_track(rfs, &rtrack, fs->io); 208 209 retval = clear_sparse_super2_last_group(rfs); 210 if (retval) 211 goto errout; 212 213 init_resource_track(&rtrack, "calculate_summary_stats", fs->io); 214 retval = ext2fs_calculate_summary_stats(rfs->new_fs); 215 if (retval) 216 goto errout; 217 print_resource_track(rfs, &rtrack, fs->io); 218 219 init_resource_track(&rtrack, "fix_resize_inode", fs->io); 220 retval = fix_resize_inode(rfs->new_fs); 221 if (retval) 222 goto errout; 223 print_resource_track(rfs, &rtrack, fs->io); 224 225 init_resource_track(&rtrack, "fix_sb_journal_backup", fs->io); 226 retval = fix_sb_journal_backup(rfs->new_fs); 227 if (retval) 228 goto errout; 229 print_resource_track(rfs, &rtrack, fs->io); 230 231 retval = ext2fs_set_gdt_csum(rfs->new_fs); 232 if (retval) 233 goto errout; 234 235 rfs->new_fs->super->s_state &= ~EXT2_ERROR_FS; 236 rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 237 238 print_resource_track(rfs, &overall_track, fs->io); 239 retval = ext2fs_close_free(&rfs->new_fs); 240 if (retval) 241 goto errout; 242 243 rfs->flags = flags; 244 245 ext2fs_free(rfs->old_fs); 246 rfs->old_fs = NULL; 247 if (rfs->itable_buf) 248 ext2fs_free_mem(&rfs->itable_buf); 249 if (rfs->reserve_blocks) 250 ext2fs_free_block_bitmap(rfs->reserve_blocks); 251 if (rfs->move_blocks) 252 ext2fs_free_block_bitmap(rfs->move_blocks); 253 ext2fs_free_mem(&rfs); 254 255 return 0; 256 257 errout: 258 if (rfs->new_fs) { 259 ext2fs_free(rfs->new_fs); 260 rfs->new_fs = NULL; 261 } 262 if (rfs->itable_buf) 263 ext2fs_free_mem(&rfs->itable_buf); 264 ext2fs_free_mem(&rfs); 265 return retval; 266 } 267 268 /* Keep the size of the group descriptor region constant */ 269 static void adjust_reserved_gdt_blocks(ext2_filsys old_fs, ext2_filsys fs) 270 { 271 if (ext2fs_has_feature_resize_inode(fs->super) && 272 (old_fs->desc_blocks != fs->desc_blocks)) { 273 int new; 274 275 new = ((int) fs->super->s_reserved_gdt_blocks) + 276 (old_fs->desc_blocks - fs->desc_blocks); 277 if (new < 0) 278 new = 0; 279 if (new > (int) fs->blocksize/4) 280 new = fs->blocksize/4; 281 fs->super->s_reserved_gdt_blocks = new; 282 } 283 } 284 285 /* Toggle 64bit mode */ 286 static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size) 287 { 288 void *o, *n, *new_group_desc; 289 dgrp_t i; 290 int copy_size; 291 errcode_t retval; 292 293 if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT))) 294 return 0; 295 296 if (new_size != ext2fs_blocks_count(rfs->new_fs->super) || 297 ext2fs_blocks_count(rfs->new_fs->super) >= (1ULL << 32) || 298 (rfs->flags & RESIZE_DISABLE_64BIT && 299 rfs->flags & RESIZE_ENABLE_64BIT)) 300 return EXT2_ET_INVALID_ARGUMENT; 301 302 if (rfs->flags & RESIZE_DISABLE_64BIT) { 303 ext2fs_clear_feature_64bit(rfs->new_fs->super); 304 rfs->new_fs->super->s_desc_size = EXT2_MIN_DESC_SIZE; 305 } else if (rfs->flags & RESIZE_ENABLE_64BIT) { 306 ext2fs_set_feature_64bit(rfs->new_fs->super); 307 rfs->new_fs->super->s_desc_size = EXT2_MIN_DESC_SIZE_64BIT; 308 } 309 310 if (EXT2_DESC_SIZE(rfs->old_fs->super) == 311 EXT2_DESC_SIZE(rfs->new_fs->super)) 312 return 0; 313 314 o = rfs->new_fs->group_desc; 315 rfs->new_fs->desc_blocks = ext2fs_div_ceil( 316 rfs->old_fs->group_desc_count, 317 EXT2_DESC_PER_BLOCK(rfs->new_fs->super)); 318 retval = ext2fs_get_arrayzero(rfs->new_fs->desc_blocks, 319 rfs->old_fs->blocksize, &new_group_desc); 320 if (retval) 321 return retval; 322 323 n = new_group_desc; 324 325 if (EXT2_DESC_SIZE(rfs->old_fs->super) <= 326 EXT2_DESC_SIZE(rfs->new_fs->super)) 327 copy_size = EXT2_DESC_SIZE(rfs->old_fs->super); 328 else 329 copy_size = EXT2_DESC_SIZE(rfs->new_fs->super); 330 for (i = 0; i < rfs->old_fs->group_desc_count; i++) { 331 memcpy(n, o, copy_size); 332 n = (char *)n + EXT2_DESC_SIZE(rfs->new_fs->super); 333 o = (char *)o + EXT2_DESC_SIZE(rfs->old_fs->super); 334 } 335 336 ext2fs_free_mem(&rfs->new_fs->group_desc); 337 rfs->new_fs->group_desc = new_group_desc; 338 339 for (i = 0; i < rfs->old_fs->group_desc_count; i++) 340 ext2fs_group_desc_csum_set(rfs->new_fs, i); 341 342 adjust_reserved_gdt_blocks(rfs->old_fs, rfs->new_fs); 343 344 return 0; 345 } 346 347 /* Move bitmaps/inode tables out of the way. */ 348 static errcode_t move_bg_metadata(ext2_resize_t rfs) 349 { 350 dgrp_t i; 351 blk64_t b, c, d, old_desc_blocks, new_desc_blocks, j; 352 ext2fs_block_bitmap old_map, new_map; 353 int old, new; 354 errcode_t retval; 355 int cluster_ratio; 356 357 if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT))) 358 return 0; 359 360 retval = ext2fs_allocate_block_bitmap(rfs->old_fs, "oldfs", &old_map); 361 if (retval) 362 return retval; 363 364 retval = ext2fs_allocate_block_bitmap(rfs->new_fs, "newfs", &new_map); 365 if (retval) 366 goto out; 367 368 if (ext2fs_has_feature_meta_bg(rfs->old_fs->super)) { 369 old_desc_blocks = rfs->old_fs->super->s_first_meta_bg; 370 new_desc_blocks = rfs->new_fs->super->s_first_meta_bg; 371 } else { 372 old_desc_blocks = rfs->old_fs->desc_blocks + 373 rfs->old_fs->super->s_reserved_gdt_blocks; 374 new_desc_blocks = rfs->new_fs->desc_blocks + 375 rfs->new_fs->super->s_reserved_gdt_blocks; 376 } 377 378 /* Construct bitmaps of super/descriptor blocks in old and new fs */ 379 for (i = 0; i < rfs->old_fs->group_desc_count; i++) { 380 retval = ext2fs_super_and_bgd_loc2(rfs->old_fs, i, &b, &c, &d, 381 NULL); 382 if (retval) 383 goto out; 384 if (b) 385 ext2fs_mark_block_bitmap2(old_map, b); 386 for (j = 0; c != 0 && j < old_desc_blocks; j++) 387 ext2fs_mark_block_bitmap2(old_map, c + j); 388 if (d) 389 ext2fs_mark_block_bitmap2(old_map, d); 390 391 retval = ext2fs_super_and_bgd_loc2(rfs->new_fs, i, &b, &c, &d, 392 NULL); 393 if (retval) 394 goto out; 395 if (b) 396 ext2fs_mark_block_bitmap2(new_map, b); 397 for (j = 0; c != 0 && j < new_desc_blocks; j++) 398 ext2fs_mark_block_bitmap2(new_map, c + j); 399 if (d) 400 ext2fs_mark_block_bitmap2(new_map, d); 401 } 402 403 cluster_ratio = EXT2FS_CLUSTER_RATIO(rfs->new_fs); 404 405 /* Find changes in block allocations for bg metadata */ 406 for (b = EXT2FS_B2C(rfs->old_fs, 407 rfs->old_fs->super->s_first_data_block); 408 b < ext2fs_blocks_count(rfs->new_fs->super); 409 b += cluster_ratio) { 410 old = ext2fs_test_block_bitmap2(old_map, b); 411 new = ext2fs_test_block_bitmap2(new_map, b); 412 413 if (old && !new) { 414 /* mark old_map, unmark new_map */ 415 if (cluster_ratio == 1) 416 ext2fs_unmark_block_bitmap2( 417 rfs->new_fs->block_map, b); 418 } else if (!old && new) 419 ; /* unmark old_map, mark new_map */ 420 else { 421 ext2fs_unmark_block_bitmap2(old_map, b); 422 ext2fs_unmark_block_bitmap2(new_map, b); 423 } 424 } 425 426 /* 427 * new_map now shows blocks that have been newly allocated. 428 * old_map now shows blocks that have been newly freed. 429 */ 430 431 /* 432 * Move any conflicting bitmaps and inode tables. Ensure that we 433 * don't try to free clusters associated with bitmaps or tables. 434 */ 435 for (i = 0; i < rfs->old_fs->group_desc_count; i++) { 436 b = ext2fs_block_bitmap_loc(rfs->new_fs, i); 437 if (ext2fs_test_block_bitmap2(new_map, b)) 438 ext2fs_block_bitmap_loc_set(rfs->new_fs, i, 0); 439 else if (ext2fs_test_block_bitmap2(old_map, b)) 440 ext2fs_unmark_block_bitmap2(old_map, b); 441 442 b = ext2fs_inode_bitmap_loc(rfs->new_fs, i); 443 if (ext2fs_test_block_bitmap2(new_map, b)) 444 ext2fs_inode_bitmap_loc_set(rfs->new_fs, i, 0); 445 else if (ext2fs_test_block_bitmap2(old_map, b)) 446 ext2fs_unmark_block_bitmap2(old_map, b); 447 448 c = ext2fs_inode_table_loc(rfs->new_fs, i); 449 for (b = 0; 450 b < rfs->new_fs->inode_blocks_per_group; 451 b++) { 452 if (ext2fs_test_block_bitmap2(new_map, b + c)) 453 ext2fs_inode_table_loc_set(rfs->new_fs, i, 0); 454 else if (ext2fs_test_block_bitmap2(old_map, b + c)) 455 ext2fs_unmark_block_bitmap2(old_map, b + c); 456 } 457 } 458 459 /* Free unused clusters */ 460 for (b = 0; 461 cluster_ratio > 1 && b < ext2fs_blocks_count(rfs->new_fs->super); 462 b += cluster_ratio) 463 if (ext2fs_test_block_bitmap2(old_map, b)) 464 ext2fs_unmark_block_bitmap2(rfs->new_fs->block_map, b); 465 out: 466 if (old_map) 467 ext2fs_free_block_bitmap(old_map); 468 if (new_map) 469 ext2fs_free_block_bitmap(new_map); 470 return retval; 471 } 472 473 /* Zero out the high bits of extent fields */ 474 static errcode_t zero_high_bits_in_extents(ext2_filsys fs, ext2_ino_t ino, 475 struct ext2_inode *inode) 476 { 477 ext2_extent_handle_t handle; 478 struct ext2fs_extent extent; 479 int op = EXT2_EXTENT_ROOT; 480 errcode_t errcode; 481 482 if (!(inode->i_flags & EXT4_EXTENTS_FL)) 483 return 0; 484 485 errcode = ext2fs_extent_open(fs, ino, &handle); 486 if (errcode) 487 return errcode; 488 489 while (1) { 490 errcode = ext2fs_extent_get(handle, op, &extent); 491 if (errcode) 492 break; 493 494 op = EXT2_EXTENT_NEXT_SIB; 495 496 if (extent.e_pblk > (1ULL << 32)) { 497 extent.e_pblk &= (1ULL << 32) - 1; 498 errcode = ext2fs_extent_replace(handle, 0, &extent); 499 if (errcode) 500 break; 501 } 502 } 503 504 /* Ok if we run off the end */ 505 if (errcode == EXT2_ET_EXTENT_NO_NEXT) 506 errcode = 0; 507 ext2fs_extent_free(handle); 508 return errcode; 509 } 510 511 /* Zero out the high bits of inodes. */ 512 static errcode_t zero_high_bits_in_inodes(ext2_resize_t rfs) 513 { 514 ext2_filsys fs = rfs->old_fs; 515 int length = EXT2_INODE_SIZE(fs->super); 516 struct ext2_inode *inode = NULL; 517 ext2_inode_scan scan = NULL; 518 errcode_t retval; 519 ext2_ino_t ino; 520 521 if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT))) 522 return 0; 523 524 if (fs->super->s_creator_os == EXT2_OS_HURD) 525 return 0; 526 527 retval = ext2fs_open_inode_scan(fs, 0, &scan); 528 if (retval) 529 return retval; 530 531 retval = ext2fs_get_mem(length, &inode); 532 if (retval) 533 goto out; 534 535 do { 536 retval = ext2fs_get_next_inode_full(scan, &ino, inode, length); 537 if (retval) 538 goto out; 539 if (!ino) 540 break; 541 if (!ext2fs_test_inode_bitmap2(fs->inode_map, ino)) 542 continue; 543 544 /* 545 * Here's how we deal with high block number fields: 546 * 547 * - i_size_high has been been written out with i_size_lo 548 * since the ext2 days, so no conversion is needed. 549 * 550 * - i_blocks_hi is guarded by both the huge_file feature and 551 * inode flags and has always been written out with 552 * i_blocks_lo if the feature is set. The field is only 553 * ever read if both feature and inode flag are set, so 554 * we don't need to zero it now. 555 * 556 * - i_file_acl_high can be uninitialized, so zero it if 557 * it isn't already. 558 */ 559 if (inode->osd2.linux2.l_i_file_acl_high) { 560 inode->osd2.linux2.l_i_file_acl_high = 0; 561 retval = ext2fs_write_inode_full(fs, ino, inode, 562 length); 563 if (retval) 564 goto out; 565 } 566 567 retval = zero_high_bits_in_extents(fs, ino, inode); 568 if (retval) 569 goto out; 570 } while (ino); 571 572 out: 573 if (inode) 574 ext2fs_free_mem(&inode); 575 if (scan) 576 ext2fs_close_inode_scan(scan); 577 return retval; 578 } 579 580 /* 581 * Clean up the bitmaps for uninitialized bitmaps 582 */ 583 static void fix_uninit_block_bitmaps(ext2_filsys fs) 584 { 585 blk64_t blk, lblk; 586 dgrp_t g; 587 unsigned int i; 588 589 if (!ext2fs_has_group_desc_csum(fs)) 590 return; 591 592 for (g=0; g < fs->group_desc_count; g++) { 593 if (!(ext2fs_bg_flags_test(fs, g, EXT2_BG_BLOCK_UNINIT))) 594 continue; 595 596 blk = ext2fs_group_first_block2(fs, g); 597 lblk = ext2fs_group_last_block2(fs, g); 598 ext2fs_unmark_block_bitmap_range2(fs->block_map, blk, 599 lblk - blk + 1); 600 601 ext2fs_reserve_super_and_bgd(fs, g, fs->block_map); 602 ext2fs_mark_block_bitmap2(fs->block_map, 603 ext2fs_block_bitmap_loc(fs, g)); 604 ext2fs_mark_block_bitmap2(fs->block_map, 605 ext2fs_inode_bitmap_loc(fs, g)); 606 for (i = 0, blk = ext2fs_inode_table_loc(fs, g); 607 i < fs->inode_blocks_per_group; 608 i++, blk++) 609 ext2fs_mark_block_bitmap2(fs->block_map, blk); 610 } 611 } 612 613 /* -------------------------------------------------------------------- 614 * 615 * Resize processing, phase 1. 616 * 617 * In this phase we adjust the in-memory superblock information, and 618 * initialize any new parts of the inode table. The new parts of the 619 * inode table are created in virgin disk space, so we can abort here 620 * without any side effects. 621 * -------------------------------------------------------------------- 622 */ 623 624 /* 625 * If the group descriptor's bitmap and inode table blocks are valid, 626 * release them in the new filesystem data structure, and mark them as 627 * reserved so the old inode table blocks don't get overwritten. 628 */ 629 static errcode_t free_gdp_blocks(ext2_filsys fs, 630 ext2fs_block_bitmap reserve_blocks, 631 ext2_filsys old_fs, 632 dgrp_t group) 633 { 634 blk64_t blk; 635 unsigned int j; 636 dgrp_t i; 637 ext2fs_block_bitmap bg_map = NULL; 638 errcode_t retval = 0; 639 dgrp_t count = old_fs->group_desc_count - fs->group_desc_count; 640 641 /* If bigalloc, don't free metadata living in the same cluster */ 642 if (EXT2FS_CLUSTER_RATIO(fs) > 1) { 643 retval = ext2fs_allocate_block_bitmap(fs, "bgdata", &bg_map); 644 if (retval) 645 goto out; 646 647 retval = mark_table_blocks(fs, bg_map); 648 if (retval) 649 goto out; 650 } 651 652 for (i = group; i < group + count; i++) { 653 blk = ext2fs_block_bitmap_loc(old_fs, i); 654 if (blk && 655 (blk < ext2fs_blocks_count(fs->super)) && 656 !(bg_map && ext2fs_test_block_bitmap2(bg_map, blk))) { 657 ext2fs_block_alloc_stats2(fs, blk, -1); 658 ext2fs_mark_block_bitmap2(reserve_blocks, blk); 659 } 660 661 blk = ext2fs_inode_bitmap_loc(old_fs, i); 662 if (blk && 663 (blk < ext2fs_blocks_count(fs->super)) && 664 !(bg_map && ext2fs_test_block_bitmap2(bg_map, blk))) { 665 ext2fs_block_alloc_stats2(fs, blk, -1); 666 ext2fs_mark_block_bitmap2(reserve_blocks, blk); 667 } 668 669 blk = ext2fs_inode_table_loc(old_fs, i); 670 for (j = 0; 671 j < fs->inode_blocks_per_group; j++, blk++) { 672 if (blk >= ext2fs_blocks_count(fs->super) || 673 (bg_map && ext2fs_test_block_bitmap2(bg_map, blk))) 674 continue; 675 ext2fs_block_alloc_stats2(fs, blk, -1); 676 ext2fs_mark_block_bitmap2(reserve_blocks, blk); 677 } 678 } 679 680 out: 681 if (bg_map) 682 ext2fs_free_block_bitmap(bg_map); 683 return retval; 684 } 685 686 /* 687 * This routine is shared by the online and offline resize routines. 688 * All of the information which is adjusted in memory is done here. 689 */ 690 errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs, 691 ext2fs_block_bitmap reserve_blocks, blk64_t new_size) 692 { 693 errcode_t retval; 694 blk64_t overhead = 0; 695 blk64_t rem; 696 blk64_t blk, group_block; 697 blk64_t real_end; 698 blk64_t old_numblocks, numblocks, adjblocks; 699 unsigned long i, j, old_desc_blocks; 700 unsigned int meta_bg, meta_bg_size; 701 int has_super, csum_flag, has_bg; 702 unsigned long long new_inodes; /* u64 to check for overflow */ 703 double percent; 704 705 ext2fs_blocks_count_set(fs->super, new_size); 706 707 retry: 708 fs->group_desc_count = ext2fs_div64_ceil(ext2fs_blocks_count(fs->super) - 709 fs->super->s_first_data_block, 710 EXT2_BLOCKS_PER_GROUP(fs->super)); 711 if (fs->group_desc_count == 0) 712 return EXT2_ET_TOOSMALL; 713 fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count, 714 EXT2_DESC_PER_BLOCK(fs->super)); 715 716 /* 717 * Overhead is the number of bookkeeping blocks per group. It 718 * includes the superblock backup, the group descriptor 719 * backups, the inode bitmap, the block bitmap, and the inode 720 * table. 721 */ 722 overhead = (int) (2 + fs->inode_blocks_per_group); 723 724 has_bg = 0; 725 if (ext2fs_has_feature_sparse_super2(fs->super)) { 726 /* 727 * We have to do this manually since 728 * super->s_backup_bgs hasn't been set up yet. 729 */ 730 if (fs->group_desc_count == 2) 731 has_bg = fs->super->s_backup_bgs[0] != 0; 732 else 733 has_bg = fs->super->s_backup_bgs[1] != 0; 734 } else 735 has_bg = ext2fs_bg_has_super(fs, fs->group_desc_count - 1); 736 if (has_bg) 737 overhead += 1 + fs->desc_blocks + 738 fs->super->s_reserved_gdt_blocks; 739 740 /* 741 * See if the last group is big enough to support the 742 * necessary data structures. If not, we need to get rid of 743 * it. 744 */ 745 rem = (ext2fs_blocks_count(fs->super) - fs->super->s_first_data_block) % 746 fs->super->s_blocks_per_group; 747 if ((fs->group_desc_count == 1) && rem && (rem < overhead)) 748 return EXT2_ET_TOOSMALL; 749 if ((fs->group_desc_count > 1) && rem && (rem < overhead+50)) { 750 ext2fs_blocks_count_set(fs->super, 751 ext2fs_blocks_count(fs->super) - rem); 752 goto retry; 753 } 754 /* 755 * Adjust the number of inodes 756 */ 757 new_inodes =(unsigned long long) fs->super->s_inodes_per_group * fs->group_desc_count; 758 if (new_inodes > ~0U) { 759 fprintf(stderr, _("inodes (%llu) must be less than %u\n"), 760 new_inodes, ~0U); 761 return EXT2_ET_TOO_MANY_INODES; 762 } 763 fs->super->s_inodes_count = fs->super->s_inodes_per_group * 764 fs->group_desc_count; 765 766 /* 767 * Adjust the number of free blocks 768 */ 769 blk = ext2fs_blocks_count(old_fs->super); 770 if (blk > ext2fs_blocks_count(fs->super)) 771 ext2fs_free_blocks_count_set(fs->super, 772 ext2fs_free_blocks_count(fs->super) - 773 (blk - ext2fs_blocks_count(fs->super))); 774 else 775 ext2fs_free_blocks_count_set(fs->super, 776 ext2fs_free_blocks_count(fs->super) + 777 (ext2fs_blocks_count(fs->super) - blk)); 778 779 /* 780 * Adjust the number of reserved blocks 781 */ 782 percent = (ext2fs_r_blocks_count(old_fs->super) * 100.0) / 783 ext2fs_blocks_count(old_fs->super); 784 ext2fs_r_blocks_count_set(fs->super, 785 (percent * ext2fs_blocks_count(fs->super) / 786 100.0)); 787 788 /* 789 * Adjust the bitmaps for size 790 */ 791 retval = ext2fs_resize_inode_bitmap2(fs->super->s_inodes_count, 792 fs->super->s_inodes_count, 793 fs->inode_map); 794 if (retval) goto errout; 795 796 real_end = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count) - 1 + 797 fs->super->s_first_data_block; 798 retval = ext2fs_resize_block_bitmap2(new_size - 1, 799 real_end, fs->block_map); 800 if (retval) goto errout; 801 802 /* 803 * If we are growing the file system, also grow the size of 804 * the reserve_blocks bitmap 805 */ 806 if (reserve_blocks && new_size > ext2fs_blocks_count(old_fs->super)) { 807 retval = ext2fs_resize_block_bitmap2(new_size - 1, 808 real_end, reserve_blocks); 809 if (retval) goto errout; 810 } 811 812 /* 813 * Reallocate the group descriptors as necessary. 814 */ 815 if (EXT2_DESC_SIZE(old_fs->super) == EXT2_DESC_SIZE(fs->super) && 816 old_fs->desc_blocks != fs->desc_blocks) { 817 retval = ext2fs_resize_mem(old_fs->desc_blocks * 818 fs->blocksize, 819 fs->desc_blocks * fs->blocksize, 820 &fs->group_desc); 821 if (retval) 822 goto errout; 823 if (fs->desc_blocks > old_fs->desc_blocks) 824 memset((char *) fs->group_desc + 825 (old_fs->desc_blocks * fs->blocksize), 0, 826 (fs->desc_blocks - old_fs->desc_blocks) * 827 fs->blocksize); 828 } 829 830 /* 831 * If the resize_inode feature is set, and we are changing the 832 * number of descriptor blocks, then adjust 833 * s_reserved_gdt_blocks if possible to avoid needing to move 834 * the inode table either now or in the future. 835 * 836 * Note: If we're converting to 64bit mode, we did this earlier. 837 */ 838 if (EXT2_DESC_SIZE(old_fs->super) == EXT2_DESC_SIZE(fs->super)) 839 adjust_reserved_gdt_blocks(old_fs, fs); 840 841 if (ext2fs_has_feature_meta_bg(fs->super) && 842 (fs->super->s_first_meta_bg > fs->desc_blocks)) { 843 ext2fs_clear_feature_meta_bg(fs->super); 844 fs->super->s_first_meta_bg = 0; 845 } 846 847 /* 848 * Update the location of the backup superblocks if the 849 * sparse_super2 feature is enabled. 850 */ 851 if (ext2fs_has_feature_sparse_super2(fs->super)) { 852 dgrp_t last_bg = fs->group_desc_count - 1; 853 dgrp_t old_last_bg = old_fs->group_desc_count - 1; 854 855 if (last_bg > old_last_bg) { 856 if (old_fs->group_desc_count == 1) 857 fs->super->s_backup_bgs[0] = 1; 858 if ((old_fs->group_desc_count < 3 && 859 fs->group_desc_count > 2) || 860 fs->super->s_backup_bgs[1]) 861 fs->super->s_backup_bgs[1] = last_bg; 862 } else if (last_bg < old_last_bg) { 863 if (fs->super->s_backup_bgs[0] > last_bg) 864 fs->super->s_backup_bgs[0] = 0; 865 if (fs->super->s_backup_bgs[1] > last_bg) 866 fs->super->s_backup_bgs[1] = 0; 867 if (last_bg > 1 && 868 old_fs->super->s_backup_bgs[1] == old_last_bg) 869 fs->super->s_backup_bgs[1] = last_bg; 870 } 871 } 872 873 /* 874 * If we are shrinking the number of block groups, we're done 875 * and can exit now. 876 */ 877 if (old_fs->group_desc_count > fs->group_desc_count) { 878 /* 879 * Check the block groups that we are chopping off 880 * and free any blocks associated with their metadata 881 */ 882 retval = free_gdp_blocks(fs, reserve_blocks, old_fs, 883 fs->group_desc_count); 884 goto errout; 885 } 886 887 /* 888 * Fix the count of the last (old) block group 889 */ 890 old_numblocks = (ext2fs_blocks_count(old_fs->super) - 891 old_fs->super->s_first_data_block) % 892 old_fs->super->s_blocks_per_group; 893 if (!old_numblocks) 894 old_numblocks = old_fs->super->s_blocks_per_group; 895 if (old_fs->group_desc_count == fs->group_desc_count) { 896 numblocks = (ext2fs_blocks_count(fs->super) - 897 fs->super->s_first_data_block) % 898 fs->super->s_blocks_per_group; 899 if (!numblocks) 900 numblocks = fs->super->s_blocks_per_group; 901 } else 902 numblocks = fs->super->s_blocks_per_group; 903 i = old_fs->group_desc_count - 1; 904 ext2fs_bg_free_blocks_count_set(fs, i, ext2fs_bg_free_blocks_count(fs, i) + (numblocks - old_numblocks)); 905 ext2fs_group_desc_csum_set(fs, i); 906 907 /* 908 * If the number of block groups is staying the same, we're 909 * done and can exit now. (If the number block groups is 910 * shrinking, we had exited earlier.) 911 */ 912 if (old_fs->group_desc_count >= fs->group_desc_count) { 913 retval = 0; 914 goto errout; 915 } 916 917 /* 918 * Initialize the new block group descriptors 919 */ 920 group_block = ext2fs_group_first_block2(fs, 921 old_fs->group_desc_count); 922 csum_flag = ext2fs_has_group_desc_csum(fs); 923 if (getenv("RESIZE2FS_FORCE_LAZY_ITABLE_INIT") || 924 (!getenv("RESIZE2FS_FORCE_ITABLE_INIT") && 925 access("/sys/fs/ext4/features/lazy_itable_init", F_OK) == 0)) 926 lazy_itable_init = 1; 927 if (ext2fs_has_feature_meta_bg(fs->super)) 928 old_desc_blocks = fs->super->s_first_meta_bg; 929 else 930 old_desc_blocks = fs->desc_blocks + 931 fs->super->s_reserved_gdt_blocks; 932 933 /* 934 * If we changed the number of block_group descriptor blocks, 935 * we need to make sure they are all marked as reserved in the 936 * filesystem's block allocation map. 937 */ 938 for (i = 0; i < old_fs->group_desc_count; i++) 939 ext2fs_reserve_super_and_bgd(fs, i, fs->block_map); 940 941 for (i = old_fs->group_desc_count; 942 i < fs->group_desc_count; i++) { 943 memset(ext2fs_group_desc(fs, fs->group_desc, i), 0, 944 sizeof(struct ext2_group_desc)); 945 adjblocks = 0; 946 947 ext2fs_bg_flags_zap(fs, i); 948 if (csum_flag) { 949 ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT); 950 if (!lazy_itable_init) 951 ext2fs_bg_flags_set(fs, i, 952 EXT2_BG_INODE_ZEROED); 953 ext2fs_bg_itable_unused_set(fs, i, 954 fs->super->s_inodes_per_group); 955 } 956 957 numblocks = ext2fs_group_blocks_count(fs, i); 958 if ((i < fs->group_desc_count - 1) && csum_flag) 959 ext2fs_bg_flags_set(fs, i, EXT2_BG_BLOCK_UNINIT); 960 961 has_super = ext2fs_bg_has_super(fs, i); 962 if (has_super) { 963 ext2fs_block_alloc_stats2(fs, group_block, +1); 964 adjblocks++; 965 } 966 meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super); 967 meta_bg = i / meta_bg_size; 968 if (!ext2fs_has_feature_meta_bg(fs->super) || 969 (meta_bg < fs->super->s_first_meta_bg)) { 970 if (has_super) { 971 for (j=0; j < old_desc_blocks; j++) 972 ext2fs_block_alloc_stats2(fs, 973 group_block + 1 + j, +1); 974 adjblocks += old_desc_blocks; 975 } 976 } else { 977 if (has_super) 978 has_super = 1; 979 if (((i % meta_bg_size) == 0) || 980 ((i % meta_bg_size) == 1) || 981 ((i % meta_bg_size) == (meta_bg_size-1))) 982 ext2fs_block_alloc_stats2(fs, 983 group_block + has_super, +1); 984 } 985 986 adjblocks += 2 + fs->inode_blocks_per_group; 987 988 numblocks -= adjblocks; 989 ext2fs_free_blocks_count_set(fs->super, 990 ext2fs_free_blocks_count(fs->super) - adjblocks); 991 fs->super->s_free_inodes_count += 992 fs->super->s_inodes_per_group; 993 ext2fs_bg_free_blocks_count_set(fs, i, numblocks); 994 ext2fs_bg_free_inodes_count_set(fs, i, 995 fs->super->s_inodes_per_group); 996 ext2fs_bg_used_dirs_count_set(fs, i, 0); 997 ext2fs_group_desc_csum_set(fs, i); 998 999 retval = ext2fs_allocate_group_table(fs, i, 0); 1000 if (retval) goto errout; 1001 1002 group_block += fs->super->s_blocks_per_group; 1003 } 1004 retval = 0; 1005 1006 /* 1007 * Mark all of the metadata blocks as reserved so they won't 1008 * get allocated by the call to ext2fs_allocate_group_table() 1009 * in blocks_to_move(), where we allocate new blocks to 1010 * replace those allocation bitmap and inode table blocks 1011 * which have to get relocated to make space for an increased 1012 * number of the block group descriptors. 1013 */ 1014 if (reserve_blocks) 1015 mark_table_blocks(fs, reserve_blocks); 1016 1017 errout: 1018 return (retval); 1019 } 1020 1021 /* 1022 * This routine adjusts the superblock and other data structures, both 1023 * in disk as well as in memory... 1024 */ 1025 static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size) 1026 { 1027 ext2_filsys fs = rfs->new_fs; 1028 int adj = 0; 1029 errcode_t retval; 1030 blk64_t group_block; 1031 unsigned long i; 1032 unsigned long max_group; 1033 1034 ext2fs_mark_super_dirty(fs); 1035 ext2fs_mark_bb_dirty(fs); 1036 ext2fs_mark_ib_dirty(fs); 1037 1038 retval = ext2fs_allocate_block_bitmap(fs, _("reserved blocks"), 1039 &rfs->reserve_blocks); 1040 if (retval) 1041 return retval; 1042 1043 retval = adjust_fs_info(fs, rfs->old_fs, rfs->reserve_blocks, new_size); 1044 if (retval) 1045 goto errout; 1046 1047 /* 1048 * Check to make sure there are enough inodes 1049 */ 1050 if ((rfs->old_fs->super->s_inodes_count - 1051 rfs->old_fs->super->s_free_inodes_count) > 1052 rfs->new_fs->super->s_inodes_count) { 1053 retval = ENOSPC; 1054 goto errout; 1055 } 1056 1057 /* 1058 * If we are shrinking the number block groups, we're done and 1059 * can exit now. 1060 */ 1061 if (rfs->old_fs->group_desc_count > fs->group_desc_count) { 1062 retval = 0; 1063 goto errout; 1064 } 1065 1066 /* 1067 * If the number of block groups is staying the same, we're 1068 * done and can exit now. (If the number block groups is 1069 * shrinking, we had exited earlier.) 1070 */ 1071 if (rfs->old_fs->group_desc_count >= fs->group_desc_count) { 1072 retval = 0; 1073 goto errout; 1074 } 1075 1076 /* 1077 * If we are using uninit_bg (aka GDT_CSUM) and the kernel 1078 * supports lazy inode initialization, we can skip 1079 * initializing the inode table. 1080 */ 1081 if (lazy_itable_init && ext2fs_has_group_desc_csum(fs)) { 1082 retval = 0; 1083 goto errout; 1084 } 1085 1086 /* 1087 * Initialize the inode table 1088 */ 1089 retval = ext2fs_get_array(fs->blocksize, fs->inode_blocks_per_group, 1090 &rfs->itable_buf); 1091 if (retval) 1092 goto errout; 1093 1094 memset(rfs->itable_buf, 0, fs->blocksize * fs->inode_blocks_per_group); 1095 group_block = ext2fs_group_first_block2(fs, 1096 rfs->old_fs->group_desc_count); 1097 adj = rfs->old_fs->group_desc_count; 1098 max_group = fs->group_desc_count - adj; 1099 if (rfs->progress) { 1100 retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS, 1101 0, max_group); 1102 if (retval) 1103 goto errout; 1104 } 1105 for (i = rfs->old_fs->group_desc_count; 1106 i < fs->group_desc_count; i++) { 1107 /* 1108 * Write out the new inode table 1109 */ 1110 retval = ext2fs_zero_blocks2(fs, ext2fs_inode_table_loc(fs, i), 1111 fs->inode_blocks_per_group, NULL, 1112 NULL); 1113 if (retval) 1114 goto errout; 1115 1116 io_channel_flush(fs->io); 1117 if (rfs->progress) { 1118 retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS, 1119 i - adj + 1, max_group); 1120 if (retval) 1121 goto errout; 1122 } 1123 group_block += fs->super->s_blocks_per_group; 1124 } 1125 io_channel_flush(fs->io); 1126 retval = 0; 1127 1128 errout: 1129 return retval; 1130 } 1131 1132 /* -------------------------------------------------------------------- 1133 * 1134 * Resize processing, phase 2. 1135 * 1136 * In this phase we adjust determine which blocks need to be moved, in 1137 * blocks_to_move(). We then copy the blocks to their ultimate new 1138 * destinations using block_mover(). Since we are copying blocks to 1139 * their new locations, again during this pass we can abort without 1140 * any problems. 1141 * -------------------------------------------------------------------- 1142 */ 1143 1144 /* 1145 * This helper function creates a block bitmap with all of the 1146 * filesystem meta-data blocks. 1147 */ 1148 static errcode_t mark_table_blocks(ext2_filsys fs, 1149 ext2fs_block_bitmap bmap) 1150 { 1151 dgrp_t i; 1152 blk64_t blk; 1153 1154 for (i = 0; i < fs->group_desc_count; i++) { 1155 ext2fs_reserve_super_and_bgd(fs, i, bmap); 1156 1157 /* 1158 * Mark the blocks used for the inode table 1159 */ 1160 blk = ext2fs_inode_table_loc(fs, i); 1161 if (blk) 1162 ext2fs_mark_block_bitmap_range2(bmap, blk, 1163 fs->inode_blocks_per_group); 1164 1165 /* 1166 * Mark block used for the block bitmap 1167 */ 1168 blk = ext2fs_block_bitmap_loc(fs, i); 1169 if (blk) 1170 ext2fs_mark_block_bitmap2(bmap, blk); 1171 1172 /* 1173 * Mark block used for the inode bitmap 1174 */ 1175 blk = ext2fs_inode_bitmap_loc(fs, i); 1176 if (blk) 1177 ext2fs_mark_block_bitmap2(bmap, blk); 1178 } 1179 return 0; 1180 } 1181 1182 /* 1183 * This function checks to see if a particular block (either a 1184 * superblock or a block group descriptor) overlaps with an inode or 1185 * block bitmap block, or with the inode table. 1186 */ 1187 static void mark_fs_metablock(ext2_resize_t rfs, 1188 ext2fs_block_bitmap meta_bmap, 1189 int group, blk64_t blk) 1190 { 1191 ext2_filsys fs = rfs->new_fs; 1192 1193 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 1194 ext2fs_block_alloc_stats2(fs, blk, +1); 1195 1196 /* 1197 * Check to see if we overlap with the inode or block bitmap, 1198 * or the inode tables. If not, and the block is in use, then 1199 * mark it as a block to be moved. 1200 */ 1201 if (is_block_bm(fs, group, blk)) { 1202 ext2fs_block_bitmap_loc_set(fs, group, 0); 1203 rfs->needed_blocks++; 1204 return; 1205 } 1206 if (is_inode_bm(fs, group, blk)) { 1207 ext2fs_inode_bitmap_loc_set(fs, group, 0); 1208 rfs->needed_blocks++; 1209 return; 1210 } 1211 if (is_inode_tb(fs, group, blk)) { 1212 ext2fs_inode_table_loc_set(fs, group, 0); 1213 rfs->needed_blocks++; 1214 return; 1215 } 1216 if (ext2fs_has_feature_flex_bg(fs->super)) { 1217 dgrp_t i; 1218 1219 for (i = 0; i < rfs->old_fs->group_desc_count; i++) { 1220 if (is_block_bm(fs, i, blk)) { 1221 ext2fs_block_bitmap_loc_set(fs, i, 0); 1222 rfs->needed_blocks++; 1223 return; 1224 } 1225 if (is_inode_bm(fs, i, blk)) { 1226 ext2fs_inode_bitmap_loc_set(fs, i, 0); 1227 rfs->needed_blocks++; 1228 return; 1229 } 1230 if (is_inode_tb(fs, i, blk)) { 1231 ext2fs_inode_table_loc_set(fs, i, 0); 1232 rfs->needed_blocks++; 1233 return; 1234 } 1235 } 1236 } 1237 1238 if (ext2fs_has_group_desc_csum(fs) && 1239 (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT))) { 1240 /* 1241 * If the block bitmap is uninitialized, which means 1242 * nothing other than standard metadata in use. 1243 */ 1244 return; 1245 } else if (ext2fs_test_block_bitmap2(rfs->old_fs->block_map, blk) && 1246 !ext2fs_test_block_bitmap2(meta_bmap, blk)) { 1247 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk); 1248 rfs->needed_blocks++; 1249 } 1250 } 1251 1252 1253 /* 1254 * This routine marks and unmarks reserved blocks in the new block 1255 * bitmap. It also determines which blocks need to be moved and 1256 * places this information into the move_blocks bitmap. 1257 */ 1258 static errcode_t blocks_to_move(ext2_resize_t rfs) 1259 { 1260 unsigned int j; 1261 int has_super; 1262 dgrp_t i, max_groups, g; 1263 blk64_t blk, group_blk; 1264 blk64_t old_blocks, new_blocks, group_end, cluster_freed; 1265 blk64_t new_size; 1266 unsigned int meta_bg, meta_bg_size; 1267 errcode_t retval; 1268 ext2_filsys fs, old_fs; 1269 ext2fs_block_bitmap meta_bmap, new_meta_bmap = NULL; 1270 int flex_bg; 1271 1272 fs = rfs->new_fs; 1273 old_fs = rfs->old_fs; 1274 if (ext2fs_blocks_count(old_fs->super) > ext2fs_blocks_count(fs->super)) 1275 fs = rfs->old_fs; 1276 1277 retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"), 1278 &rfs->move_blocks); 1279 if (retval) 1280 return retval; 1281 1282 retval = ext2fs_allocate_block_bitmap(fs, _("meta-data blocks"), 1283 &meta_bmap); 1284 if (retval) 1285 return retval; 1286 1287 retval = mark_table_blocks(old_fs, meta_bmap); 1288 if (retval) 1289 return retval; 1290 1291 fs = rfs->new_fs; 1292 1293 /* 1294 * If we're shrinking the filesystem, we need to move any 1295 * group's metadata blocks (either allocation bitmaps or the 1296 * inode table) which are beyond the end of the new 1297 * filesystem. 1298 */ 1299 new_size = ext2fs_blocks_count(fs->super); 1300 if (new_size < ext2fs_blocks_count(old_fs->super)) { 1301 for (g = 0; g < fs->group_desc_count; g++) { 1302 int realloc = 0; 1303 /* 1304 * ext2fs_allocate_group_table will re-allocate any 1305 * metadata blocks whose location is set to zero. 1306 */ 1307 if (ext2fs_block_bitmap_loc(fs, g) >= new_size) { 1308 ext2fs_block_bitmap_loc_set(fs, g, 0); 1309 realloc = 1; 1310 } 1311 if (ext2fs_inode_bitmap_loc(fs, g) >= new_size) { 1312 ext2fs_inode_bitmap_loc_set(fs, g, 0); 1313 realloc = 1; 1314 } 1315 if ((ext2fs_inode_table_loc(fs, g) + 1316 fs->inode_blocks_per_group) > new_size) { 1317 ext2fs_inode_table_loc_set(fs, g, 0); 1318 realloc = 1; 1319 } 1320 1321 if (realloc) { 1322 retval = ext2fs_allocate_group_table(fs, g, 0); 1323 if (retval) 1324 return retval; 1325 } 1326 } 1327 } 1328 1329 /* 1330 * If we're shrinking the filesystem, we need to move all of 1331 * the blocks that don't fit any more 1332 */ 1333 for (blk = ext2fs_blocks_count(fs->super); 1334 blk < ext2fs_blocks_count(old_fs->super); blk++) { 1335 g = ext2fs_group_of_blk2(fs, blk); 1336 if (ext2fs_has_group_desc_csum(fs) && 1337 ext2fs_bg_flags_test(old_fs, g, EXT2_BG_BLOCK_UNINIT)) { 1338 /* 1339 * The block bitmap is uninitialized, so skip 1340 * to the next block group. 1341 */ 1342 blk = ext2fs_group_first_block2(fs, g+1) - 1; 1343 continue; 1344 } 1345 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1346 !ext2fs_test_block_bitmap2(meta_bmap, blk)) { 1347 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk); 1348 rfs->needed_blocks++; 1349 } 1350 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 1351 } 1352 1353 if (ext2fs_has_feature_meta_bg(old_fs->super)) 1354 old_blocks = old_fs->super->s_first_meta_bg; 1355 else 1356 old_blocks = old_fs->desc_blocks + 1357 old_fs->super->s_reserved_gdt_blocks; 1358 if (ext2fs_has_feature_meta_bg(fs->super)) 1359 new_blocks = fs->super->s_first_meta_bg; 1360 else 1361 new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks; 1362 1363 retval = reserve_sparse_super2_last_group(rfs, meta_bmap); 1364 if (retval) 1365 goto errout; 1366 1367 if (EXT2_DESC_SIZE(rfs->old_fs->super) == 1368 EXT2_DESC_SIZE(rfs->new_fs->super) && 1369 old_blocks == new_blocks) { 1370 retval = 0; 1371 goto errout; 1372 } 1373 1374 max_groups = fs->group_desc_count; 1375 if (max_groups > old_fs->group_desc_count) 1376 max_groups = old_fs->group_desc_count; 1377 group_blk = old_fs->super->s_first_data_block; 1378 /* 1379 * If we're reducing the number of descriptor blocks, this 1380 * makes life easy. :-) We just have to mark some extra 1381 * blocks as free. 1382 */ 1383 if (old_blocks > new_blocks) { 1384 if (EXT2FS_CLUSTER_RATIO(fs) > 1) { 1385 retval = ext2fs_allocate_block_bitmap(fs, 1386 _("new meta blocks"), 1387 &new_meta_bmap); 1388 if (retval) 1389 goto errout; 1390 1391 retval = mark_table_blocks(fs, new_meta_bmap); 1392 if (retval) 1393 goto errout; 1394 } 1395 1396 for (i = 0; i < max_groups; i++) { 1397 if (!ext2fs_bg_has_super(old_fs, i)) { 1398 group_blk += fs->super->s_blocks_per_group; 1399 continue; 1400 } 1401 group_end = group_blk + 1 + old_blocks; 1402 for (blk = group_blk + 1 + new_blocks; 1403 blk < group_end;) { 1404 if (new_meta_bmap == NULL || 1405 !ext2fs_test_block_bitmap2(new_meta_bmap, 1406 blk)) { 1407 cluster_freed = 1408 EXT2FS_CLUSTER_RATIO(fs) - 1409 (blk & 1410 EXT2FS_CLUSTER_MASK(fs)); 1411 if (cluster_freed > group_end - blk) 1412 cluster_freed = group_end - blk; 1413 ext2fs_block_alloc_stats2(fs, blk, -1); 1414 blk += EXT2FS_CLUSTER_RATIO(fs); 1415 rfs->needed_blocks -= cluster_freed; 1416 continue; 1417 } 1418 rfs->needed_blocks--; 1419 blk++; 1420 } 1421 group_blk += fs->super->s_blocks_per_group; 1422 } 1423 retval = 0; 1424 goto errout; 1425 } 1426 /* 1427 * If we're increasing the number of descriptor blocks, life 1428 * gets interesting.... 1429 */ 1430 meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super); 1431 flex_bg = ext2fs_has_feature_flex_bg(fs->super); 1432 /* first reserve all of the existing fs meta blocks */ 1433 for (i = 0; i < max_groups; i++) { 1434 has_super = ext2fs_bg_has_super(fs, i); 1435 if (has_super) 1436 mark_fs_metablock(rfs, meta_bmap, i, group_blk); 1437 1438 meta_bg = i / meta_bg_size; 1439 if (!ext2fs_has_feature_meta_bg(fs->super) || 1440 (meta_bg < fs->super->s_first_meta_bg)) { 1441 if (has_super) { 1442 for (blk = group_blk+1; 1443 blk < group_blk + 1 + new_blocks; blk++) 1444 mark_fs_metablock(rfs, meta_bmap, 1445 i, blk); 1446 } 1447 } else { 1448 if (has_super) 1449 has_super = 1; 1450 if (((i % meta_bg_size) == 0) || 1451 ((i % meta_bg_size) == 1) || 1452 ((i % meta_bg_size) == (meta_bg_size-1))) 1453 mark_fs_metablock(rfs, meta_bmap, i, 1454 group_blk + has_super); 1455 } 1456 1457 /* 1458 * Reserve the existing meta blocks that we know 1459 * aren't to be moved. 1460 * 1461 * For flex_bg file systems, in order to avoid 1462 * overwriting fs metadata (especially inode table 1463 * blocks) belonging to a different block group when 1464 * we are relocating the inode tables, we need to 1465 * reserve all existing fs metadata blocks. 1466 */ 1467 if (ext2fs_block_bitmap_loc(fs, i)) 1468 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1469 ext2fs_block_bitmap_loc(fs, i)); 1470 else if (flex_bg && i < old_fs->group_desc_count) 1471 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1472 ext2fs_block_bitmap_loc(old_fs, i)); 1473 1474 if (ext2fs_inode_bitmap_loc(fs, i)) 1475 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1476 ext2fs_inode_bitmap_loc(fs, i)); 1477 else if (flex_bg && i < old_fs->group_desc_count) 1478 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1479 ext2fs_inode_bitmap_loc(old_fs, i)); 1480 1481 if (ext2fs_inode_table_loc(fs, i)) 1482 ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks, 1483 ext2fs_inode_table_loc(fs, i), 1484 fs->inode_blocks_per_group); 1485 else if (flex_bg && i < old_fs->group_desc_count) 1486 ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks, 1487 ext2fs_inode_table_loc(old_fs, i), 1488 old_fs->inode_blocks_per_group); 1489 1490 group_blk += rfs->new_fs->super->s_blocks_per_group; 1491 } 1492 1493 /* Allocate the missing data structures */ 1494 for (i = 0; i < max_groups; i++) { 1495 if (ext2fs_inode_table_loc(fs, i) && 1496 ext2fs_inode_bitmap_loc(fs, i) && 1497 ext2fs_block_bitmap_loc(fs, i)) 1498 continue; 1499 1500 retval = ext2fs_allocate_group_table(fs, i, 1501 rfs->reserve_blocks); 1502 if (retval) 1503 goto errout; 1504 1505 /* 1506 * For those structures that have changed, we need to 1507 * do bookkeeping. 1508 */ 1509 if (ext2fs_block_bitmap_loc(old_fs, i) != 1510 (blk = ext2fs_block_bitmap_loc(fs, i))) { 1511 ext2fs_block_alloc_stats2(fs, blk, +1); 1512 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1513 !ext2fs_test_block_bitmap2(meta_bmap, blk)) 1514 ext2fs_mark_block_bitmap2(rfs->move_blocks, 1515 blk); 1516 } 1517 if (ext2fs_inode_bitmap_loc(old_fs, i) != 1518 (blk = ext2fs_inode_bitmap_loc(fs, i))) { 1519 ext2fs_block_alloc_stats2(fs, blk, +1); 1520 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1521 !ext2fs_test_block_bitmap2(meta_bmap, blk)) 1522 ext2fs_mark_block_bitmap2(rfs->move_blocks, 1523 blk); 1524 } 1525 1526 /* 1527 * The inode table, if we need to relocate it, is 1528 * handled specially. We have to reserve the blocks 1529 * for both the old and the new inode table, since we 1530 * can't have the inode table be destroyed during the 1531 * block relocation phase. 1532 */ 1533 if (ext2fs_inode_table_loc(fs, i) == ext2fs_inode_table_loc(old_fs, i)) 1534 continue; /* inode table not moved */ 1535 1536 rfs->needed_blocks += fs->inode_blocks_per_group; 1537 1538 /* 1539 * Mark the new inode table as in use in the new block 1540 * allocation bitmap, and move any blocks that might 1541 * be necessary. 1542 */ 1543 for (blk = ext2fs_inode_table_loc(fs, i), j=0; 1544 j < fs->inode_blocks_per_group ; j++, blk++) { 1545 ext2fs_block_alloc_stats2(fs, blk, +1); 1546 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1547 !ext2fs_test_block_bitmap2(meta_bmap, blk)) 1548 ext2fs_mark_block_bitmap2(rfs->move_blocks, 1549 blk); 1550 } 1551 1552 /* 1553 * Make sure the old inode table is reserved in the 1554 * block reservation bitmap. 1555 */ 1556 for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0; 1557 j < fs->inode_blocks_per_group ; j++, blk++) 1558 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 1559 } 1560 retval = 0; 1561 1562 errout: 1563 if (new_meta_bmap) 1564 ext2fs_free_block_bitmap(new_meta_bmap); 1565 if (meta_bmap) 1566 ext2fs_free_block_bitmap(meta_bmap); 1567 1568 return retval; 1569 } 1570 1571 /* 1572 * This helper function tries to allocate a new block. We try to 1573 * avoid hitting the original group descriptor blocks at least at 1574 * first, since we want to make it possible to recover from a badly 1575 * aborted resize operation as much as possible. 1576 * 1577 * In the future, I may further modify this routine to balance out 1578 * where we get the new blocks across the various block groups. 1579 * Ideally we would allocate blocks that corresponded with the block 1580 * group of the containing inode, and keep contiguous blocks 1581 * together. However, this very difficult to do efficiently, since we 1582 * don't have the necessary information up front. 1583 */ 1584 1585 #define AVOID_OLD 1 1586 #define DESPERATION 2 1587 1588 static void init_block_alloc(ext2_resize_t rfs) 1589 { 1590 rfs->alloc_state = AVOID_OLD; 1591 rfs->new_blk = rfs->new_fs->super->s_first_data_block; 1592 #if 0 1593 /* HACK for testing */ 1594 if (ext2fs_blocks_count(rfs->new_fs->super) > 1595 ext2fs_blocks_count(rfs->old_fs->super)) 1596 rfs->new_blk = ext2fs_blocks_count(rfs->old_fs->super); 1597 #endif 1598 } 1599 1600 static blk64_t get_new_block(ext2_resize_t rfs) 1601 { 1602 ext2_filsys fs = rfs->new_fs; 1603 1604 while (1) { 1605 if (rfs->new_blk >= ext2fs_blocks_count(fs->super)) { 1606 if (rfs->alloc_state == DESPERATION) 1607 return 0; 1608 1609 #ifdef RESIZE2FS_DEBUG 1610 if (rfs->flags & RESIZE_DEBUG_BMOVE) 1611 printf("Going into desperation mode " 1612 "for block allocations\n"); 1613 #endif 1614 rfs->alloc_state = DESPERATION; 1615 rfs->new_blk = fs->super->s_first_data_block; 1616 continue; 1617 } 1618 if (ext2fs_test_block_bitmap2(fs->block_map, rfs->new_blk) || 1619 ext2fs_test_block_bitmap2(rfs->reserve_blocks, 1620 rfs->new_blk) || 1621 ((rfs->alloc_state == AVOID_OLD) && 1622 (rfs->new_blk < ext2fs_blocks_count(rfs->old_fs->super)) && 1623 ext2fs_test_block_bitmap2(rfs->old_fs->block_map, 1624 rfs->new_blk))) { 1625 rfs->new_blk++; 1626 continue; 1627 } 1628 return rfs->new_blk; 1629 } 1630 } 1631 1632 static errcode_t resize2fs_get_alloc_block(ext2_filsys fs, 1633 blk64_t goal EXT2FS_ATTR((unused)), 1634 blk64_t *ret) 1635 { 1636 ext2_resize_t rfs = (ext2_resize_t) fs->priv_data; 1637 blk64_t blk; 1638 int group; 1639 1640 blk = get_new_block(rfs); 1641 if (!blk) 1642 return ENOSPC; 1643 1644 #ifdef RESIZE2FS_DEBUG 1645 if (rfs->flags & 0xF) 1646 printf("get_alloc_block allocating %llu\n", blk); 1647 #endif 1648 1649 ext2fs_mark_block_bitmap2(rfs->old_fs->block_map, blk); 1650 ext2fs_mark_block_bitmap2(rfs->new_fs->block_map, blk); 1651 1652 group = ext2fs_group_of_blk2(rfs->old_fs, blk); 1653 ext2fs_clear_block_uninit(rfs->old_fs, group); 1654 group = ext2fs_group_of_blk2(rfs->new_fs, blk); 1655 ext2fs_clear_block_uninit(rfs->new_fs, group); 1656 1657 *ret = (blk64_t) blk; 1658 return 0; 1659 } 1660 1661 static errcode_t block_mover(ext2_resize_t rfs) 1662 { 1663 blk64_t blk, old_blk, new_blk; 1664 ext2_filsys fs = rfs->new_fs; 1665 ext2_filsys old_fs = rfs->old_fs; 1666 errcode_t retval; 1667 __u64 c, size; 1668 int to_move, moved; 1669 ext2_badblocks_list badblock_list = 0; 1670 int bb_modified = 0; 1671 1672 fs->get_alloc_block = resize2fs_get_alloc_block; 1673 old_fs->get_alloc_block = resize2fs_get_alloc_block; 1674 1675 retval = ext2fs_read_bb_inode(old_fs, &badblock_list); 1676 if (retval) 1677 return retval; 1678 1679 new_blk = fs->super->s_first_data_block; 1680 if (!rfs->itable_buf) { 1681 retval = ext2fs_get_array(fs->blocksize, 1682 fs->inode_blocks_per_group, 1683 &rfs->itable_buf); 1684 if (retval) 1685 return retval; 1686 } 1687 retval = ext2fs_create_extent_table(&rfs->bmap, 0); 1688 if (retval) 1689 return retval; 1690 1691 /* 1692 * The first step is to figure out where all of the blocks 1693 * will go. 1694 */ 1695 to_move = moved = 0; 1696 init_block_alloc(rfs); 1697 for (blk = B2C(old_fs->super->s_first_data_block); 1698 blk < ext2fs_blocks_count(old_fs->super); 1699 blk += EXT2FS_CLUSTER_RATIO(fs)) { 1700 if (!ext2fs_test_block_bitmap2(old_fs->block_map, blk)) 1701 continue; 1702 if (!ext2fs_test_block_bitmap2(rfs->move_blocks, blk)) 1703 continue; 1704 if (ext2fs_badblocks_list_test(badblock_list, blk)) { 1705 ext2fs_badblocks_list_del(badblock_list, blk); 1706 bb_modified++; 1707 continue; 1708 } 1709 1710 new_blk = get_new_block(rfs); 1711 if (!new_blk) { 1712 retval = ENOSPC; 1713 goto errout; 1714 } 1715 ext2fs_block_alloc_stats2(fs, new_blk, +1); 1716 ext2fs_add_extent_entry(rfs->bmap, B2C(blk), B2C(new_blk)); 1717 to_move++; 1718 } 1719 1720 if (to_move == 0) { 1721 if (rfs->bmap) { 1722 ext2fs_free_extent_table(rfs->bmap); 1723 rfs->bmap = 0; 1724 } 1725 retval = 0; 1726 goto errout; 1727 } 1728 1729 /* 1730 * Step two is to actually move the blocks 1731 */ 1732 retval = ext2fs_iterate_extent(rfs->bmap, 0, 0, 0); 1733 if (retval) goto errout; 1734 1735 if (rfs->progress) { 1736 retval = (rfs->progress)(rfs, E2_RSZ_BLOCK_RELOC_PASS, 1737 0, to_move); 1738 if (retval) 1739 goto errout; 1740 } 1741 while (1) { 1742 retval = ext2fs_iterate_extent(rfs->bmap, &old_blk, &new_blk, &size); 1743 if (retval) goto errout; 1744 if (!size) 1745 break; 1746 old_blk = C2B(old_blk); 1747 new_blk = C2B(new_blk); 1748 size = C2B(size); 1749 #ifdef RESIZE2FS_DEBUG 1750 if (rfs->flags & RESIZE_DEBUG_BMOVE) 1751 printf("Moving %llu blocks %llu->%llu\n", 1752 size, old_blk, new_blk); 1753 #endif 1754 do { 1755 c = size; 1756 if (c > fs->inode_blocks_per_group) 1757 c = fs->inode_blocks_per_group; 1758 retval = io_channel_read_blk64(fs->io, old_blk, c, 1759 rfs->itable_buf); 1760 if (retval) goto errout; 1761 retval = io_channel_write_blk64(fs->io, new_blk, c, 1762 rfs->itable_buf); 1763 if (retval) goto errout; 1764 size -= c; 1765 new_blk += c; 1766 old_blk += c; 1767 moved += c; 1768 if (rfs->progress) { 1769 io_channel_flush(fs->io); 1770 retval = (rfs->progress)(rfs, 1771 E2_RSZ_BLOCK_RELOC_PASS, 1772 moved, to_move); 1773 if (retval) 1774 goto errout; 1775 } 1776 } while (size > 0); 1777 io_channel_flush(fs->io); 1778 } 1779 1780 errout: 1781 if (badblock_list) { 1782 if (!retval && bb_modified) 1783 retval = ext2fs_update_bb_inode(old_fs, 1784 badblock_list); 1785 ext2fs_badblocks_list_free(badblock_list); 1786 } 1787 return retval; 1788 } 1789 1790 1791 /* -------------------------------------------------------------------- 1792 * 1793 * Resize processing, phase 3 1794 * 1795 * -------------------------------------------------------------------- 1796 */ 1797 1798 1799 /* 1800 * The extent translation table is stored in clusters so we need to 1801 * take special care when mapping a source block number to its 1802 * destination block number. 1803 */ 1804 static __u64 extent_translate(ext2_filsys fs, ext2_extent extent, __u64 old_loc) 1805 { 1806 __u64 new_block = C2B(ext2fs_extent_translate(extent, B2C(old_loc))); 1807 1808 if (new_block != 0) 1809 new_block += old_loc & (EXT2FS_CLUSTER_RATIO(fs) - 1); 1810 return new_block; 1811 } 1812 1813 struct process_block_struct { 1814 ext2_resize_t rfs; 1815 ext2_ino_t ino; 1816 ext2_ino_t old_ino; 1817 struct ext2_inode * inode; 1818 errcode_t error; 1819 int is_dir; 1820 int changed; 1821 int has_extents; 1822 }; 1823 1824 static int process_block(ext2_filsys fs, blk64_t *block_nr, 1825 e2_blkcnt_t blockcnt, 1826 blk64_t ref_block EXT2FS_ATTR((unused)), 1827 int ref_offset EXT2FS_ATTR((unused)), void *priv_data) 1828 { 1829 struct process_block_struct *pb; 1830 errcode_t retval; 1831 blk64_t block, new_block; 1832 int ret = 0; 1833 1834 pb = (struct process_block_struct *) priv_data; 1835 block = *block_nr; 1836 if (pb->rfs->bmap) { 1837 new_block = extent_translate(fs, pb->rfs->bmap, block); 1838 if (new_block) { 1839 *block_nr = new_block; 1840 ret |= BLOCK_CHANGED; 1841 pb->changed = 1; 1842 #ifdef RESIZE2FS_DEBUG 1843 if (pb->rfs->flags & RESIZE_DEBUG_BMOVE) 1844 printf("ino=%u, blockcnt=%lld, %llu->%llu\n", 1845 pb->old_ino, blockcnt, block, 1846 new_block); 1847 #endif 1848 block = new_block; 1849 } 1850 } 1851 1852 if (pb->is_dir) { 1853 retval = ext2fs_add_dir_block2(fs->dblist, pb->ino, 1854 block, (int) blockcnt); 1855 if (retval) { 1856 pb->error = retval; 1857 ret |= BLOCK_ABORT; 1858 } 1859 } 1860 return ret; 1861 } 1862 1863 /* 1864 * Progress callback 1865 */ 1866 static errcode_t progress_callback(ext2_filsys fs, 1867 ext2_inode_scan scan EXT2FS_ATTR((unused)), 1868 dgrp_t group, void * priv_data) 1869 { 1870 ext2_resize_t rfs = (ext2_resize_t) priv_data; 1871 errcode_t retval; 1872 1873 /* 1874 * This check is to protect against old ext2 libraries. It 1875 * shouldn't be needed against new libraries. 1876 */ 1877 if ((group+1) == 0) 1878 return 0; 1879 1880 if (rfs->progress) { 1881 io_channel_flush(fs->io); 1882 retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS, 1883 group+1, fs->group_desc_count); 1884 if (retval) 1885 return retval; 1886 } 1887 1888 return 0; 1889 } 1890 1891 static errcode_t migrate_ea_block(ext2_resize_t rfs, ext2_ino_t ino, 1892 struct ext2_inode *inode, int *changed) 1893 { 1894 char *buf = NULL; 1895 blk64_t new_block; 1896 errcode_t err = 0; 1897 1898 /* No EA block or no remapping? Quit early. */ 1899 if (ext2fs_file_acl_block(rfs->old_fs, inode) == 0 || !rfs->bmap) 1900 return 0; 1901 new_block = extent_translate(rfs->old_fs, rfs->bmap, 1902 ext2fs_file_acl_block(rfs->old_fs, inode)); 1903 if (new_block == 0) 1904 return 0; 1905 1906 /* Set the new ACL block */ 1907 ext2fs_file_acl_block_set(rfs->old_fs, inode, new_block); 1908 1909 /* Update checksum */ 1910 if (ext2fs_has_feature_metadata_csum(rfs->new_fs->super)) { 1911 err = ext2fs_get_mem(rfs->old_fs->blocksize, &buf); 1912 if (err) 1913 return err; 1914 rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; 1915 err = ext2fs_read_ext_attr3(rfs->old_fs, new_block, buf, ino); 1916 rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS; 1917 if (err) 1918 goto out; 1919 err = ext2fs_write_ext_attr3(rfs->old_fs, new_block, buf, ino); 1920 if (err) 1921 goto out; 1922 } 1923 *changed = 1; 1924 1925 out: 1926 ext2fs_free_mem(&buf); 1927 return err; 1928 } 1929 1930 /* Rewrite extents */ 1931 static errcode_t rewrite_extents(ext2_filsys fs, ext2_ino_t ino) 1932 { 1933 ext2_extent_handle_t handle; 1934 struct ext2fs_extent extent; 1935 errcode_t errcode; 1936 struct ext2_extent_info info; 1937 1938 errcode = ext2fs_extent_open(fs, ino, &handle); 1939 if (errcode) 1940 return errcode; 1941 1942 errcode = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent); 1943 if (errcode) 1944 goto out; 1945 1946 do { 1947 errcode = ext2fs_extent_get_info(handle, &info); 1948 if (errcode) 1949 break; 1950 1951 /* 1952 * If this is the first extent in an extent block that we 1953 * haven't visited, rewrite the extent to force the ETB 1954 * checksum to be rewritten. 1955 */ 1956 if (info.curr_entry == 1 && info.curr_level != 0 && 1957 !(extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)) { 1958 errcode = ext2fs_extent_replace(handle, 0, &extent); 1959 if (errcode) 1960 break; 1961 } 1962 1963 /* Skip to the end of a block of leaf nodes */ 1964 if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) { 1965 errcode = ext2fs_extent_get(handle, 1966 EXT2_EXTENT_LAST_SIB, 1967 &extent); 1968 if (errcode) 1969 break; 1970 } 1971 1972 errcode = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT, &extent); 1973 } while (errcode == 0); 1974 1975 out: 1976 /* Ok if we run off the end */ 1977 if (errcode == EXT2_ET_EXTENT_NO_NEXT) 1978 errcode = 0; 1979 ext2fs_extent_free(handle); 1980 return errcode; 1981 } 1982 1983 static void quiet_com_err_proc(const char *whoami EXT2FS_ATTR((unused)), 1984 errcode_t code EXT2FS_ATTR((unused)), 1985 const char *fmt EXT2FS_ATTR((unused)), 1986 va_list args EXT2FS_ATTR((unused))) 1987 { 1988 } 1989 1990 static int fix_ea_entries(ext2_extent imap, struct ext2_ext_attr_entry *entry, 1991 struct ext2_ext_attr_entry *end, ext2_ino_t last_ino) 1992 { 1993 int modified = 0; 1994 ext2_ino_t new_ino; 1995 1996 while (entry < end && !EXT2_EXT_IS_LAST_ENTRY(entry)) { 1997 if (entry->e_value_inum > last_ino) { 1998 new_ino = ext2fs_extent_translate(imap, 1999 entry->e_value_inum); 2000 entry->e_value_inum = new_ino; 2001 modified = 1; 2002 } 2003 entry = EXT2_EXT_ATTR_NEXT(entry); 2004 } 2005 return modified; 2006 } 2007 2008 static int fix_ea_ibody_entries(ext2_extent imap, 2009 struct ext2_inode_large *inode, int inode_size, 2010 ext2_ino_t last_ino) 2011 { 2012 struct ext2_ext_attr_entry *start, *end; 2013 __u32 *ea_magic; 2014 2015 if (inode->i_extra_isize == 0) 2016 return 0; 2017 2018 ea_magic = (__u32 *)((char *)inode + EXT2_GOOD_OLD_INODE_SIZE + 2019 inode->i_extra_isize); 2020 if (*ea_magic != EXT2_EXT_ATTR_MAGIC) 2021 return 0; 2022 2023 start = (struct ext2_ext_attr_entry *)(ea_magic + 1); 2024 end = (struct ext2_ext_attr_entry *)((char *)inode + inode_size); 2025 2026 return fix_ea_entries(imap, start, end, last_ino); 2027 } 2028 2029 static int fix_ea_block_entries(ext2_extent imap, char *block_buf, 2030 unsigned int blocksize, ext2_ino_t last_ino) 2031 { 2032 struct ext2_ext_attr_header *header; 2033 struct ext2_ext_attr_entry *start, *end; 2034 2035 header = (struct ext2_ext_attr_header *)block_buf; 2036 start = (struct ext2_ext_attr_entry *)(header+1); 2037 end = (struct ext2_ext_attr_entry *)(block_buf + blocksize); 2038 2039 return fix_ea_entries(imap, start, end, last_ino); 2040 } 2041 2042 /* A simple LRU cache to check recently processed blocks. */ 2043 struct blk_cache { 2044 int cursor; 2045 blk64_t blks[4]; 2046 }; 2047 2048 #define BLK_IN_CACHE(b,c) ((b) == (c).blks[0] || (b) == (c).blks[1] || \ 2049 (b) == (c).blks[2] || (b) == (c).blks[3]) 2050 #define BLK_ADD_CACHE(b,c) { \ 2051 (c).blks[(c).cursor] = (b); \ 2052 (c).cursor = ((c).cursor + 1) % 4; \ 2053 } 2054 2055 static errcode_t fix_ea_inode_refs(ext2_resize_t rfs, struct ext2_inode *inode, 2056 char *block_buf, ext2_ino_t last_ino) 2057 { 2058 ext2_filsys fs = rfs->new_fs; 2059 ext2_inode_scan scan = NULL; 2060 ext2_ino_t ino; 2061 int inode_size = EXT2_INODE_SIZE(fs->super); 2062 blk64_t blk; 2063 int modified; 2064 struct blk_cache blk_cache; 2065 struct ext2_ext_attr_header *header; 2066 errcode_t retval; 2067 2068 memset(&blk_cache, 0, sizeof(blk_cache)); 2069 2070 header = (struct ext2_ext_attr_header *)block_buf; 2071 2072 retval = ext2fs_open_inode_scan(fs, 0, &scan); 2073 if (retval) 2074 goto out; 2075 2076 while (1) { 2077 retval = ext2fs_get_next_inode_full(scan, &ino, inode, 2078 inode_size); 2079 if (retval) 2080 goto out; 2081 if (!ino) 2082 break; 2083 2084 if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO) 2085 continue; /* inode not in use */ 2086 2087 if (inode_size != EXT2_GOOD_OLD_INODE_SIZE) { 2088 modified = fix_ea_ibody_entries(rfs->imap, 2089 (struct ext2_inode_large *)inode, 2090 inode_size, last_ino); 2091 if (modified) { 2092 retval = ext2fs_write_inode_full(fs, ino, inode, 2093 inode_size); 2094 if (retval) 2095 goto out; 2096 } 2097 } 2098 2099 blk = ext2fs_file_acl_block(fs, inode); 2100 if (blk && !BLK_IN_CACHE(blk, blk_cache)) { 2101 retval = ext2fs_read_ext_attr3(fs, blk, block_buf, ino); 2102 if (retval) 2103 goto out; 2104 2105 modified = fix_ea_block_entries(rfs->imap, block_buf, 2106 fs->blocksize, 2107 last_ino); 2108 if (modified) { 2109 retval = ext2fs_write_ext_attr3(fs, blk, 2110 block_buf, ino); 2111 if (retval) 2112 goto out; 2113 /* 2114 * If refcount is greater than 1, we might see 2115 * the same block referenced by other inodes 2116 * later. 2117 */ 2118 if (header->h_refcount > 1) 2119 BLK_ADD_CACHE(blk, blk_cache); 2120 } 2121 } 2122 } 2123 retval = 0; 2124 out: 2125 if (scan) 2126 ext2fs_close_inode_scan(scan); 2127 return retval; 2128 2129 } 2130 static errcode_t inode_scan_and_fix(ext2_resize_t rfs) 2131 { 2132 struct process_block_struct pb; 2133 ext2_ino_t ino, new_inode; 2134 struct ext2_inode *inode = NULL; 2135 ext2_inode_scan scan = NULL; 2136 errcode_t retval; 2137 char *block_buf = 0; 2138 ext2_ino_t start_to_move; 2139 int inode_size; 2140 int update_ea_inode_refs = 0; 2141 2142 if ((rfs->old_fs->group_desc_count <= 2143 rfs->new_fs->group_desc_count) && 2144 !rfs->bmap) 2145 return 0; 2146 2147 set_com_err_hook(quiet_com_err_proc); 2148 2149 retval = ext2fs_open_inode_scan(rfs->old_fs, 0, &scan); 2150 if (retval) goto errout; 2151 2152 retval = ext2fs_init_dblist(rfs->old_fs, 0); 2153 if (retval) goto errout; 2154 retval = ext2fs_get_array(rfs->old_fs->blocksize, 3, &block_buf); 2155 if (retval) goto errout; 2156 2157 start_to_move = (rfs->new_fs->group_desc_count * 2158 rfs->new_fs->super->s_inodes_per_group); 2159 2160 if (rfs->progress) { 2161 retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS, 2162 0, rfs->old_fs->group_desc_count); 2163 if (retval) 2164 goto errout; 2165 } 2166 ext2fs_set_inode_callback(scan, progress_callback, (void *) rfs); 2167 pb.rfs = rfs; 2168 pb.inode = inode; 2169 pb.error = 0; 2170 new_inode = EXT2_FIRST_INODE(rfs->new_fs->super); 2171 inode_size = EXT2_INODE_SIZE(rfs->new_fs->super); 2172 inode = malloc(inode_size); 2173 if (!inode) { 2174 retval = ENOMEM; 2175 goto errout; 2176 } 2177 /* 2178 * First, copy all of the inodes that need to be moved 2179 * elsewhere in the inode table 2180 */ 2181 while (1) { 2182 retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size); 2183 if (retval) goto errout; 2184 if (!ino) 2185 break; 2186 2187 if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO) 2188 continue; /* inode not in use */ 2189 2190 pb.is_dir = LINUX_S_ISDIR(inode->i_mode); 2191 pb.changed = 0; 2192 2193 /* Remap EA block */ 2194 retval = migrate_ea_block(rfs, ino, inode, &pb.changed); 2195 if (retval) 2196 goto errout; 2197 2198 new_inode = ino; 2199 if (ino <= start_to_move) 2200 goto remap_blocks; /* Don't need to move inode. */ 2201 2202 /* 2203 * Find a new inode. Now that extents and directory blocks 2204 * are tied to the inode number through the checksum, we must 2205 * set up the new inode before we start rewriting blocks. 2206 */ 2207 retval = ext2fs_new_inode(rfs->new_fs, 0, 0, 0, &new_inode); 2208 if (retval) 2209 goto errout; 2210 2211 ext2fs_inode_alloc_stats2(rfs->new_fs, new_inode, +1, 2212 pb.is_dir); 2213 /* 2214 * i_ctime field in xattr inodes contain a portion of the ref 2215 * count, do not overwrite. 2216 */ 2217 if (inode->i_flags & EXT4_EA_INODE_FL) 2218 update_ea_inode_refs = 1; 2219 else 2220 inode->i_ctime = time(0); 2221 2222 retval = ext2fs_write_inode_full(rfs->old_fs, new_inode, 2223 inode, inode_size); 2224 if (retval) 2225 goto errout; 2226 pb.changed = 0; 2227 2228 #ifdef RESIZE2FS_DEBUG 2229 if (rfs->flags & RESIZE_DEBUG_INODEMAP) 2230 printf("Inode moved %u->%u\n", ino, new_inode); 2231 #endif 2232 if (!rfs->imap) { 2233 retval = ext2fs_create_extent_table(&rfs->imap, 0); 2234 if (retval) 2235 goto errout; 2236 } 2237 ext2fs_add_extent_entry(rfs->imap, ino, new_inode); 2238 2239 remap_blocks: 2240 if (pb.changed) 2241 retval = ext2fs_write_inode_full(rfs->old_fs, 2242 new_inode, 2243 inode, inode_size); 2244 if (retval) 2245 goto errout; 2246 2247 /* Rewrite extent block checksums with new inode number */ 2248 if (ext2fs_has_feature_metadata_csum(rfs->old_fs->super) && 2249 (inode->i_flags & EXT4_EXTENTS_FL)) { 2250 rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; 2251 retval = rewrite_extents(rfs->old_fs, new_inode); 2252 rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS; 2253 if (retval) 2254 goto errout; 2255 } 2256 2257 /* 2258 * Update inodes to point to new blocks; schedule directory 2259 * blocks for inode remapping. Need to write out dir blocks 2260 * with new inode numbers if we have metadata_csum enabled. 2261 */ 2262 if (ext2fs_inode_has_valid_blocks2(rfs->old_fs, inode) && 2263 (rfs->bmap || pb.is_dir)) { 2264 pb.ino = new_inode; 2265 pb.old_ino = ino; 2266 pb.has_extents = inode->i_flags & EXT4_EXTENTS_FL; 2267 rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; 2268 retval = ext2fs_block_iterate3(rfs->old_fs, 2269 new_inode, 0, block_buf, 2270 process_block, &pb); 2271 rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS; 2272 if (retval) 2273 goto errout; 2274 if (pb.error) { 2275 retval = pb.error; 2276 goto errout; 2277 } 2278 } else if ((inode->i_flags & EXT4_INLINE_DATA_FL) && 2279 (rfs->bmap || pb.is_dir)) { 2280 /* inline data dir; update it too */ 2281 retval = ext2fs_add_dir_block2(rfs->old_fs->dblist, 2282 new_inode, 0, 0); 2283 if (retval) 2284 goto errout; 2285 } 2286 } 2287 2288 if (update_ea_inode_refs && 2289 ext2fs_has_feature_ea_inode(rfs->new_fs->super)) { 2290 retval = fix_ea_inode_refs(rfs, inode, block_buf, 2291 start_to_move); 2292 if (retval) 2293 goto errout; 2294 } 2295 io_channel_flush(rfs->old_fs->io); 2296 2297 errout: 2298 reset_com_err_hook(); 2299 if (rfs->bmap) { 2300 ext2fs_free_extent_table(rfs->bmap); 2301 rfs->bmap = 0; 2302 } 2303 if (scan) 2304 ext2fs_close_inode_scan(scan); 2305 if (block_buf) 2306 ext2fs_free_mem(&block_buf); 2307 free(inode); 2308 return retval; 2309 } 2310 2311 /* -------------------------------------------------------------------- 2312 * 2313 * Resize processing, phase 4. 2314 * 2315 * -------------------------------------------------------------------- 2316 */ 2317 2318 struct istruct { 2319 ext2_resize_t rfs; 2320 errcode_t err; 2321 unsigned int max_dirs; 2322 unsigned int num; 2323 }; 2324 2325 static int check_and_change_inodes(ext2_ino_t dir, 2326 int entry EXT2FS_ATTR((unused)), 2327 struct ext2_dir_entry *dirent, int offset, 2328 int blocksize EXT2FS_ATTR((unused)), 2329 char *buf EXT2FS_ATTR((unused)), 2330 void *priv_data) 2331 { 2332 struct istruct *is = (struct istruct *) priv_data; 2333 struct ext2_inode inode; 2334 ext2_ino_t new_inode; 2335 errcode_t retval; 2336 int ret = 0; 2337 2338 if (is->rfs->progress && offset == 0) { 2339 io_channel_flush(is->rfs->old_fs->io); 2340 is->err = (is->rfs->progress)(is->rfs, 2341 E2_RSZ_INODE_REF_UPD_PASS, 2342 ++is->num, is->max_dirs); 2343 if (is->err) 2344 return DIRENT_ABORT; 2345 } 2346 2347 /* 2348 * If we have checksums enabled and the inode wasn't present in the 2349 * old fs, then we must rewrite all dir blocks with new checksums. 2350 */ 2351 if (ext2fs_has_feature_metadata_csum(is->rfs->old_fs->super) && 2352 !ext2fs_test_inode_bitmap2(is->rfs->old_fs->inode_map, dir)) 2353 ret |= DIRENT_CHANGED; 2354 2355 if (!dirent->inode) 2356 return ret; 2357 2358 new_inode = ext2fs_extent_translate(is->rfs->imap, dirent->inode); 2359 2360 if (!new_inode) 2361 return ret; 2362 #ifdef RESIZE2FS_DEBUG 2363 if (is->rfs->flags & RESIZE_DEBUG_INODEMAP) 2364 printf("Inode translate (dir=%u, name=%.*s, %u->%u)\n", 2365 dir, ext2fs_dirent_name_len(dirent), dirent->name, 2366 dirent->inode, new_inode); 2367 #endif 2368 2369 dirent->inode = new_inode; 2370 2371 /* Update the directory mtime and ctime */ 2372 retval = ext2fs_read_inode(is->rfs->old_fs, dir, &inode); 2373 if (retval == 0) { 2374 inode.i_mtime = inode.i_ctime = time(0); 2375 is->err = ext2fs_write_inode(is->rfs->old_fs, dir, &inode); 2376 if (is->err) 2377 return ret | DIRENT_ABORT; 2378 } 2379 2380 return ret | DIRENT_CHANGED; 2381 } 2382 2383 static errcode_t inode_ref_fix(ext2_resize_t rfs) 2384 { 2385 errcode_t retval; 2386 struct istruct is; 2387 2388 if (!rfs->imap) 2389 return 0; 2390 2391 /* 2392 * Now, we iterate over all of the directories to update the 2393 * inode references 2394 */ 2395 is.num = 0; 2396 is.max_dirs = ext2fs_dblist_count2(rfs->old_fs->dblist); 2397 is.rfs = rfs; 2398 is.err = 0; 2399 2400 if (rfs->progress) { 2401 retval = (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS, 2402 0, is.max_dirs); 2403 if (retval) 2404 goto errout; 2405 } 2406 2407 rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; 2408 retval = ext2fs_dblist_dir_iterate(rfs->old_fs->dblist, 2409 DIRENT_FLAG_INCLUDE_EMPTY, 0, 2410 check_and_change_inodes, &is); 2411 rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS; 2412 if (retval) 2413 goto errout; 2414 if (is.err) { 2415 retval = is.err; 2416 goto errout; 2417 } 2418 2419 if (rfs->progress && (is.num < is.max_dirs)) 2420 (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS, 2421 is.max_dirs, is.max_dirs); 2422 2423 errout: 2424 ext2fs_free_extent_table(rfs->imap); 2425 rfs->imap = 0; 2426 return retval; 2427 } 2428 2429 2430 /* -------------------------------------------------------------------- 2431 * 2432 * Resize processing, phase 5. 2433 * 2434 * In this phase we actually move the inode table around, and then 2435 * update the summary statistics. This is scary, since aborting here 2436 * will potentially scramble the filesystem. (We are moving the 2437 * inode tables around in place, and so the potential for lost data, 2438 * or at the very least scrambling the mapping between filenames and 2439 * inode numbers is very high in case of a power failure here.) 2440 * -------------------------------------------------------------------- 2441 */ 2442 2443 2444 /* 2445 * A very scary routine --- this one moves the inode table around!!! 2446 * 2447 * After this you have to use the rfs->new_fs file handle to read and 2448 * write inodes. 2449 */ 2450 static errcode_t move_itables(ext2_resize_t rfs) 2451 { 2452 int n, num, size; 2453 long long diff; 2454 dgrp_t i, max_groups; 2455 ext2_filsys fs = rfs->new_fs; 2456 char *cp; 2457 blk64_t old_blk, new_blk, blk, cluster_freed; 2458 errcode_t retval; 2459 int to_move, moved; 2460 unsigned int j; 2461 ext2fs_block_bitmap new_bmap = NULL; 2462 2463 max_groups = fs->group_desc_count; 2464 if (max_groups > rfs->old_fs->group_desc_count) 2465 max_groups = rfs->old_fs->group_desc_count; 2466 2467 size = fs->blocksize * fs->inode_blocks_per_group; 2468 if (!rfs->itable_buf) { 2469 retval = ext2fs_get_mem(size, &rfs->itable_buf); 2470 if (retval) 2471 return retval; 2472 } 2473 2474 if (EXT2FS_CLUSTER_RATIO(fs) > 1) { 2475 retval = ext2fs_allocate_block_bitmap(fs, _("new meta blocks"), 2476 &new_bmap); 2477 if (retval) 2478 return retval; 2479 2480 retval = mark_table_blocks(fs, new_bmap); 2481 if (retval) 2482 goto errout; 2483 } 2484 2485 /* 2486 * Figure out how many inode tables we need to move 2487 */ 2488 to_move = moved = 0; 2489 for (i=0; i < max_groups; i++) 2490 if (ext2fs_inode_table_loc(rfs->old_fs, i) != 2491 ext2fs_inode_table_loc(fs, i)) 2492 to_move++; 2493 2494 if (to_move == 0) { 2495 retval = 0; 2496 goto errout; 2497 } 2498 2499 if (rfs->progress) { 2500 retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS, 2501 0, to_move); 2502 if (retval) 2503 goto errout; 2504 } 2505 2506 rfs->old_fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; 2507 2508 for (i=0; i < max_groups; i++) { 2509 old_blk = ext2fs_inode_table_loc(rfs->old_fs, i); 2510 new_blk = ext2fs_inode_table_loc(fs, i); 2511 diff = new_blk - old_blk; 2512 2513 #ifdef RESIZE2FS_DEBUG 2514 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 2515 printf("Itable move group %d block %llu->%llu (diff %lld)\n", 2516 i, old_blk, new_blk, diff); 2517 #endif 2518 2519 if (!diff) 2520 continue; 2521 if (diff < 0) 2522 diff = 0; 2523 2524 retval = io_channel_read_blk64(fs->io, old_blk, 2525 fs->inode_blocks_per_group, 2526 rfs->itable_buf); 2527 if (retval) 2528 goto errout; 2529 /* 2530 * The end of the inode table segment often contains 2531 * all zeros, and we're often only moving the inode 2532 * table down a block or two. If so, we can optimize 2533 * things by not rewriting blocks that we know to be zero 2534 * already. 2535 */ 2536 for (cp = rfs->itable_buf+size-1, n=0; n < size; n++, cp--) 2537 if (*cp) 2538 break; 2539 n = n >> EXT2_BLOCK_SIZE_BITS(fs->super); 2540 #ifdef RESIZE2FS_DEBUG 2541 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 2542 printf("%d blocks of zeros...\n", n); 2543 #endif 2544 num = fs->inode_blocks_per_group; 2545 if (n > diff) 2546 num -= n; 2547 2548 retval = io_channel_write_blk64(fs->io, new_blk, 2549 num, rfs->itable_buf); 2550 if (retval) { 2551 io_channel_write_blk64(fs->io, old_blk, 2552 num, rfs->itable_buf); 2553 goto errout; 2554 } 2555 if (n > diff) { 2556 retval = io_channel_write_blk64(fs->io, 2557 old_blk + fs->inode_blocks_per_group, 2558 diff, (rfs->itable_buf + 2559 (fs->inode_blocks_per_group - diff) * 2560 fs->blocksize)); 2561 if (retval) 2562 goto errout; 2563 } 2564 2565 for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0; 2566 j < fs->inode_blocks_per_group;) { 2567 if (new_bmap == NULL || 2568 !ext2fs_test_block_bitmap2(new_bmap, blk)) { 2569 ext2fs_block_alloc_stats2(fs, blk, -1); 2570 cluster_freed = EXT2FS_CLUSTER_RATIO(fs) - 2571 (blk & EXT2FS_CLUSTER_MASK(fs)); 2572 blk += cluster_freed; 2573 j += cluster_freed; 2574 continue; 2575 } 2576 blk++; 2577 j++; 2578 } 2579 2580 ext2fs_inode_table_loc_set(rfs->old_fs, i, new_blk); 2581 ext2fs_group_desc_csum_set(rfs->old_fs, i); 2582 ext2fs_mark_super_dirty(rfs->old_fs); 2583 ext2fs_flush(rfs->old_fs); 2584 2585 if (rfs->progress) { 2586 retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS, 2587 ++moved, to_move); 2588 if (retval) 2589 goto errout; 2590 } 2591 } 2592 mark_table_blocks(fs, fs->block_map); 2593 ext2fs_flush(fs); 2594 #ifdef RESIZE2FS_DEBUG 2595 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 2596 printf("Inode table move finished.\n"); 2597 #endif 2598 retval = 0; 2599 2600 errout: 2601 if (new_bmap) 2602 ext2fs_free_block_bitmap(new_bmap); 2603 return retval; 2604 } 2605 2606 /* 2607 * This function is used when expanding a file system. It frees the 2608 * superblock and block group descriptor blocks from the block group 2609 * which is no longer the last block group. 2610 */ 2611 static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs) 2612 { 2613 ext2_filsys fs = rfs->new_fs; 2614 ext2_filsys old_fs = rfs->old_fs; 2615 errcode_t retval; 2616 dgrp_t old_last_bg = rfs->old_fs->group_desc_count - 1; 2617 dgrp_t last_bg = fs->group_desc_count - 1; 2618 blk64_t sb, old_desc; 2619 blk_t num; 2620 2621 if (!ext2fs_has_feature_sparse_super2(fs->super)) 2622 return 0; 2623 2624 if (last_bg <= old_last_bg) 2625 return 0; 2626 2627 if (fs->super->s_backup_bgs[0] == old_fs->super->s_backup_bgs[0] && 2628 fs->super->s_backup_bgs[1] == old_fs->super->s_backup_bgs[1]) 2629 return 0; 2630 2631 if (old_fs->super->s_backup_bgs[0] != old_last_bg && 2632 old_fs->super->s_backup_bgs[1] != old_last_bg) 2633 return 0; 2634 2635 if (fs->super->s_backup_bgs[0] == old_last_bg || 2636 fs->super->s_backup_bgs[1] == old_last_bg) 2637 return 0; 2638 2639 if (old_last_bg == 0) 2640 return 0; 2641 2642 retval = ext2fs_super_and_bgd_loc2(rfs->old_fs, old_last_bg, 2643 &sb, &old_desc, NULL, &num); 2644 if (retval) 2645 return retval; 2646 2647 if (sb) 2648 ext2fs_unmark_block_bitmap2(fs->block_map, sb); 2649 if (old_desc) 2650 ext2fs_unmark_block_bitmap_range2(fs->block_map, old_desc, num); 2651 return 0; 2652 } 2653 2654 /* 2655 * This function is used when shrinking a file system. We need to 2656 * utilize blocks from what will be the new last block group for the 2657 * backup superblock and block group descriptor blocks. 2658 * Unfortunately, those blocks may be used by other files or fs 2659 * metadata blocks. We need to mark them as being in use. 2660 */ 2661 static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs, 2662 ext2fs_block_bitmap meta_bmap) 2663 { 2664 ext2_filsys fs = rfs->new_fs; 2665 ext2_filsys old_fs = rfs->old_fs; 2666 errcode_t retval; 2667 dgrp_t old_last_bg = rfs->old_fs->group_desc_count - 1; 2668 dgrp_t last_bg = fs->group_desc_count - 1; 2669 dgrp_t g; 2670 blk64_t blk, sb, old_desc; 2671 blk_t i, num; 2672 int realloc = 0; 2673 2674 if (!ext2fs_has_feature_sparse_super2(fs->super)) 2675 return 0; 2676 2677 if (last_bg >= old_last_bg) 2678 return 0; 2679 2680 if (fs->super->s_backup_bgs[0] == old_fs->super->s_backup_bgs[0] && 2681 fs->super->s_backup_bgs[1] == old_fs->super->s_backup_bgs[1]) 2682 return 0; 2683 2684 if (fs->super->s_backup_bgs[0] != last_bg && 2685 fs->super->s_backup_bgs[1] != last_bg) 2686 return 0; 2687 2688 if (old_fs->super->s_backup_bgs[0] == last_bg || 2689 old_fs->super->s_backup_bgs[1] == last_bg) 2690 return 0; 2691 2692 retval = ext2fs_super_and_bgd_loc2(rfs->new_fs, last_bg, 2693 &sb, &old_desc, NULL, &num); 2694 if (retval) 2695 return retval; 2696 2697 if (last_bg && !sb) { 2698 fputs(_("Should never happen! No sb in last super_sparse bg?\n"), 2699 stderr); 2700 exit(1); 2701 } 2702 if (old_desc && old_desc != sb+1) { 2703 fputs(_("Should never happen! Unexpected old_desc in " 2704 "super_sparse bg?\n"), 2705 stderr); 2706 exit(1); 2707 } 2708 num = (old_desc) ? num : 1; 2709 2710 /* Reserve the backup blocks */ 2711 ext2fs_mark_block_bitmap_range2(fs->block_map, sb, num); 2712 2713 for (g = 0; g < fs->group_desc_count; g++) { 2714 blk64_t mb; 2715 2716 mb = ext2fs_block_bitmap_loc(fs, g); 2717 if ((mb >= sb) && (mb < sb + num)) { 2718 ext2fs_block_bitmap_loc_set(fs, g, 0); 2719 realloc = 1; 2720 } 2721 mb = ext2fs_inode_bitmap_loc(fs, g); 2722 if ((mb >= sb) && (mb < sb + num)) { 2723 ext2fs_inode_bitmap_loc_set(fs, g, 0); 2724 realloc = 1; 2725 } 2726 mb = ext2fs_inode_table_loc(fs, g); 2727 if ((mb < sb + num) && 2728 (sb < mb + fs->inode_blocks_per_group)) { 2729 ext2fs_inode_table_loc_set(fs, g, 0); 2730 realloc = 1; 2731 } 2732 if (realloc) { 2733 retval = ext2fs_allocate_group_table(fs, g, 0); 2734 if (retval) 2735 return retval; 2736 } 2737 } 2738 2739 for (blk = sb, i = 0; i < num; blk++, i++) { 2740 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 2741 !ext2fs_test_block_bitmap2(meta_bmap, blk)) { 2742 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk); 2743 rfs->needed_blocks++; 2744 } 2745 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 2746 } 2747 return 0; 2748 } 2749 2750 /* 2751 * Fix the resize inode 2752 */ 2753 static errcode_t fix_resize_inode(ext2_filsys fs) 2754 { 2755 struct ext2_inode inode; 2756 errcode_t retval; 2757 2758 if (!ext2fs_has_feature_resize_inode(fs->super)) 2759 return 0; 2760 2761 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode); 2762 if (retval) goto errout; 2763 2764 ext2fs_iblk_set(fs, &inode, 1); 2765 2766 retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode); 2767 if (retval) goto errout; 2768 2769 if (!inode.i_block[EXT2_DIND_BLOCK]) { 2770 /* 2771 * Avoid zeroing out block #0; that's rude. This 2772 * should never happen anyway since the filesystem 2773 * should be fsck'ed and we assume it is consistent. 2774 */ 2775 fprintf(stderr, "%s", 2776 _("Should never happen: resize inode corrupt!\n")); 2777 exit(1); 2778 } 2779 2780 retval = ext2fs_zero_blocks2(fs, inode.i_block[EXT2_DIND_BLOCK], 1, 2781 NULL, NULL); 2782 if (retval) 2783 goto errout; 2784 2785 retval = ext2fs_create_resize_inode(fs); 2786 if (retval) 2787 goto errout; 2788 2789 errout: 2790 return retval; 2791 } 2792 2793 /* 2794 * Finally, recalculate the summary information 2795 */ 2796 static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs) 2797 { 2798 blk64_t blk; 2799 ext2_ino_t ino; 2800 unsigned int group = 0; 2801 unsigned int count = 0; 2802 blk64_t total_blocks_free = 0; 2803 int total_inodes_free = 0; 2804 int group_free = 0; 2805 int uninit = 0; 2806 blk64_t super_blk, old_desc_blk, new_desc_blk; 2807 int old_desc_blocks; 2808 2809 /* 2810 * First calculate the block statistics 2811 */ 2812 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT); 2813 ext2fs_super_and_bgd_loc2(fs, group, &super_blk, &old_desc_blk, 2814 &new_desc_blk, 0); 2815 if (ext2fs_has_feature_meta_bg(fs->super)) 2816 old_desc_blocks = fs->super->s_first_meta_bg; 2817 else 2818 old_desc_blocks = fs->desc_blocks + 2819 fs->super->s_reserved_gdt_blocks; 2820 for (blk = B2C(fs->super->s_first_data_block); 2821 blk < ext2fs_blocks_count(fs->super); 2822 blk += EXT2FS_CLUSTER_RATIO(fs)) { 2823 if ((uninit && 2824 !(EQ_CLSTR(blk, super_blk) || 2825 ((old_desc_blk && old_desc_blocks && 2826 GE_CLSTR(blk, old_desc_blk) && 2827 LT_CLSTR(blk, old_desc_blk + old_desc_blocks))) || 2828 ((new_desc_blk && EQ_CLSTR(blk, new_desc_blk))) || 2829 EQ_CLSTR(blk, ext2fs_block_bitmap_loc(fs, group)) || 2830 EQ_CLSTR(blk, ext2fs_inode_bitmap_loc(fs, group)) || 2831 ((GE_CLSTR(blk, ext2fs_inode_table_loc(fs, group)) && 2832 LT_CLSTR(blk, ext2fs_inode_table_loc(fs, group) 2833 + fs->inode_blocks_per_group))))) || 2834 (!ext2fs_fast_test_block_bitmap2(fs->block_map, blk))) { 2835 group_free++; 2836 total_blocks_free++; 2837 } 2838 count++; 2839 if ((count == fs->super->s_clusters_per_group) || 2840 EQ_CLSTR(blk, ext2fs_blocks_count(fs->super)-1)) { 2841 ext2fs_bg_free_blocks_count_set(fs, group, group_free); 2842 ext2fs_group_desc_csum_set(fs, group); 2843 group++; 2844 if (group >= fs->group_desc_count) 2845 break; 2846 count = 0; 2847 group_free = 0; 2848 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT); 2849 ext2fs_super_and_bgd_loc2(fs, group, &super_blk, 2850 &old_desc_blk, 2851 &new_desc_blk, 0); 2852 if (ext2fs_has_feature_meta_bg(fs->super)) 2853 old_desc_blocks = fs->super->s_first_meta_bg; 2854 else 2855 old_desc_blocks = fs->desc_blocks + 2856 fs->super->s_reserved_gdt_blocks; 2857 } 2858 } 2859 total_blocks_free = C2B(total_blocks_free); 2860 ext2fs_free_blocks_count_set(fs->super, total_blocks_free); 2861 2862 /* 2863 * Next, calculate the inode statistics 2864 */ 2865 group_free = 0; 2866 count = 0; 2867 group = 0; 2868 2869 /* Protect loop from wrap-around if s_inodes_count maxed */ 2870 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT); 2871 for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) { 2872 if (uninit || 2873 !ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino)) { 2874 group_free++; 2875 total_inodes_free++; 2876 } 2877 count++; 2878 if ((count == fs->super->s_inodes_per_group) || 2879 (ino == fs->super->s_inodes_count)) { 2880 ext2fs_bg_free_inodes_count_set(fs, group, group_free); 2881 ext2fs_group_desc_csum_set(fs, group); 2882 group++; 2883 if (group >= fs->group_desc_count) 2884 break; 2885 count = 0; 2886 group_free = 0; 2887 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT); 2888 } 2889 } 2890 fs->super->s_free_inodes_count = total_inodes_free; 2891 ext2fs_mark_super_dirty(fs); 2892 return 0; 2893 } 2894 2895 /* 2896 * Journal may have been relocated; update the backup journal blocks 2897 * in the superblock. 2898 */ 2899 static errcode_t fix_sb_journal_backup(ext2_filsys fs) 2900 { 2901 errcode_t retval; 2902 struct ext2_inode inode; 2903 2904 if (!ext2fs_has_feature_journal(fs->super)) 2905 return 0; 2906 2907 /* External journal? Nothing to do. */ 2908 if (fs->super->s_journal_dev && !fs->super->s_journal_inum) 2909 return 0; 2910 2911 retval = ext2fs_read_inode(fs, fs->super->s_journal_inum, &inode); 2912 if (retval) 2913 return retval; 2914 memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4); 2915 fs->super->s_jnl_blocks[15] = inode.i_size_high; 2916 fs->super->s_jnl_blocks[16] = inode.i_size; 2917 fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS; 2918 ext2fs_mark_super_dirty(fs); 2919 return 0; 2920 } 2921 2922 static int calc_group_overhead(ext2_filsys fs, blk64_t grp, 2923 int old_desc_blocks) 2924 { 2925 blk64_t super_blk, old_desc_blk, new_desc_blk; 2926 int overhead; 2927 2928 /* inode table blocks plus allocation bitmaps */ 2929 overhead = fs->inode_blocks_per_group + 2; 2930 2931 ext2fs_super_and_bgd_loc2(fs, grp, &super_blk, 2932 &old_desc_blk, &new_desc_blk, 0); 2933 if ((grp == 0) || super_blk) 2934 overhead++; 2935 if (old_desc_blk) 2936 overhead += old_desc_blocks; 2937 else if (new_desc_blk) 2938 overhead++; 2939 return overhead; 2940 } 2941 2942 2943 /* 2944 * calculate the minimum number of blocks the given fs can be resized to 2945 */ 2946 blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags) 2947 { 2948 ext2_ino_t inode_count; 2949 dgrp_t groups, flex_groups; 2950 blk64_t blks_needed, data_blocks; 2951 blk64_t grp, data_needed, last_start; 2952 blk64_t overhead = 0; 2953 int old_desc_blocks; 2954 int flexbg_size = 1 << fs->super->s_log_groups_per_flex; 2955 2956 /* 2957 * first figure out how many group descriptors we need to 2958 * handle the number of inodes we have 2959 */ 2960 inode_count = fs->super->s_inodes_count - 2961 fs->super->s_free_inodes_count; 2962 blks_needed = ext2fs_div_ceil(inode_count, 2963 fs->super->s_inodes_per_group) * 2964 (blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super); 2965 groups = ext2fs_div64_ceil(blks_needed, 2966 EXT2_BLOCKS_PER_GROUP(fs->super)); 2967 #ifdef RESIZE2FS_DEBUG 2968 if (flags & RESIZE_DEBUG_MIN_CALC) 2969 printf("fs has %d inodes, %d groups required.\n", 2970 inode_count, groups); 2971 #endif 2972 2973 /* 2974 * number of old-style block group descriptor blocks 2975 */ 2976 if (ext2fs_has_feature_meta_bg(fs->super)) 2977 old_desc_blocks = fs->super->s_first_meta_bg; 2978 else 2979 old_desc_blocks = fs->desc_blocks + 2980 fs->super->s_reserved_gdt_blocks; 2981 2982 /* calculate how many blocks are needed for data */ 2983 data_needed = ext2fs_blocks_count(fs->super) - 2984 ext2fs_free_blocks_count(fs->super); 2985 2986 for (grp = 0; grp < fs->group_desc_count; grp++) 2987 data_needed -= calc_group_overhead(fs, grp, old_desc_blocks); 2988 #ifdef RESIZE2FS_DEBUG 2989 if (flags & RESIZE_DEBUG_MIN_CALC) 2990 printf("fs requires %llu data blocks.\n", data_needed); 2991 #endif 2992 2993 /* 2994 * For ext4 we need to allow for up to a flex_bg worth of 2995 * inode tables of slack space so the resize operation can be 2996 * guaranteed to finish. 2997 */ 2998 flex_groups = groups; 2999 if (ext2fs_has_feature_flex_bg(fs->super)) { 3000 dgrp_t remainder = groups & (flexbg_size - 1); 3001 3002 flex_groups += flexbg_size - remainder; 3003 if (flex_groups > fs->group_desc_count) 3004 flex_groups = fs->group_desc_count; 3005 } 3006 3007 /* 3008 * figure out how many data blocks we have given the number of groups 3009 * we need for our inodes 3010 */ 3011 data_blocks = EXT2_GROUPS_TO_BLOCKS(fs->super, groups); 3012 last_start = 0; 3013 for (grp = 0; grp < flex_groups; grp++) { 3014 overhead = calc_group_overhead(fs, grp, old_desc_blocks); 3015 3016 /* 3017 * we want to keep track of how much data we can store in 3018 * the groups leading up to the last group so we can determine 3019 * how big the last group needs to be 3020 */ 3021 if (grp < (groups - 1)) 3022 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) - 3023 overhead; 3024 3025 if (data_blocks > overhead) 3026 data_blocks -= overhead; 3027 else 3028 data_blocks = 0; 3029 } 3030 #ifdef RESIZE2FS_DEBUG 3031 if (flags & RESIZE_DEBUG_MIN_CALC) 3032 printf("With %d group(s), we have %llu blocks available.\n", 3033 groups, data_blocks); 3034 #endif 3035 3036 /* 3037 * if we need more group descriptors in order to accommodate our data 3038 * then we need to add them here 3039 */ 3040 blks_needed = data_needed; 3041 while (blks_needed > data_blocks) { 3042 blk64_t remainder = blks_needed - data_blocks; 3043 dgrp_t extra_grps; 3044 3045 /* figure out how many more groups we need for the data */ 3046 extra_grps = ext2fs_div64_ceil(remainder, 3047 EXT2_BLOCKS_PER_GROUP(fs->super)); 3048 3049 data_blocks += EXT2_GROUPS_TO_BLOCKS(fs->super, extra_grps); 3050 3051 /* ok we have to account for the last group */ 3052 overhead = calc_group_overhead(fs, groups-1, old_desc_blocks); 3053 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) - overhead; 3054 3055 grp = flex_groups; 3056 groups += extra_grps; 3057 if (!ext2fs_has_feature_flex_bg(fs->super)) 3058 flex_groups = groups; 3059 else if (groups > flex_groups) { 3060 dgrp_t r = groups & (flexbg_size - 1); 3061 3062 flex_groups = groups + flexbg_size - r; 3063 if (flex_groups > fs->group_desc_count) 3064 flex_groups = fs->group_desc_count; 3065 } 3066 3067 for (; grp < flex_groups; grp++) { 3068 overhead = calc_group_overhead(fs, grp, 3069 old_desc_blocks); 3070 3071 /* 3072 * again, we need to see how much data we cram into 3073 * all of the groups leading up to the last group 3074 */ 3075 if (grp < groups - 1) 3076 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) 3077 - overhead; 3078 3079 data_blocks -= overhead; 3080 } 3081 3082 #ifdef RESIZE2FS_DEBUG 3083 if (flags & RESIZE_DEBUG_MIN_CALC) 3084 printf("Added %d extra group(s), " 3085 "blks_needed %llu, data_blocks %llu, " 3086 "last_start %llu\n", extra_grps, blks_needed, 3087 data_blocks, last_start); 3088 #endif 3089 } 3090 3091 /* now for the fun voodoo */ 3092 grp = groups - 1; 3093 if (ext2fs_has_feature_flex_bg(fs->super) && 3094 (grp & ~(flexbg_size - 1)) == 0) 3095 grp = grp & ~(flexbg_size - 1); 3096 overhead = 0; 3097 for (; grp < flex_groups; grp++) 3098 overhead += calc_group_overhead(fs, grp, old_desc_blocks); 3099 3100 #ifdef RESIZE2FS_DEBUG 3101 if (flags & RESIZE_DEBUG_MIN_CALC) 3102 printf("Last group's overhead is %llu\n", overhead); 3103 #endif 3104 3105 /* 3106 * if this is the case then the last group is going to have data in it 3107 * so we need to adjust the size of the last group accordingly 3108 */ 3109 if (last_start < blks_needed) { 3110 blk64_t remainder = blks_needed - last_start; 3111 3112 #ifdef RESIZE2FS_DEBUG 3113 if (flags & RESIZE_DEBUG_MIN_CALC) 3114 printf("Need %llu data blocks in last group\n", 3115 remainder); 3116 #endif 3117 /* 3118 * 50 is a magic number that mkfs/resize uses to see if its 3119 * even worth making/resizing the fs. basically you need to 3120 * have at least 50 blocks in addition to the blocks needed 3121 * for the metadata in the last group 3122 */ 3123 if (remainder > 50) 3124 overhead += remainder; 3125 else 3126 overhead += 50; 3127 } else 3128 overhead += 50; 3129 3130 overhead += fs->super->s_first_data_block; 3131 #ifdef RESIZE2FS_DEBUG 3132 if (flags & RESIZE_DEBUG_MIN_CALC) 3133 printf("Final size of last group is %lld\n", overhead); 3134 #endif 3135 3136 /* Add extra slack for bigalloc file systems */ 3137 if (EXT2FS_CLUSTER_RATIO(fs) > 1) 3138 overhead += EXT2FS_CLUSTER_RATIO(fs) * 2; 3139 3140 /* 3141 * since our last group doesn't have to be BLOCKS_PER_GROUP 3142 * large, we only do groups-1, and then add the number of 3143 * blocks needed to handle the group descriptor metadata+data 3144 * that we need 3145 */ 3146 blks_needed = EXT2_GROUPS_TO_BLOCKS(fs->super, groups - 1); 3147 blks_needed += overhead; 3148 3149 /* 3150 * Make sure blks_needed covers the end of the inode table in 3151 * the last block group. 3152 */ 3153 overhead = ext2fs_inode_table_loc(fs, groups-1) + 3154 fs->inode_blocks_per_group; 3155 if (blks_needed < overhead) 3156 blks_needed = overhead; 3157 3158 #ifdef RESIZE2FS_DEBUG 3159 if (flags & RESIZE_DEBUG_MIN_CALC) 3160 printf("Estimated blocks needed: %llu\n", blks_needed); 3161 #endif 3162 3163 /* 3164 * If at this point we've already added up more "needed" than 3165 * the current size, just return current size as minimum. 3166 */ 3167 if (blks_needed >= ext2fs_blocks_count(fs->super)) 3168 return ext2fs_blocks_count(fs->super); 3169 /* 3170 * We need to reserve a few extra blocks if extents are 3171 * enabled, in case we need to grow the extent tree. The more 3172 * we shrink the file system, the more space we need. 3173 * 3174 * The absolute worst case is every single data block is in 3175 * the part of the file system that needs to be evacuated, 3176 * with each data block needs to be in its own extent, and 3177 * with each inode needing at least one extent block. 3178 */ 3179 if (ext2fs_has_feature_extents(fs->super)) { 3180 blk64_t safe_margin = (ext2fs_blocks_count(fs->super) - 3181 blks_needed)/500; 3182 unsigned int exts_per_blk = (fs->blocksize / 3183 sizeof(struct ext3_extent)) - 1; 3184 blk64_t worst_case = ((data_needed + exts_per_blk - 1) / 3185 exts_per_blk); 3186 3187 if (worst_case < inode_count) 3188 worst_case = inode_count; 3189 3190 if (safe_margin > worst_case) 3191 safe_margin = worst_case; 3192 3193 #ifdef RESIZE2FS_DEBUG 3194 if (flags & RESIZE_DEBUG_MIN_CALC) 3195 printf("Extents safety margin: %llu\n", safe_margin); 3196 #endif 3197 blks_needed += safe_margin; 3198 } 3199 3200 return blks_needed; 3201 } 3202