1 /* 2 * resize2fs.c --- ext2 main routine 3 * 4 * Copyright (C) 1997, 1998 by Theodore Ts'o and 5 * PowerQuest, Inc. 6 * 7 * Copyright (C) 1999, 2000 by Theosore Ts'o 8 * 9 * %Begin-Header% 10 * This file may be redistributed under the terms of the GNU Public 11 * License. 12 * %End-Header% 13 */ 14 15 /* 16 * Resizing a filesystem consists of the following phases: 17 * 18 * 1. Adjust superblock and write out new parts of the inode 19 * table 20 * 2. Determine blocks which need to be relocated, and copy the 21 * contents of blocks from their old locations to the new ones. 22 * 3. Scan the inode table, doing the following: 23 * a. If blocks have been moved, update the block 24 * pointers in the inodes and indirect blocks to 25 * point at the new block locations. 26 * b. If parts of the inode table need to be evacuated, 27 * copy inodes from their old locations to their 28 * new ones. 29 * c. If (b) needs to be done, note which blocks contain 30 * directory information, since we will need to 31 * update the directory information. 32 * 4. Update the directory blocks with the new inode locations. 33 * 5. Move the inode tables, if necessary. 34 */ 35 36 #include "config.h" 37 #include "resize2fs.h" 38 #include <time.h> 39 40 #ifdef __linux__ /* Kludge for debugging */ 41 #define RESIZE2FS_DEBUG 42 #endif 43 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 succint... */ 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 unitialized 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"), 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_ITABLE_INIT") && 924 access("/sys/fs/ext4/features/lazy_itable_init", F_OK) == 0) 925 lazy_itable_init = 1; 926 if (ext2fs_has_feature_meta_bg(fs->super)) 927 old_desc_blocks = fs->super->s_first_meta_bg; 928 else 929 old_desc_blocks = fs->desc_blocks + 930 fs->super->s_reserved_gdt_blocks; 931 932 /* 933 * If we changed the number of block_group descriptor blocks, 934 * we need to make sure they are all marked as reserved in the 935 * file systems's block allocation map. 936 */ 937 for (i = 0; i < old_fs->group_desc_count; i++) 938 ext2fs_reserve_super_and_bgd(fs, i, fs->block_map); 939 940 for (i = old_fs->group_desc_count; 941 i < fs->group_desc_count; i++) { 942 memset(ext2fs_group_desc(fs, fs->group_desc, i), 0, 943 sizeof(struct ext2_group_desc)); 944 adjblocks = 0; 945 946 ext2fs_bg_flags_zap(fs, i); 947 if (csum_flag) { 948 ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT); 949 if (!lazy_itable_init) 950 ext2fs_bg_flags_set(fs, i, 951 EXT2_BG_INODE_ZEROED); 952 ext2fs_bg_itable_unused_set(fs, i, 953 fs->super->s_inodes_per_group); 954 } 955 956 numblocks = ext2fs_group_blocks_count(fs, i); 957 if ((i < fs->group_desc_count - 1) && csum_flag) 958 ext2fs_bg_flags_set(fs, i, EXT2_BG_BLOCK_UNINIT); 959 960 has_super = ext2fs_bg_has_super(fs, i); 961 if (has_super) { 962 ext2fs_block_alloc_stats2(fs, group_block, +1); 963 adjblocks++; 964 } 965 meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super); 966 meta_bg = i / meta_bg_size; 967 if (!ext2fs_has_feature_meta_bg(fs->super) || 968 (meta_bg < fs->super->s_first_meta_bg)) { 969 if (has_super) { 970 for (j=0; j < old_desc_blocks; j++) 971 ext2fs_block_alloc_stats2(fs, 972 group_block + 1 + j, +1); 973 adjblocks += old_desc_blocks; 974 } 975 } else { 976 if (has_super) 977 has_super = 1; 978 if (((i % meta_bg_size) == 0) || 979 ((i % meta_bg_size) == 1) || 980 ((i % meta_bg_size) == (meta_bg_size-1))) 981 ext2fs_block_alloc_stats2(fs, 982 group_block + has_super, +1); 983 } 984 985 adjblocks += 2 + fs->inode_blocks_per_group; 986 987 numblocks -= adjblocks; 988 ext2fs_free_blocks_count_set(fs->super, 989 ext2fs_free_blocks_count(fs->super) - adjblocks); 990 fs->super->s_free_inodes_count += 991 fs->super->s_inodes_per_group; 992 ext2fs_bg_free_blocks_count_set(fs, i, numblocks); 993 ext2fs_bg_free_inodes_count_set(fs, i, 994 fs->super->s_inodes_per_group); 995 ext2fs_bg_used_dirs_count_set(fs, i, 0); 996 ext2fs_group_desc_csum_set(fs, i); 997 998 retval = ext2fs_allocate_group_table(fs, i, 0); 999 if (retval) goto errout; 1000 1001 group_block += fs->super->s_blocks_per_group; 1002 } 1003 retval = 0; 1004 1005 /* 1006 * Mark all of the metadata blocks as reserved so they won't 1007 * get allocated by the call to ext2fs_allocate_group_table() 1008 * in blocks_to_move(), where we allocate new blocks to 1009 * replace those allocation bitmap and inode table blocks 1010 * which have to get relocated to make space for an increased 1011 * number of the block group descriptors. 1012 */ 1013 if (reserve_blocks) 1014 mark_table_blocks(fs, reserve_blocks); 1015 1016 errout: 1017 return (retval); 1018 } 1019 1020 /* 1021 * This routine adjusts the superblock and other data structures, both 1022 * in disk as well as in memory... 1023 */ 1024 static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size) 1025 { 1026 ext2_filsys fs = rfs->new_fs; 1027 int adj = 0; 1028 errcode_t retval; 1029 blk64_t group_block; 1030 unsigned long i; 1031 unsigned long max_group; 1032 1033 ext2fs_mark_super_dirty(fs); 1034 ext2fs_mark_bb_dirty(fs); 1035 ext2fs_mark_ib_dirty(fs); 1036 1037 retval = ext2fs_allocate_block_bitmap(fs, _("reserved blocks"), 1038 &rfs->reserve_blocks); 1039 if (retval) 1040 return retval; 1041 1042 retval = adjust_fs_info(fs, rfs->old_fs, rfs->reserve_blocks, new_size); 1043 if (retval) 1044 goto errout; 1045 1046 /* 1047 * Check to make sure there are enough inodes 1048 */ 1049 if ((rfs->old_fs->super->s_inodes_count - 1050 rfs->old_fs->super->s_free_inodes_count) > 1051 rfs->new_fs->super->s_inodes_count) { 1052 retval = ENOSPC; 1053 goto errout; 1054 } 1055 1056 /* 1057 * If we are shrinking the number block groups, we're done and 1058 * can exit now. 1059 */ 1060 if (rfs->old_fs->group_desc_count > fs->group_desc_count) { 1061 retval = 0; 1062 goto errout; 1063 } 1064 1065 /* 1066 * If the number of block groups is staying the same, we're 1067 * done and can exit now. (If the number block groups is 1068 * shrinking, we had exited earlier.) 1069 */ 1070 if (rfs->old_fs->group_desc_count >= fs->group_desc_count) { 1071 retval = 0; 1072 goto errout; 1073 } 1074 1075 /* 1076 * If we are using uninit_bg (aka GDT_CSUM) and the kernel 1077 * supports lazy inode initialization, we can skip 1078 * initializing the inode table. 1079 */ 1080 if (lazy_itable_init && ext2fs_has_group_desc_csum(fs)) { 1081 retval = 0; 1082 goto errout; 1083 } 1084 1085 /* 1086 * Initialize the inode table 1087 */ 1088 retval = ext2fs_get_array(fs->blocksize, fs->inode_blocks_per_group, 1089 &rfs->itable_buf); 1090 if (retval) 1091 goto errout; 1092 1093 memset(rfs->itable_buf, 0, fs->blocksize * fs->inode_blocks_per_group); 1094 group_block = ext2fs_group_first_block2(fs, 1095 rfs->old_fs->group_desc_count); 1096 adj = rfs->old_fs->group_desc_count; 1097 max_group = fs->group_desc_count - adj; 1098 if (rfs->progress) { 1099 retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS, 1100 0, max_group); 1101 if (retval) 1102 goto errout; 1103 } 1104 for (i = rfs->old_fs->group_desc_count; 1105 i < fs->group_desc_count; i++) { 1106 /* 1107 * Write out the new inode table 1108 */ 1109 retval = ext2fs_zero_blocks2(fs, ext2fs_inode_table_loc(fs, i), 1110 fs->inode_blocks_per_group, NULL, 1111 NULL); 1112 if (retval) 1113 goto errout; 1114 1115 io_channel_flush(fs->io); 1116 if (rfs->progress) { 1117 retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS, 1118 i - adj + 1, max_group); 1119 if (retval) 1120 goto errout; 1121 } 1122 group_block += fs->super->s_blocks_per_group; 1123 } 1124 io_channel_flush(fs->io); 1125 retval = 0; 1126 1127 errout: 1128 return retval; 1129 } 1130 1131 /* -------------------------------------------------------------------- 1132 * 1133 * Resize processing, phase 2. 1134 * 1135 * In this phase we adjust determine which blocks need to be moved, in 1136 * blocks_to_move(). We then copy the blocks to their ultimate new 1137 * destinations using block_mover(). Since we are copying blocks to 1138 * their new locations, again during this pass we can abort without 1139 * any problems. 1140 * -------------------------------------------------------------------- 1141 */ 1142 1143 /* 1144 * This helper function creates a block bitmap with all of the 1145 * filesystem meta-data blocks. 1146 */ 1147 static errcode_t mark_table_blocks(ext2_filsys fs, 1148 ext2fs_block_bitmap bmap) 1149 { 1150 dgrp_t i; 1151 blk64_t blk; 1152 1153 for (i = 0; i < fs->group_desc_count; i++) { 1154 ext2fs_reserve_super_and_bgd(fs, i, bmap); 1155 1156 /* 1157 * Mark the blocks used for the inode table 1158 */ 1159 blk = ext2fs_inode_table_loc(fs, i); 1160 if (blk) 1161 ext2fs_mark_block_bitmap_range2(bmap, blk, 1162 fs->inode_blocks_per_group); 1163 1164 /* 1165 * Mark block used for the block bitmap 1166 */ 1167 blk = ext2fs_block_bitmap_loc(fs, i); 1168 if (blk) 1169 ext2fs_mark_block_bitmap2(bmap, blk); 1170 1171 /* 1172 * Mark block used for the inode bitmap 1173 */ 1174 blk = ext2fs_inode_bitmap_loc(fs, i); 1175 if (blk) 1176 ext2fs_mark_block_bitmap2(bmap, blk); 1177 } 1178 return 0; 1179 } 1180 1181 /* 1182 * This function checks to see if a particular block (either a 1183 * superblock or a block group descriptor) overlaps with an inode or 1184 * block bitmap block, or with the inode table. 1185 */ 1186 static void mark_fs_metablock(ext2_resize_t rfs, 1187 ext2fs_block_bitmap meta_bmap, 1188 int group, blk64_t blk) 1189 { 1190 ext2_filsys fs = rfs->new_fs; 1191 1192 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 1193 ext2fs_block_alloc_stats2(fs, blk, +1); 1194 1195 /* 1196 * Check to see if we overlap with the inode or block bitmap, 1197 * or the inode tables. If not, and the block is in use, then 1198 * mark it as a block to be moved. 1199 */ 1200 if (is_block_bm(fs, group, blk)) { 1201 ext2fs_block_bitmap_loc_set(fs, group, 0); 1202 rfs->needed_blocks++; 1203 return; 1204 } 1205 if (is_inode_bm(fs, group, blk)) { 1206 ext2fs_inode_bitmap_loc_set(fs, group, 0); 1207 rfs->needed_blocks++; 1208 return; 1209 } 1210 if (is_inode_tb(fs, group, blk)) { 1211 ext2fs_inode_table_loc_set(fs, group, 0); 1212 rfs->needed_blocks++; 1213 return; 1214 } 1215 if (ext2fs_has_feature_flex_bg(fs->super)) { 1216 dgrp_t i; 1217 1218 for (i = 0; i < rfs->old_fs->group_desc_count; i++) { 1219 if (is_block_bm(fs, i, blk)) { 1220 ext2fs_block_bitmap_loc_set(fs, i, 0); 1221 rfs->needed_blocks++; 1222 return; 1223 } 1224 if (is_inode_bm(fs, i, blk)) { 1225 ext2fs_inode_bitmap_loc_set(fs, i, 0); 1226 rfs->needed_blocks++; 1227 return; 1228 } 1229 if (is_inode_tb(fs, i, blk)) { 1230 ext2fs_inode_table_loc_set(fs, i, 0); 1231 rfs->needed_blocks++; 1232 return; 1233 } 1234 } 1235 } 1236 1237 if (ext2fs_has_group_desc_csum(fs) && 1238 (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT))) { 1239 /* 1240 * If the block bitmap is uninitialized, which means 1241 * nothing other than standard metadata in use. 1242 */ 1243 return; 1244 } else if (ext2fs_test_block_bitmap2(rfs->old_fs->block_map, blk) && 1245 !ext2fs_test_block_bitmap2(meta_bmap, blk)) { 1246 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk); 1247 rfs->needed_blocks++; 1248 } 1249 } 1250 1251 1252 /* 1253 * This routine marks and unmarks reserved blocks in the new block 1254 * bitmap. It also determines which blocks need to be moved and 1255 * places this information into the move_blocks bitmap. 1256 */ 1257 static errcode_t blocks_to_move(ext2_resize_t rfs) 1258 { 1259 unsigned int j; 1260 int has_super; 1261 dgrp_t i, max_groups, g; 1262 blk64_t blk, group_blk; 1263 blk64_t old_blocks, new_blocks, group_end, cluster_freed; 1264 blk64_t new_size; 1265 unsigned int meta_bg, meta_bg_size; 1266 errcode_t retval; 1267 ext2_filsys fs, old_fs; 1268 ext2fs_block_bitmap meta_bmap, new_meta_bmap = NULL; 1269 int flex_bg; 1270 1271 fs = rfs->new_fs; 1272 old_fs = rfs->old_fs; 1273 if (ext2fs_blocks_count(old_fs->super) > ext2fs_blocks_count(fs->super)) 1274 fs = rfs->old_fs; 1275 1276 retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"), 1277 &rfs->move_blocks); 1278 if (retval) 1279 return retval; 1280 1281 retval = ext2fs_allocate_block_bitmap(fs, _("meta-data blocks"), 1282 &meta_bmap); 1283 if (retval) 1284 return retval; 1285 1286 retval = mark_table_blocks(old_fs, meta_bmap); 1287 if (retval) 1288 return retval; 1289 1290 fs = rfs->new_fs; 1291 1292 /* 1293 * If we're shrinking the filesystem, we need to move any 1294 * group's metadata blocks (either allocation bitmaps or the 1295 * inode table) which are beyond the end of the new 1296 * filesystem. 1297 */ 1298 new_size = ext2fs_blocks_count(fs->super); 1299 if (new_size < ext2fs_blocks_count(old_fs->super)) { 1300 for (g = 0; g < fs->group_desc_count; g++) { 1301 int realloc = 0; 1302 /* 1303 * ext2fs_allocate_group_table will re-allocate any 1304 * metadata blocks whose location is set to zero. 1305 */ 1306 if (ext2fs_block_bitmap_loc(fs, g) >= new_size) { 1307 ext2fs_block_bitmap_loc_set(fs, g, 0); 1308 realloc = 1; 1309 } 1310 if (ext2fs_inode_bitmap_loc(fs, g) >= new_size) { 1311 ext2fs_inode_bitmap_loc_set(fs, g, 0); 1312 realloc = 1; 1313 } 1314 if ((ext2fs_inode_table_loc(fs, g) + 1315 fs->inode_blocks_per_group) > new_size) { 1316 ext2fs_inode_table_loc_set(fs, g, 0); 1317 realloc = 1; 1318 } 1319 1320 if (realloc) { 1321 retval = ext2fs_allocate_group_table(fs, g, 0); 1322 if (retval) 1323 return retval; 1324 } 1325 } 1326 } 1327 1328 /* 1329 * If we're shrinking the filesystem, we need to move all of 1330 * the blocks that don't fit any more 1331 */ 1332 for (blk = ext2fs_blocks_count(fs->super); 1333 blk < ext2fs_blocks_count(old_fs->super); blk++) { 1334 g = ext2fs_group_of_blk2(fs, blk); 1335 if (ext2fs_has_group_desc_csum(fs) && 1336 ext2fs_bg_flags_test(old_fs, g, EXT2_BG_BLOCK_UNINIT)) { 1337 /* 1338 * The block bitmap is uninitialized, so skip 1339 * to the next block group. 1340 */ 1341 blk = ext2fs_group_first_block2(fs, g+1) - 1; 1342 continue; 1343 } 1344 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1345 !ext2fs_test_block_bitmap2(meta_bmap, blk)) { 1346 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk); 1347 rfs->needed_blocks++; 1348 } 1349 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 1350 } 1351 1352 if (ext2fs_has_feature_meta_bg(old_fs->super)) 1353 old_blocks = old_fs->super->s_first_meta_bg; 1354 else 1355 old_blocks = old_fs->desc_blocks + 1356 old_fs->super->s_reserved_gdt_blocks; 1357 if (ext2fs_has_feature_meta_bg(fs->super)) 1358 new_blocks = fs->super->s_first_meta_bg; 1359 else 1360 new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks; 1361 1362 retval = reserve_sparse_super2_last_group(rfs, meta_bmap); 1363 if (retval) 1364 goto errout; 1365 1366 if (EXT2_DESC_SIZE(rfs->old_fs->super) == 1367 EXT2_DESC_SIZE(rfs->new_fs->super) && 1368 old_blocks == new_blocks) { 1369 retval = 0; 1370 goto errout; 1371 } 1372 1373 max_groups = fs->group_desc_count; 1374 if (max_groups > old_fs->group_desc_count) 1375 max_groups = old_fs->group_desc_count; 1376 group_blk = old_fs->super->s_first_data_block; 1377 /* 1378 * If we're reducing the number of descriptor blocks, this 1379 * makes life easy. :-) We just have to mark some extra 1380 * blocks as free. 1381 */ 1382 if (old_blocks > new_blocks) { 1383 if (EXT2FS_CLUSTER_RATIO(fs) > 1) { 1384 retval = ext2fs_allocate_block_bitmap(fs, 1385 _("new meta blocks"), 1386 &new_meta_bmap); 1387 if (retval) 1388 goto errout; 1389 1390 retval = mark_table_blocks(fs, new_meta_bmap); 1391 if (retval) 1392 goto errout; 1393 } 1394 1395 for (i = 0; i < max_groups; i++) { 1396 if (!ext2fs_bg_has_super(old_fs, i)) { 1397 group_blk += fs->super->s_blocks_per_group; 1398 continue; 1399 } 1400 group_end = group_blk + 1 + old_blocks; 1401 for (blk = group_blk + 1 + new_blocks; 1402 blk < group_end;) { 1403 if (new_meta_bmap == NULL || 1404 !ext2fs_test_block_bitmap2(new_meta_bmap, 1405 blk)) { 1406 cluster_freed = 1407 EXT2FS_CLUSTER_RATIO(fs) - 1408 (blk & 1409 EXT2FS_CLUSTER_MASK(fs)); 1410 if (cluster_freed > group_end - blk) 1411 cluster_freed = group_end - blk; 1412 ext2fs_block_alloc_stats2(fs, blk, -1); 1413 blk += EXT2FS_CLUSTER_RATIO(fs); 1414 rfs->needed_blocks -= cluster_freed; 1415 continue; 1416 } 1417 rfs->needed_blocks--; 1418 blk++; 1419 } 1420 group_blk += fs->super->s_blocks_per_group; 1421 } 1422 retval = 0; 1423 goto errout; 1424 } 1425 /* 1426 * If we're increasing the number of descriptor blocks, life 1427 * gets interesting.... 1428 */ 1429 meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super); 1430 flex_bg = ext2fs_has_feature_flex_bg(fs->super); 1431 /* first reserve all of the existing fs meta blocks */ 1432 for (i = 0; i < max_groups; i++) { 1433 has_super = ext2fs_bg_has_super(fs, i); 1434 if (has_super) 1435 mark_fs_metablock(rfs, meta_bmap, i, group_blk); 1436 1437 meta_bg = i / meta_bg_size; 1438 if (!ext2fs_has_feature_meta_bg(fs->super) || 1439 (meta_bg < fs->super->s_first_meta_bg)) { 1440 if (has_super) { 1441 for (blk = group_blk+1; 1442 blk < group_blk + 1 + new_blocks; blk++) 1443 mark_fs_metablock(rfs, meta_bmap, 1444 i, blk); 1445 } 1446 } else { 1447 if (has_super) 1448 has_super = 1; 1449 if (((i % meta_bg_size) == 0) || 1450 ((i % meta_bg_size) == 1) || 1451 ((i % meta_bg_size) == (meta_bg_size-1))) 1452 mark_fs_metablock(rfs, meta_bmap, i, 1453 group_blk + has_super); 1454 } 1455 1456 /* 1457 * Reserve the existing meta blocks that we know 1458 * aren't to be moved. 1459 * 1460 * For flex_bg file systems, in order to avoid 1461 * overwriting fs metadata (especially inode table 1462 * blocks) belonging to a different block group when 1463 * we are relocating the inode tables, we need to 1464 * reserve all existing fs metadata blocks. 1465 */ 1466 if (ext2fs_block_bitmap_loc(fs, i)) 1467 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1468 ext2fs_block_bitmap_loc(fs, i)); 1469 else if (flex_bg && i < old_fs->group_desc_count) 1470 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1471 ext2fs_block_bitmap_loc(old_fs, i)); 1472 1473 if (ext2fs_inode_bitmap_loc(fs, i)) 1474 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1475 ext2fs_inode_bitmap_loc(fs, i)); 1476 else if (flex_bg && i < old_fs->group_desc_count) 1477 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, 1478 ext2fs_inode_bitmap_loc(old_fs, i)); 1479 1480 if (ext2fs_inode_table_loc(fs, i)) 1481 ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks, 1482 ext2fs_inode_table_loc(fs, i), 1483 fs->inode_blocks_per_group); 1484 else if (flex_bg && i < old_fs->group_desc_count) 1485 ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks, 1486 ext2fs_inode_table_loc(old_fs, i), 1487 old_fs->inode_blocks_per_group); 1488 1489 group_blk += rfs->new_fs->super->s_blocks_per_group; 1490 } 1491 1492 /* Allocate the missing data structures */ 1493 for (i = 0; i < max_groups; i++) { 1494 if (ext2fs_inode_table_loc(fs, i) && 1495 ext2fs_inode_bitmap_loc(fs, i) && 1496 ext2fs_block_bitmap_loc(fs, i)) 1497 continue; 1498 1499 retval = ext2fs_allocate_group_table(fs, i, 1500 rfs->reserve_blocks); 1501 if (retval) 1502 goto errout; 1503 1504 /* 1505 * For those structures that have changed, we need to 1506 * do bookkeepping. 1507 */ 1508 if (ext2fs_block_bitmap_loc(old_fs, i) != 1509 (blk = ext2fs_block_bitmap_loc(fs, i))) { 1510 ext2fs_block_alloc_stats2(fs, blk, +1); 1511 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1512 !ext2fs_test_block_bitmap2(meta_bmap, blk)) 1513 ext2fs_mark_block_bitmap2(rfs->move_blocks, 1514 blk); 1515 } 1516 if (ext2fs_inode_bitmap_loc(old_fs, i) != 1517 (blk = ext2fs_inode_bitmap_loc(fs, i))) { 1518 ext2fs_block_alloc_stats2(fs, blk, +1); 1519 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1520 !ext2fs_test_block_bitmap2(meta_bmap, blk)) 1521 ext2fs_mark_block_bitmap2(rfs->move_blocks, 1522 blk); 1523 } 1524 1525 /* 1526 * The inode table, if we need to relocate it, is 1527 * handled specially. We have to reserve the blocks 1528 * for both the old and the new inode table, since we 1529 * can't have the inode table be destroyed during the 1530 * block relocation phase. 1531 */ 1532 if (ext2fs_inode_table_loc(fs, i) == ext2fs_inode_table_loc(old_fs, i)) 1533 continue; /* inode table not moved */ 1534 1535 rfs->needed_blocks += fs->inode_blocks_per_group; 1536 1537 /* 1538 * Mark the new inode table as in use in the new block 1539 * allocation bitmap, and move any blocks that might 1540 * be necessary. 1541 */ 1542 for (blk = ext2fs_inode_table_loc(fs, i), j=0; 1543 j < fs->inode_blocks_per_group ; j++, blk++) { 1544 ext2fs_block_alloc_stats2(fs, blk, +1); 1545 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 1546 !ext2fs_test_block_bitmap2(meta_bmap, blk)) 1547 ext2fs_mark_block_bitmap2(rfs->move_blocks, 1548 blk); 1549 } 1550 1551 /* 1552 * Make sure the old inode table is reserved in the 1553 * block reservation bitmap. 1554 */ 1555 for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0; 1556 j < fs->inode_blocks_per_group ; j++, blk++) 1557 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 1558 } 1559 retval = 0; 1560 1561 errout: 1562 if (new_meta_bmap) 1563 ext2fs_free_block_bitmap(new_meta_bmap); 1564 if (meta_bmap) 1565 ext2fs_free_block_bitmap(meta_bmap); 1566 1567 return retval; 1568 } 1569 1570 /* 1571 * This helper function tries to allocate a new block. We try to 1572 * avoid hitting the original group descriptor blocks at least at 1573 * first, since we want to make it possible to recover from a badly 1574 * aborted resize operation as much as possible. 1575 * 1576 * In the future, I may further modify this routine to balance out 1577 * where we get the new blocks across the various block groups. 1578 * Ideally we would allocate blocks that corresponded with the block 1579 * group of the containing inode, and keep contiguous blocks 1580 * together. However, this very difficult to do efficiently, since we 1581 * don't have the necessary information up front. 1582 */ 1583 1584 #define AVOID_OLD 1 1585 #define DESPERATION 2 1586 1587 static void init_block_alloc(ext2_resize_t rfs) 1588 { 1589 rfs->alloc_state = AVOID_OLD; 1590 rfs->new_blk = rfs->new_fs->super->s_first_data_block; 1591 #if 0 1592 /* HACK for testing */ 1593 if (ext2fs_blocks_count(rfs->new_fs->super) > 1594 ext2fs_blocks_count(rfs->old_fs->super)) 1595 rfs->new_blk = ext2fs_blocks_count(rfs->old_fs->super); 1596 #endif 1597 } 1598 1599 static blk64_t get_new_block(ext2_resize_t rfs) 1600 { 1601 ext2_filsys fs = rfs->new_fs; 1602 1603 while (1) { 1604 if (rfs->new_blk >= ext2fs_blocks_count(fs->super)) { 1605 if (rfs->alloc_state == DESPERATION) 1606 return 0; 1607 1608 #ifdef RESIZE2FS_DEBUG 1609 if (rfs->flags & RESIZE_DEBUG_BMOVE) 1610 printf("Going into desperation mode " 1611 "for block allocations\n"); 1612 #endif 1613 rfs->alloc_state = DESPERATION; 1614 rfs->new_blk = fs->super->s_first_data_block; 1615 continue; 1616 } 1617 if (ext2fs_test_block_bitmap2(fs->block_map, rfs->new_blk) || 1618 ext2fs_test_block_bitmap2(rfs->reserve_blocks, 1619 rfs->new_blk) || 1620 ((rfs->alloc_state == AVOID_OLD) && 1621 (rfs->new_blk < ext2fs_blocks_count(rfs->old_fs->super)) && 1622 ext2fs_test_block_bitmap2(rfs->old_fs->block_map, 1623 rfs->new_blk))) { 1624 rfs->new_blk++; 1625 continue; 1626 } 1627 return rfs->new_blk; 1628 } 1629 } 1630 1631 static errcode_t resize2fs_get_alloc_block(ext2_filsys fs, 1632 blk64_t goal EXT2FS_ATTR((unused)), 1633 blk64_t *ret) 1634 { 1635 ext2_resize_t rfs = (ext2_resize_t) fs->priv_data; 1636 blk64_t blk; 1637 int group; 1638 1639 blk = get_new_block(rfs); 1640 if (!blk) 1641 return ENOSPC; 1642 1643 #ifdef RESIZE2FS_DEBUG 1644 if (rfs->flags & 0xF) 1645 printf("get_alloc_block allocating %llu\n", blk); 1646 #endif 1647 1648 ext2fs_mark_block_bitmap2(rfs->old_fs->block_map, blk); 1649 ext2fs_mark_block_bitmap2(rfs->new_fs->block_map, blk); 1650 1651 group = ext2fs_group_of_blk2(rfs->old_fs, blk); 1652 ext2fs_clear_block_uninit(rfs->old_fs, group); 1653 group = ext2fs_group_of_blk2(rfs->new_fs, blk); 1654 ext2fs_clear_block_uninit(rfs->new_fs, group); 1655 1656 *ret = (blk64_t) blk; 1657 return 0; 1658 } 1659 1660 static errcode_t block_mover(ext2_resize_t rfs) 1661 { 1662 blk64_t blk, old_blk, new_blk; 1663 ext2_filsys fs = rfs->new_fs; 1664 ext2_filsys old_fs = rfs->old_fs; 1665 errcode_t retval; 1666 __u64 c, size; 1667 int to_move, moved; 1668 ext2_badblocks_list badblock_list = 0; 1669 int bb_modified = 0; 1670 1671 fs->get_alloc_block = resize2fs_get_alloc_block; 1672 old_fs->get_alloc_block = resize2fs_get_alloc_block; 1673 1674 retval = ext2fs_read_bb_inode(old_fs, &badblock_list); 1675 if (retval) 1676 return retval; 1677 1678 new_blk = fs->super->s_first_data_block; 1679 if (!rfs->itable_buf) { 1680 retval = ext2fs_get_array(fs->blocksize, 1681 fs->inode_blocks_per_group, 1682 &rfs->itable_buf); 1683 if (retval) 1684 return retval; 1685 } 1686 retval = ext2fs_create_extent_table(&rfs->bmap, 0); 1687 if (retval) 1688 return retval; 1689 1690 /* 1691 * The first step is to figure out where all of the blocks 1692 * will go. 1693 */ 1694 to_move = moved = 0; 1695 init_block_alloc(rfs); 1696 for (blk = B2C(old_fs->super->s_first_data_block); 1697 blk < ext2fs_blocks_count(old_fs->super); 1698 blk += EXT2FS_CLUSTER_RATIO(fs)) { 1699 if (!ext2fs_test_block_bitmap2(old_fs->block_map, blk)) 1700 continue; 1701 if (!ext2fs_test_block_bitmap2(rfs->move_blocks, blk)) 1702 continue; 1703 if (ext2fs_badblocks_list_test(badblock_list, blk)) { 1704 ext2fs_badblocks_list_del(badblock_list, blk); 1705 bb_modified++; 1706 continue; 1707 } 1708 1709 new_blk = get_new_block(rfs); 1710 if (!new_blk) { 1711 retval = ENOSPC; 1712 goto errout; 1713 } 1714 ext2fs_block_alloc_stats2(fs, new_blk, +1); 1715 ext2fs_add_extent_entry(rfs->bmap, B2C(blk), B2C(new_blk)); 1716 to_move++; 1717 } 1718 1719 if (to_move == 0) { 1720 if (rfs->bmap) { 1721 ext2fs_free_extent_table(rfs->bmap); 1722 rfs->bmap = 0; 1723 } 1724 retval = 0; 1725 goto errout; 1726 } 1727 1728 /* 1729 * Step two is to actually move the blocks 1730 */ 1731 retval = ext2fs_iterate_extent(rfs->bmap, 0, 0, 0); 1732 if (retval) goto errout; 1733 1734 if (rfs->progress) { 1735 retval = (rfs->progress)(rfs, E2_RSZ_BLOCK_RELOC_PASS, 1736 0, to_move); 1737 if (retval) 1738 goto errout; 1739 } 1740 while (1) { 1741 retval = ext2fs_iterate_extent(rfs->bmap, &old_blk, &new_blk, &size); 1742 if (retval) goto errout; 1743 if (!size) 1744 break; 1745 old_blk = C2B(old_blk); 1746 new_blk = C2B(new_blk); 1747 size = C2B(size); 1748 #ifdef RESIZE2FS_DEBUG 1749 if (rfs->flags & RESIZE_DEBUG_BMOVE) 1750 printf("Moving %llu blocks %llu->%llu\n", 1751 size, old_blk, new_blk); 1752 #endif 1753 do { 1754 c = size; 1755 if (c > fs->inode_blocks_per_group) 1756 c = fs->inode_blocks_per_group; 1757 retval = io_channel_read_blk64(fs->io, old_blk, c, 1758 rfs->itable_buf); 1759 if (retval) goto errout; 1760 retval = io_channel_write_blk64(fs->io, new_blk, c, 1761 rfs->itable_buf); 1762 if (retval) goto errout; 1763 size -= c; 1764 new_blk += c; 1765 old_blk += c; 1766 moved += c; 1767 if (rfs->progress) { 1768 io_channel_flush(fs->io); 1769 retval = (rfs->progress)(rfs, 1770 E2_RSZ_BLOCK_RELOC_PASS, 1771 moved, to_move); 1772 if (retval) 1773 goto errout; 1774 } 1775 } while (size > 0); 1776 io_channel_flush(fs->io); 1777 } 1778 1779 errout: 1780 if (badblock_list) { 1781 if (!retval && bb_modified) 1782 retval = ext2fs_update_bb_inode(old_fs, 1783 badblock_list); 1784 ext2fs_badblocks_list_free(badblock_list); 1785 } 1786 return retval; 1787 } 1788 1789 1790 /* -------------------------------------------------------------------- 1791 * 1792 * Resize processing, phase 3 1793 * 1794 * -------------------------------------------------------------------- 1795 */ 1796 1797 1798 /* 1799 * The extent translation table is stored in clusters so we need to 1800 * take special care when mapping a source block number to its 1801 * destination block number. 1802 */ 1803 static __u64 extent_translate(ext2_filsys fs, ext2_extent extent, __u64 old_loc) 1804 { 1805 __u64 new_block = C2B(ext2fs_extent_translate(extent, B2C(old_loc))); 1806 1807 if (new_block != 0) 1808 new_block += old_loc & (EXT2FS_CLUSTER_RATIO(fs) - 1); 1809 return new_block; 1810 } 1811 1812 struct process_block_struct { 1813 ext2_resize_t rfs; 1814 ext2_ino_t ino; 1815 ext2_ino_t old_ino; 1816 struct ext2_inode * inode; 1817 errcode_t error; 1818 int is_dir; 1819 int changed; 1820 int has_extents; 1821 }; 1822 1823 static int process_block(ext2_filsys fs, blk64_t *block_nr, 1824 e2_blkcnt_t blockcnt, 1825 blk64_t ref_block EXT2FS_ATTR((unused)), 1826 int ref_offset EXT2FS_ATTR((unused)), void *priv_data) 1827 { 1828 struct process_block_struct *pb; 1829 errcode_t retval; 1830 blk64_t block, new_block; 1831 int ret = 0; 1832 1833 pb = (struct process_block_struct *) priv_data; 1834 block = *block_nr; 1835 if (pb->rfs->bmap) { 1836 new_block = extent_translate(fs, pb->rfs->bmap, block); 1837 if (new_block) { 1838 *block_nr = new_block; 1839 ret |= BLOCK_CHANGED; 1840 pb->changed = 1; 1841 #ifdef RESIZE2FS_DEBUG 1842 if (pb->rfs->flags & RESIZE_DEBUG_BMOVE) 1843 printf("ino=%u, blockcnt=%lld, %llu->%llu\n", 1844 pb->old_ino, blockcnt, block, 1845 new_block); 1846 #endif 1847 block = new_block; 1848 } 1849 } 1850 1851 if (pb->is_dir) { 1852 retval = ext2fs_add_dir_block2(fs->dblist, pb->ino, 1853 block, (int) blockcnt); 1854 if (retval) { 1855 pb->error = retval; 1856 ret |= BLOCK_ABORT; 1857 } 1858 } 1859 return ret; 1860 } 1861 1862 /* 1863 * Progress callback 1864 */ 1865 static errcode_t progress_callback(ext2_filsys fs, 1866 ext2_inode_scan scan EXT2FS_ATTR((unused)), 1867 dgrp_t group, void * priv_data) 1868 { 1869 ext2_resize_t rfs = (ext2_resize_t) priv_data; 1870 errcode_t retval; 1871 1872 /* 1873 * This check is to protect against old ext2 libraries. It 1874 * shouldn't be needed against new libraries. 1875 */ 1876 if ((group+1) == 0) 1877 return 0; 1878 1879 if (rfs->progress) { 1880 io_channel_flush(fs->io); 1881 retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS, 1882 group+1, fs->group_desc_count); 1883 if (retval) 1884 return retval; 1885 } 1886 1887 return 0; 1888 } 1889 1890 static errcode_t migrate_ea_block(ext2_resize_t rfs, ext2_ino_t ino, 1891 struct ext2_inode *inode, int *changed) 1892 { 1893 char *buf = NULL; 1894 blk64_t new_block; 1895 errcode_t err = 0; 1896 1897 /* No EA block or no remapping? Quit early. */ 1898 if (ext2fs_file_acl_block(rfs->old_fs, inode) == 0 || !rfs->bmap) 1899 return 0; 1900 new_block = extent_translate(rfs->old_fs, rfs->bmap, 1901 ext2fs_file_acl_block(rfs->old_fs, inode)); 1902 if (new_block == 0) 1903 return 0; 1904 1905 /* Set the new ACL block */ 1906 ext2fs_file_acl_block_set(rfs->old_fs, inode, new_block); 1907 1908 /* Update checksum */ 1909 if (ext2fs_has_feature_metadata_csum(rfs->new_fs->super)) { 1910 err = ext2fs_get_mem(rfs->old_fs->blocksize, &buf); 1911 if (err) 1912 return err; 1913 rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; 1914 err = ext2fs_read_ext_attr3(rfs->old_fs, new_block, buf, ino); 1915 rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS; 1916 if (err) 1917 goto out; 1918 err = ext2fs_write_ext_attr3(rfs->old_fs, new_block, buf, ino); 1919 if (err) 1920 goto out; 1921 } 1922 *changed = 1; 1923 1924 out: 1925 ext2fs_free_mem(&buf); 1926 return err; 1927 } 1928 1929 /* Rewrite extents */ 1930 static errcode_t rewrite_extents(ext2_filsys fs, ext2_ino_t ino) 1931 { 1932 ext2_extent_handle_t handle; 1933 struct ext2fs_extent extent; 1934 errcode_t errcode; 1935 struct ext2_extent_info info; 1936 1937 errcode = ext2fs_extent_open(fs, ino, &handle); 1938 if (errcode) 1939 return errcode; 1940 1941 errcode = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent); 1942 if (errcode) 1943 goto out; 1944 1945 do { 1946 errcode = ext2fs_extent_get_info(handle, &info); 1947 if (errcode) 1948 break; 1949 1950 /* 1951 * If this is the first extent in an extent block that we 1952 * haven't visited, rewrite the extent to force the ETB 1953 * checksum to be rewritten. 1954 */ 1955 if (info.curr_entry == 1 && info.curr_level != 0 && 1956 !(extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)) { 1957 errcode = ext2fs_extent_replace(handle, 0, &extent); 1958 if (errcode) 1959 break; 1960 } 1961 1962 /* Skip to the end of a block of leaf nodes */ 1963 if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) { 1964 errcode = ext2fs_extent_get(handle, 1965 EXT2_EXTENT_LAST_SIB, 1966 &extent); 1967 if (errcode) 1968 break; 1969 } 1970 1971 errcode = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT, &extent); 1972 } while (errcode == 0); 1973 1974 out: 1975 /* Ok if we run off the end */ 1976 if (errcode == EXT2_ET_EXTENT_NO_NEXT) 1977 errcode = 0; 1978 ext2fs_extent_free(handle); 1979 return errcode; 1980 } 1981 1982 static void quiet_com_err_proc(const char *whoami EXT2FS_ATTR((unused)), 1983 errcode_t code EXT2FS_ATTR((unused)), 1984 const char *fmt EXT2FS_ATTR((unused)), 1985 va_list args EXT2FS_ATTR((unused))) 1986 { 1987 } 1988 1989 static errcode_t inode_scan_and_fix(ext2_resize_t rfs) 1990 { 1991 struct process_block_struct pb; 1992 ext2_ino_t ino, new_inode; 1993 struct ext2_inode *inode = NULL; 1994 ext2_inode_scan scan = NULL; 1995 errcode_t retval; 1996 char *block_buf = 0; 1997 ext2_ino_t start_to_move; 1998 int inode_size; 1999 2000 if ((rfs->old_fs->group_desc_count <= 2001 rfs->new_fs->group_desc_count) && 2002 !rfs->bmap) 2003 return 0; 2004 2005 set_com_err_hook(quiet_com_err_proc); 2006 2007 retval = ext2fs_open_inode_scan(rfs->old_fs, 0, &scan); 2008 if (retval) goto errout; 2009 2010 retval = ext2fs_init_dblist(rfs->old_fs, 0); 2011 if (retval) goto errout; 2012 retval = ext2fs_get_array(rfs->old_fs->blocksize, 3, &block_buf); 2013 if (retval) goto errout; 2014 2015 start_to_move = (rfs->new_fs->group_desc_count * 2016 rfs->new_fs->super->s_inodes_per_group); 2017 2018 if (rfs->progress) { 2019 retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS, 2020 0, rfs->old_fs->group_desc_count); 2021 if (retval) 2022 goto errout; 2023 } 2024 ext2fs_set_inode_callback(scan, progress_callback, (void *) rfs); 2025 pb.rfs = rfs; 2026 pb.inode = inode; 2027 pb.error = 0; 2028 new_inode = EXT2_FIRST_INODE(rfs->new_fs->super); 2029 inode_size = EXT2_INODE_SIZE(rfs->new_fs->super); 2030 inode = malloc(inode_size); 2031 if (!inode) { 2032 retval = ENOMEM; 2033 goto errout; 2034 } 2035 /* 2036 * First, copy all of the inodes that need to be moved 2037 * elsewhere in the inode table 2038 */ 2039 while (1) { 2040 retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size); 2041 if (retval) goto errout; 2042 if (!ino) 2043 break; 2044 2045 if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO) 2046 continue; /* inode not in use */ 2047 2048 pb.is_dir = LINUX_S_ISDIR(inode->i_mode); 2049 pb.changed = 0; 2050 2051 /* Remap EA block */ 2052 retval = migrate_ea_block(rfs, ino, inode, &pb.changed); 2053 if (retval) 2054 goto errout; 2055 2056 new_inode = ino; 2057 if (ino <= start_to_move) 2058 goto remap_blocks; /* Don't need to move inode. */ 2059 2060 /* 2061 * Find a new inode. Now that extents and directory blocks 2062 * are tied to the inode number through the checksum, we must 2063 * set up the new inode before we start rewriting blocks. 2064 */ 2065 retval = ext2fs_new_inode(rfs->new_fs, 0, 0, 0, &new_inode); 2066 if (retval) 2067 goto errout; 2068 2069 ext2fs_inode_alloc_stats2(rfs->new_fs, new_inode, +1, 2070 pb.is_dir); 2071 inode->i_ctime = time(0); 2072 retval = ext2fs_write_inode_full(rfs->old_fs, new_inode, 2073 inode, inode_size); 2074 if (retval) 2075 goto errout; 2076 pb.changed = 0; 2077 2078 #ifdef RESIZE2FS_DEBUG 2079 if (rfs->flags & RESIZE_DEBUG_INODEMAP) 2080 printf("Inode moved %u->%u\n", ino, new_inode); 2081 #endif 2082 if (!rfs->imap) { 2083 retval = ext2fs_create_extent_table(&rfs->imap, 0); 2084 if (retval) 2085 goto errout; 2086 } 2087 ext2fs_add_extent_entry(rfs->imap, ino, new_inode); 2088 2089 remap_blocks: 2090 if (pb.changed) 2091 retval = ext2fs_write_inode_full(rfs->old_fs, 2092 new_inode, 2093 inode, inode_size); 2094 if (retval) 2095 goto errout; 2096 2097 /* Rewrite extent block checksums with new inode number */ 2098 if (ext2fs_has_feature_metadata_csum(rfs->old_fs->super) && 2099 (inode->i_flags & EXT4_EXTENTS_FL)) { 2100 rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; 2101 retval = rewrite_extents(rfs->old_fs, new_inode); 2102 rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS; 2103 if (retval) 2104 goto errout; 2105 } 2106 2107 /* 2108 * Update inodes to point to new blocks; schedule directory 2109 * blocks for inode remapping. Need to write out dir blocks 2110 * with new inode numbers if we have metadata_csum enabled. 2111 */ 2112 if (ext2fs_inode_has_valid_blocks2(rfs->old_fs, inode) && 2113 (rfs->bmap || pb.is_dir)) { 2114 pb.ino = new_inode; 2115 pb.old_ino = ino; 2116 pb.has_extents = inode->i_flags & EXT4_EXTENTS_FL; 2117 rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; 2118 retval = ext2fs_block_iterate3(rfs->old_fs, 2119 new_inode, 0, block_buf, 2120 process_block, &pb); 2121 rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS; 2122 if (retval) 2123 goto errout; 2124 if (pb.error) { 2125 retval = pb.error; 2126 goto errout; 2127 } 2128 } else if ((inode->i_flags & EXT4_INLINE_DATA_FL) && 2129 (rfs->bmap || pb.is_dir)) { 2130 /* inline data dir; update it too */ 2131 retval = ext2fs_add_dir_block2(rfs->old_fs->dblist, 2132 new_inode, 0, 0); 2133 if (retval) 2134 goto errout; 2135 } 2136 } 2137 io_channel_flush(rfs->old_fs->io); 2138 2139 errout: 2140 reset_com_err_hook(); 2141 if (rfs->bmap) { 2142 ext2fs_free_extent_table(rfs->bmap); 2143 rfs->bmap = 0; 2144 } 2145 if (scan) 2146 ext2fs_close_inode_scan(scan); 2147 if (block_buf) 2148 ext2fs_free_mem(&block_buf); 2149 free(inode); 2150 return retval; 2151 } 2152 2153 /* -------------------------------------------------------------------- 2154 * 2155 * Resize processing, phase 4. 2156 * 2157 * -------------------------------------------------------------------- 2158 */ 2159 2160 struct istruct { 2161 ext2_resize_t rfs; 2162 errcode_t err; 2163 unsigned int max_dirs; 2164 unsigned int num; 2165 }; 2166 2167 static int check_and_change_inodes(ext2_ino_t dir, 2168 int entry EXT2FS_ATTR((unused)), 2169 struct ext2_dir_entry *dirent, int offset, 2170 int blocksize EXT2FS_ATTR((unused)), 2171 char *buf EXT2FS_ATTR((unused)), 2172 void *priv_data) 2173 { 2174 struct istruct *is = (struct istruct *) priv_data; 2175 struct ext2_inode inode; 2176 ext2_ino_t new_inode; 2177 errcode_t retval; 2178 int ret = 0; 2179 2180 if (is->rfs->progress && offset == 0) { 2181 io_channel_flush(is->rfs->old_fs->io); 2182 is->err = (is->rfs->progress)(is->rfs, 2183 E2_RSZ_INODE_REF_UPD_PASS, 2184 ++is->num, is->max_dirs); 2185 if (is->err) 2186 return DIRENT_ABORT; 2187 } 2188 2189 /* 2190 * If we have checksums enabled and the inode wasn't present in the 2191 * old fs, then we must rewrite all dir blocks with new checksums. 2192 */ 2193 if (ext2fs_has_feature_metadata_csum(is->rfs->old_fs->super) && 2194 !ext2fs_test_inode_bitmap2(is->rfs->old_fs->inode_map, dir)) 2195 ret |= DIRENT_CHANGED; 2196 2197 if (!dirent->inode) 2198 return ret; 2199 2200 new_inode = ext2fs_extent_translate(is->rfs->imap, dirent->inode); 2201 2202 if (!new_inode) 2203 return ret; 2204 #ifdef RESIZE2FS_DEBUG 2205 if (is->rfs->flags & RESIZE_DEBUG_INODEMAP) 2206 printf("Inode translate (dir=%u, name=%.*s, %u->%u)\n", 2207 dir, ext2fs_dirent_name_len(dirent), dirent->name, 2208 dirent->inode, new_inode); 2209 #endif 2210 2211 dirent->inode = new_inode; 2212 2213 /* Update the directory mtime and ctime */ 2214 retval = ext2fs_read_inode(is->rfs->old_fs, dir, &inode); 2215 if (retval == 0) { 2216 inode.i_mtime = inode.i_ctime = time(0); 2217 is->err = ext2fs_write_inode(is->rfs->old_fs, dir, &inode); 2218 if (is->err) 2219 return ret | DIRENT_ABORT; 2220 } 2221 2222 return ret | DIRENT_CHANGED; 2223 } 2224 2225 static errcode_t inode_ref_fix(ext2_resize_t rfs) 2226 { 2227 errcode_t retval; 2228 struct istruct is; 2229 2230 if (!rfs->imap) 2231 return 0; 2232 2233 /* 2234 * Now, we iterate over all of the directories to update the 2235 * inode references 2236 */ 2237 is.num = 0; 2238 is.max_dirs = ext2fs_dblist_count2(rfs->old_fs->dblist); 2239 is.rfs = rfs; 2240 is.err = 0; 2241 2242 if (rfs->progress) { 2243 retval = (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS, 2244 0, is.max_dirs); 2245 if (retval) 2246 goto errout; 2247 } 2248 2249 rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; 2250 retval = ext2fs_dblist_dir_iterate(rfs->old_fs->dblist, 2251 DIRENT_FLAG_INCLUDE_EMPTY, 0, 2252 check_and_change_inodes, &is); 2253 rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS; 2254 if (retval) 2255 goto errout; 2256 if (is.err) { 2257 retval = is.err; 2258 goto errout; 2259 } 2260 2261 if (rfs->progress && (is.num < is.max_dirs)) 2262 (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS, 2263 is.max_dirs, is.max_dirs); 2264 2265 errout: 2266 ext2fs_free_extent_table(rfs->imap); 2267 rfs->imap = 0; 2268 return retval; 2269 } 2270 2271 2272 /* -------------------------------------------------------------------- 2273 * 2274 * Resize processing, phase 5. 2275 * 2276 * In this phase we actually move the inode table around, and then 2277 * update the summary statistics. This is scary, since aborting here 2278 * will potentially scramble the filesystem. (We are moving the 2279 * inode tables around in place, and so the potential for lost data, 2280 * or at the very least scrambling the mapping between filenames and 2281 * inode numbers is very high in case of a power failure here.) 2282 * -------------------------------------------------------------------- 2283 */ 2284 2285 2286 /* 2287 * A very scary routine --- this one moves the inode table around!!! 2288 * 2289 * After this you have to use the rfs->new_fs file handle to read and 2290 * write inodes. 2291 */ 2292 static errcode_t move_itables(ext2_resize_t rfs) 2293 { 2294 int n, num, size; 2295 long long diff; 2296 dgrp_t i, max_groups; 2297 ext2_filsys fs = rfs->new_fs; 2298 char *cp; 2299 blk64_t old_blk, new_blk, blk, cluster_freed; 2300 errcode_t retval; 2301 int to_move, moved; 2302 unsigned int j; 2303 ext2fs_block_bitmap new_bmap = NULL; 2304 2305 max_groups = fs->group_desc_count; 2306 if (max_groups > rfs->old_fs->group_desc_count) 2307 max_groups = rfs->old_fs->group_desc_count; 2308 2309 size = fs->blocksize * fs->inode_blocks_per_group; 2310 if (!rfs->itable_buf) { 2311 retval = ext2fs_get_mem(size, &rfs->itable_buf); 2312 if (retval) 2313 return retval; 2314 } 2315 2316 if (EXT2FS_CLUSTER_RATIO(fs) > 1) { 2317 retval = ext2fs_allocate_block_bitmap(fs, _("new meta blocks"), 2318 &new_bmap); 2319 if (retval) 2320 return retval; 2321 2322 retval = mark_table_blocks(fs, new_bmap); 2323 if (retval) 2324 goto errout; 2325 } 2326 2327 /* 2328 * Figure out how many inode tables we need to move 2329 */ 2330 to_move = moved = 0; 2331 for (i=0; i < max_groups; i++) 2332 if (ext2fs_inode_table_loc(rfs->old_fs, i) != 2333 ext2fs_inode_table_loc(fs, i)) 2334 to_move++; 2335 2336 if (to_move == 0) { 2337 retval = 0; 2338 goto errout; 2339 } 2340 2341 if (rfs->progress) { 2342 retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS, 2343 0, to_move); 2344 if (retval) 2345 goto errout; 2346 } 2347 2348 rfs->old_fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; 2349 2350 for (i=0; i < max_groups; i++) { 2351 old_blk = ext2fs_inode_table_loc(rfs->old_fs, i); 2352 new_blk = ext2fs_inode_table_loc(fs, i); 2353 diff = new_blk - old_blk; 2354 2355 #ifdef RESIZE2FS_DEBUG 2356 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 2357 printf("Itable move group %d block %llu->%llu (diff %lld)\n", 2358 i, old_blk, new_blk, diff); 2359 #endif 2360 2361 if (!diff) 2362 continue; 2363 if (diff < 0) 2364 diff = 0; 2365 2366 retval = io_channel_read_blk64(fs->io, old_blk, 2367 fs->inode_blocks_per_group, 2368 rfs->itable_buf); 2369 if (retval) 2370 goto errout; 2371 /* 2372 * The end of the inode table segment often contains 2373 * all zeros, and we're often only moving the inode 2374 * table down a block or two. If so, we can optimize 2375 * things by not rewriting blocks that we know to be zero 2376 * already. 2377 */ 2378 for (cp = rfs->itable_buf+size-1, n=0; n < size; n++, cp--) 2379 if (*cp) 2380 break; 2381 n = n >> EXT2_BLOCK_SIZE_BITS(fs->super); 2382 #ifdef RESIZE2FS_DEBUG 2383 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 2384 printf("%d blocks of zeros...\n", n); 2385 #endif 2386 num = fs->inode_blocks_per_group; 2387 if (n > diff) 2388 num -= n; 2389 2390 retval = io_channel_write_blk64(fs->io, new_blk, 2391 num, rfs->itable_buf); 2392 if (retval) { 2393 io_channel_write_blk64(fs->io, old_blk, 2394 num, rfs->itable_buf); 2395 goto errout; 2396 } 2397 if (n > diff) { 2398 retval = io_channel_write_blk64(fs->io, 2399 old_blk + fs->inode_blocks_per_group, 2400 diff, (rfs->itable_buf + 2401 (fs->inode_blocks_per_group - diff) * 2402 fs->blocksize)); 2403 if (retval) 2404 goto errout; 2405 } 2406 2407 for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0; 2408 j < fs->inode_blocks_per_group;) { 2409 if (new_bmap == NULL || 2410 !ext2fs_test_block_bitmap2(new_bmap, blk)) { 2411 ext2fs_block_alloc_stats2(fs, blk, -1); 2412 cluster_freed = EXT2FS_CLUSTER_RATIO(fs) - 2413 (blk & EXT2FS_CLUSTER_MASK(fs)); 2414 blk += cluster_freed; 2415 j += cluster_freed; 2416 continue; 2417 } 2418 blk++; 2419 j++; 2420 } 2421 2422 ext2fs_inode_table_loc_set(rfs->old_fs, i, new_blk); 2423 ext2fs_group_desc_csum_set(rfs->old_fs, i); 2424 ext2fs_mark_super_dirty(rfs->old_fs); 2425 ext2fs_flush(rfs->old_fs); 2426 2427 if (rfs->progress) { 2428 retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS, 2429 ++moved, to_move); 2430 if (retval) 2431 goto errout; 2432 } 2433 } 2434 mark_table_blocks(fs, fs->block_map); 2435 ext2fs_flush(fs); 2436 #ifdef RESIZE2FS_DEBUG 2437 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE) 2438 printf("Inode table move finished.\n"); 2439 #endif 2440 retval = 0; 2441 2442 errout: 2443 if (new_bmap) 2444 ext2fs_free_block_bitmap(new_bmap); 2445 return retval; 2446 } 2447 2448 /* 2449 * This function is used when expanding a file system. It frees the 2450 * superblock and block group descriptor blocks from the block group 2451 * which is no longer the last block group. 2452 */ 2453 static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs) 2454 { 2455 ext2_filsys fs = rfs->new_fs; 2456 ext2_filsys old_fs = rfs->old_fs; 2457 errcode_t retval; 2458 dgrp_t old_last_bg = rfs->old_fs->group_desc_count - 1; 2459 dgrp_t last_bg = fs->group_desc_count - 1; 2460 blk64_t sb, old_desc; 2461 blk_t num; 2462 2463 if (!ext2fs_has_feature_sparse_super2(fs->super)) 2464 return 0; 2465 2466 if (last_bg <= old_last_bg) 2467 return 0; 2468 2469 if (fs->super->s_backup_bgs[0] == old_fs->super->s_backup_bgs[0] && 2470 fs->super->s_backup_bgs[1] == old_fs->super->s_backup_bgs[1]) 2471 return 0; 2472 2473 if (old_fs->super->s_backup_bgs[0] != old_last_bg && 2474 old_fs->super->s_backup_bgs[1] != old_last_bg) 2475 return 0; 2476 2477 if (fs->super->s_backup_bgs[0] == old_last_bg || 2478 fs->super->s_backup_bgs[1] == old_last_bg) 2479 return 0; 2480 2481 if (old_last_bg == 0) 2482 return 0; 2483 2484 retval = ext2fs_super_and_bgd_loc2(rfs->old_fs, old_last_bg, 2485 &sb, &old_desc, NULL, &num); 2486 if (retval) 2487 return retval; 2488 2489 if (sb) 2490 ext2fs_unmark_block_bitmap2(fs->block_map, sb); 2491 if (old_desc) 2492 ext2fs_unmark_block_bitmap_range2(fs->block_map, old_desc, num); 2493 return 0; 2494 } 2495 2496 /* 2497 * This function is used when shrinking a file system. We need to 2498 * utilize blocks from what will be the new last block group for the 2499 * backup superblock and block group descriptor blocks. 2500 * Unfortunately, those blocks may be used by other files or fs 2501 * metadata blocks. We need to mark them as being in use. 2502 */ 2503 static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs, 2504 ext2fs_block_bitmap meta_bmap) 2505 { 2506 ext2_filsys fs = rfs->new_fs; 2507 ext2_filsys old_fs = rfs->old_fs; 2508 errcode_t retval; 2509 dgrp_t old_last_bg = rfs->old_fs->group_desc_count - 1; 2510 dgrp_t last_bg = fs->group_desc_count - 1; 2511 dgrp_t g; 2512 blk64_t blk, sb, old_desc; 2513 blk_t i, num; 2514 int realloc = 0; 2515 2516 if (!ext2fs_has_feature_sparse_super2(fs->super)) 2517 return 0; 2518 2519 if (last_bg >= old_last_bg) 2520 return 0; 2521 2522 if (fs->super->s_backup_bgs[0] == old_fs->super->s_backup_bgs[0] && 2523 fs->super->s_backup_bgs[1] == old_fs->super->s_backup_bgs[1]) 2524 return 0; 2525 2526 if (fs->super->s_backup_bgs[0] != last_bg && 2527 fs->super->s_backup_bgs[1] != last_bg) 2528 return 0; 2529 2530 if (old_fs->super->s_backup_bgs[0] == last_bg || 2531 old_fs->super->s_backup_bgs[1] == last_bg) 2532 return 0; 2533 2534 retval = ext2fs_super_and_bgd_loc2(rfs->new_fs, last_bg, 2535 &sb, &old_desc, NULL, &num); 2536 if (retval) 2537 return retval; 2538 2539 if (last_bg && !sb) { 2540 fputs(_("Should never happen! No sb in last super_sparse bg?\n"), 2541 stderr); 2542 exit(1); 2543 } 2544 if (old_desc && old_desc != sb+1) { 2545 fputs(_("Should never happen! Unexpected old_desc in " 2546 "super_sparse bg?\n"), 2547 stderr); 2548 exit(1); 2549 } 2550 num = (old_desc) ? num : 1; 2551 2552 /* Reserve the backup blocks */ 2553 ext2fs_mark_block_bitmap_range2(fs->block_map, sb, num); 2554 2555 for (g = 0; g < fs->group_desc_count; g++) { 2556 blk64_t mb; 2557 2558 mb = ext2fs_block_bitmap_loc(fs, g); 2559 if ((mb >= sb) && (mb < sb + num)) { 2560 ext2fs_block_bitmap_loc_set(fs, g, 0); 2561 realloc = 1; 2562 } 2563 mb = ext2fs_inode_bitmap_loc(fs, g); 2564 if ((mb >= sb) && (mb < sb + num)) { 2565 ext2fs_inode_bitmap_loc_set(fs, g, 0); 2566 realloc = 1; 2567 } 2568 mb = ext2fs_inode_table_loc(fs, g); 2569 if ((mb < sb + num) && 2570 (sb < mb + fs->inode_blocks_per_group)) { 2571 ext2fs_inode_table_loc_set(fs, g, 0); 2572 realloc = 1; 2573 } 2574 if (realloc) { 2575 retval = ext2fs_allocate_group_table(fs, g, 0); 2576 if (retval) 2577 return retval; 2578 } 2579 } 2580 2581 for (blk = sb, i = 0; i < num; blk++, i++) { 2582 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) && 2583 !ext2fs_test_block_bitmap2(meta_bmap, blk)) { 2584 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk); 2585 rfs->needed_blocks++; 2586 } 2587 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk); 2588 } 2589 return 0; 2590 } 2591 2592 /* 2593 * Fix the resize inode 2594 */ 2595 static errcode_t fix_resize_inode(ext2_filsys fs) 2596 { 2597 struct ext2_inode inode; 2598 errcode_t retval; 2599 2600 if (!ext2fs_has_feature_resize_inode(fs->super)) 2601 return 0; 2602 2603 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode); 2604 if (retval) goto errout; 2605 2606 ext2fs_iblk_set(fs, &inode, 1); 2607 2608 retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode); 2609 if (retval) goto errout; 2610 2611 if (!inode.i_block[EXT2_DIND_BLOCK]) { 2612 /* 2613 * Avoid zeroing out block #0; that's rude. This 2614 * should never happen anyway since the filesystem 2615 * should be fsck'ed and we assume it is consistent. 2616 */ 2617 fprintf(stderr, "%s", 2618 _("Should never happen: resize inode corrupt!\n")); 2619 exit(1); 2620 } 2621 2622 retval = ext2fs_zero_blocks2(fs, inode.i_block[EXT2_DIND_BLOCK], 1, 2623 NULL, NULL); 2624 if (retval) 2625 goto errout; 2626 2627 retval = ext2fs_create_resize_inode(fs); 2628 if (retval) 2629 goto errout; 2630 2631 errout: 2632 return retval; 2633 } 2634 2635 /* 2636 * Finally, recalculate the summary information 2637 */ 2638 static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs) 2639 { 2640 blk64_t blk; 2641 ext2_ino_t ino; 2642 unsigned int group = 0; 2643 unsigned int count = 0; 2644 blk64_t total_blocks_free = 0; 2645 int total_inodes_free = 0; 2646 int group_free = 0; 2647 int uninit = 0; 2648 blk64_t super_blk, old_desc_blk, new_desc_blk; 2649 int old_desc_blocks; 2650 2651 /* 2652 * First calculate the block statistics 2653 */ 2654 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT); 2655 ext2fs_super_and_bgd_loc2(fs, group, &super_blk, &old_desc_blk, 2656 &new_desc_blk, 0); 2657 if (ext2fs_has_feature_meta_bg(fs->super)) 2658 old_desc_blocks = fs->super->s_first_meta_bg; 2659 else 2660 old_desc_blocks = fs->desc_blocks + 2661 fs->super->s_reserved_gdt_blocks; 2662 for (blk = B2C(fs->super->s_first_data_block); 2663 blk < ext2fs_blocks_count(fs->super); 2664 blk += EXT2FS_CLUSTER_RATIO(fs)) { 2665 if ((uninit && 2666 !(EQ_CLSTR(blk, super_blk) || 2667 ((old_desc_blk && old_desc_blocks && 2668 GE_CLSTR(blk, old_desc_blk) && 2669 LT_CLSTR(blk, old_desc_blk + old_desc_blocks))) || 2670 ((new_desc_blk && EQ_CLSTR(blk, new_desc_blk))) || 2671 EQ_CLSTR(blk, ext2fs_block_bitmap_loc(fs, group)) || 2672 EQ_CLSTR(blk, ext2fs_inode_bitmap_loc(fs, group)) || 2673 ((GE_CLSTR(blk, ext2fs_inode_table_loc(fs, group)) && 2674 LT_CLSTR(blk, ext2fs_inode_table_loc(fs, group) 2675 + fs->inode_blocks_per_group))))) || 2676 (!ext2fs_fast_test_block_bitmap2(fs->block_map, blk))) { 2677 group_free++; 2678 total_blocks_free++; 2679 } 2680 count++; 2681 if ((count == fs->super->s_clusters_per_group) || 2682 EQ_CLSTR(blk, ext2fs_blocks_count(fs->super)-1)) { 2683 ext2fs_bg_free_blocks_count_set(fs, group, group_free); 2684 ext2fs_group_desc_csum_set(fs, group); 2685 group++; 2686 if (group >= fs->group_desc_count) 2687 break; 2688 count = 0; 2689 group_free = 0; 2690 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT); 2691 ext2fs_super_and_bgd_loc2(fs, group, &super_blk, 2692 &old_desc_blk, 2693 &new_desc_blk, 0); 2694 if (ext2fs_has_feature_meta_bg(fs->super)) 2695 old_desc_blocks = fs->super->s_first_meta_bg; 2696 else 2697 old_desc_blocks = fs->desc_blocks + 2698 fs->super->s_reserved_gdt_blocks; 2699 } 2700 } 2701 total_blocks_free = C2B(total_blocks_free); 2702 ext2fs_free_blocks_count_set(fs->super, total_blocks_free); 2703 2704 /* 2705 * Next, calculate the inode statistics 2706 */ 2707 group_free = 0; 2708 count = 0; 2709 group = 0; 2710 2711 /* Protect loop from wrap-around if s_inodes_count maxed */ 2712 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT); 2713 for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) { 2714 if (uninit || 2715 !ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino)) { 2716 group_free++; 2717 total_inodes_free++; 2718 } 2719 count++; 2720 if ((count == fs->super->s_inodes_per_group) || 2721 (ino == fs->super->s_inodes_count)) { 2722 ext2fs_bg_free_inodes_count_set(fs, group, group_free); 2723 ext2fs_group_desc_csum_set(fs, group); 2724 group++; 2725 if (group >= fs->group_desc_count) 2726 break; 2727 count = 0; 2728 group_free = 0; 2729 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT); 2730 } 2731 } 2732 fs->super->s_free_inodes_count = total_inodes_free; 2733 ext2fs_mark_super_dirty(fs); 2734 return 0; 2735 } 2736 2737 /* 2738 * Journal may have been relocated; update the backup journal blocks 2739 * in the superblock. 2740 */ 2741 static errcode_t fix_sb_journal_backup(ext2_filsys fs) 2742 { 2743 errcode_t retval; 2744 struct ext2_inode inode; 2745 2746 if (!ext2fs_has_feature_journal(fs->super)) 2747 return 0; 2748 2749 /* External journal? Nothing to do. */ 2750 if (fs->super->s_journal_dev && !fs->super->s_journal_inum) 2751 return 0; 2752 2753 retval = ext2fs_read_inode(fs, fs->super->s_journal_inum, &inode); 2754 if (retval) 2755 return retval; 2756 memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4); 2757 fs->super->s_jnl_blocks[15] = inode.i_size_high; 2758 fs->super->s_jnl_blocks[16] = inode.i_size; 2759 fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS; 2760 ext2fs_mark_super_dirty(fs); 2761 return 0; 2762 } 2763 2764 static int calc_group_overhead(ext2_filsys fs, blk64_t grp, 2765 int old_desc_blocks) 2766 { 2767 blk64_t super_blk, old_desc_blk, new_desc_blk; 2768 int overhead; 2769 2770 /* inode table blocks plus allocation bitmaps */ 2771 overhead = fs->inode_blocks_per_group + 2; 2772 2773 ext2fs_super_and_bgd_loc2(fs, grp, &super_blk, 2774 &old_desc_blk, &new_desc_blk, 0); 2775 if ((grp == 0) || super_blk) 2776 overhead++; 2777 if (old_desc_blk) 2778 overhead += old_desc_blocks; 2779 else if (new_desc_blk) 2780 overhead++; 2781 return overhead; 2782 } 2783 2784 2785 /* 2786 * calcluate the minimum number of blocks the given fs can be resized to 2787 */ 2788 blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags) 2789 { 2790 ext2_ino_t inode_count; 2791 dgrp_t groups, flex_groups; 2792 blk64_t blks_needed, data_blocks; 2793 blk64_t grp, data_needed, last_start; 2794 blk64_t overhead = 0; 2795 int old_desc_blocks; 2796 int flexbg_size = 1 << fs->super->s_log_groups_per_flex; 2797 2798 /* 2799 * first figure out how many group descriptors we need to 2800 * handle the number of inodes we have 2801 */ 2802 inode_count = fs->super->s_inodes_count - 2803 fs->super->s_free_inodes_count; 2804 blks_needed = ext2fs_div_ceil(inode_count, 2805 fs->super->s_inodes_per_group) * 2806 (blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super); 2807 groups = ext2fs_div64_ceil(blks_needed, 2808 EXT2_BLOCKS_PER_GROUP(fs->super)); 2809 #ifdef RESIZE2FS_DEBUG 2810 if (flags & RESIZE_DEBUG_MIN_CALC) 2811 printf("fs has %d inodes, %d groups required.\n", 2812 inode_count, groups); 2813 #endif 2814 2815 /* 2816 * number of old-style block group descriptor blocks 2817 */ 2818 if (ext2fs_has_feature_meta_bg(fs->super)) 2819 old_desc_blocks = fs->super->s_first_meta_bg; 2820 else 2821 old_desc_blocks = fs->desc_blocks + 2822 fs->super->s_reserved_gdt_blocks; 2823 2824 /* calculate how many blocks are needed for data */ 2825 data_needed = ext2fs_blocks_count(fs->super) - 2826 ext2fs_free_blocks_count(fs->super); 2827 2828 for (grp = 0; grp < fs->group_desc_count; grp++) 2829 data_needed -= calc_group_overhead(fs, grp, old_desc_blocks); 2830 #ifdef RESIZE2FS_DEBUG 2831 if (flags & RESIZE_DEBUG_MIN_CALC) 2832 printf("fs requires %llu data blocks.\n", data_needed); 2833 #endif 2834 2835 /* 2836 * For ext4 we need to allow for up to a flex_bg worth of 2837 * inode tables of slack space so the resize operation can be 2838 * guaranteed to finish. 2839 */ 2840 flex_groups = groups; 2841 if (ext2fs_has_feature_flex_bg(fs->super)) { 2842 dgrp_t remainder = groups & (flexbg_size - 1); 2843 2844 flex_groups += flexbg_size - remainder; 2845 if (flex_groups > fs->group_desc_count) 2846 flex_groups = fs->group_desc_count; 2847 } 2848 2849 /* 2850 * figure out how many data blocks we have given the number of groups 2851 * we need for our inodes 2852 */ 2853 data_blocks = EXT2_GROUPS_TO_BLOCKS(fs->super, groups); 2854 last_start = 0; 2855 for (grp = 0; grp < flex_groups; grp++) { 2856 overhead = calc_group_overhead(fs, grp, old_desc_blocks); 2857 2858 /* 2859 * we want to keep track of how much data we can store in 2860 * the groups leading up to the last group so we can determine 2861 * how big the last group needs to be 2862 */ 2863 if (grp < (groups - 1)) 2864 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) - 2865 overhead; 2866 2867 if (data_blocks > overhead) 2868 data_blocks -= overhead; 2869 else 2870 data_blocks = 0; 2871 } 2872 #ifdef RESIZE2FS_DEBUG 2873 if (flags & RESIZE_DEBUG_MIN_CALC) 2874 printf("With %d group(s), we have %llu blocks available.\n", 2875 groups, data_blocks); 2876 #endif 2877 2878 /* 2879 * if we need more group descriptors in order to accomodate our data 2880 * then we need to add them here 2881 */ 2882 blks_needed = data_needed; 2883 while (blks_needed > data_blocks) { 2884 blk64_t remainder = blks_needed - data_blocks; 2885 dgrp_t extra_grps; 2886 2887 /* figure out how many more groups we need for the data */ 2888 extra_grps = ext2fs_div64_ceil(remainder, 2889 EXT2_BLOCKS_PER_GROUP(fs->super)); 2890 2891 data_blocks += EXT2_GROUPS_TO_BLOCKS(fs->super, extra_grps); 2892 2893 /* ok we have to account for the last group */ 2894 overhead = calc_group_overhead(fs, groups-1, old_desc_blocks); 2895 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) - overhead; 2896 2897 grp = flex_groups; 2898 groups += extra_grps; 2899 if (!ext2fs_has_feature_flex_bg(fs->super)) 2900 flex_groups = groups; 2901 else if (groups > flex_groups) { 2902 dgrp_t r = groups & (flexbg_size - 1); 2903 2904 flex_groups = groups + flexbg_size - r; 2905 if (flex_groups > fs->group_desc_count) 2906 flex_groups = fs->group_desc_count; 2907 } 2908 2909 for (; grp < flex_groups; grp++) { 2910 overhead = calc_group_overhead(fs, grp, 2911 old_desc_blocks); 2912 2913 /* 2914 * again, we need to see how much data we cram into 2915 * all of the groups leading up to the last group 2916 */ 2917 if (grp < groups - 1) 2918 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) 2919 - overhead; 2920 2921 data_blocks -= overhead; 2922 } 2923 2924 #ifdef RESIZE2FS_DEBUG 2925 if (flags & RESIZE_DEBUG_MIN_CALC) 2926 printf("Added %d extra group(s), " 2927 "blks_needed %llu, data_blocks %llu, " 2928 "last_start %llu\n", extra_grps, blks_needed, 2929 data_blocks, last_start); 2930 #endif 2931 } 2932 2933 /* now for the fun voodoo */ 2934 grp = groups - 1; 2935 if (ext2fs_has_feature_flex_bg(fs->super) && 2936 (grp & ~(flexbg_size - 1)) == 0) 2937 grp = grp & ~(flexbg_size - 1); 2938 overhead = 0; 2939 for (; grp < flex_groups; grp++) 2940 overhead += calc_group_overhead(fs, grp, old_desc_blocks); 2941 2942 #ifdef RESIZE2FS_DEBUG 2943 if (flags & RESIZE_DEBUG_MIN_CALC) 2944 printf("Last group's overhead is %llu\n", overhead); 2945 #endif 2946 2947 /* 2948 * if this is the case then the last group is going to have data in it 2949 * so we need to adjust the size of the last group accordingly 2950 */ 2951 if (last_start < blks_needed) { 2952 blk64_t remainder = blks_needed - last_start; 2953 2954 #ifdef RESIZE2FS_DEBUG 2955 if (flags & RESIZE_DEBUG_MIN_CALC) 2956 printf("Need %llu data blocks in last group\n", 2957 remainder); 2958 #endif 2959 /* 2960 * 50 is a magic number that mkfs/resize uses to see if its 2961 * even worth making/resizing the fs. basically you need to 2962 * have at least 50 blocks in addition to the blocks needed 2963 * for the metadata in the last group 2964 */ 2965 if (remainder > 50) 2966 overhead += remainder; 2967 else 2968 overhead += 50; 2969 } else 2970 overhead += 50; 2971 2972 overhead += fs->super->s_first_data_block; 2973 #ifdef RESIZE2FS_DEBUG 2974 if (flags & RESIZE_DEBUG_MIN_CALC) 2975 printf("Final size of last group is %lld\n", overhead); 2976 #endif 2977 2978 /* Add extra slack for bigalloc file systems */ 2979 if (EXT2FS_CLUSTER_RATIO(fs) > 1) 2980 overhead += EXT2FS_CLUSTER_RATIO(fs) * 2; 2981 2982 /* 2983 * since our last group doesn't have to be BLOCKS_PER_GROUP 2984 * large, we only do groups-1, and then add the number of 2985 * blocks needed to handle the group descriptor metadata+data 2986 * that we need 2987 */ 2988 blks_needed = EXT2_GROUPS_TO_BLOCKS(fs->super, groups - 1); 2989 blks_needed += overhead; 2990 2991 /* 2992 * Make sure blks_needed covers the end of the inode table in 2993 * the last block group. 2994 */ 2995 overhead = ext2fs_inode_table_loc(fs, groups-1) + 2996 fs->inode_blocks_per_group; 2997 if (blks_needed < overhead) 2998 blks_needed = overhead; 2999 3000 #ifdef RESIZE2FS_DEBUG 3001 if (flags & RESIZE_DEBUG_MIN_CALC) 3002 printf("Estimated blocks needed: %llu\n", blks_needed); 3003 #endif 3004 3005 /* 3006 * If at this point we've already added up more "needed" than 3007 * the current size, just return current size as minimum. 3008 */ 3009 if (blks_needed >= ext2fs_blocks_count(fs->super)) 3010 return ext2fs_blocks_count(fs->super); 3011 /* 3012 * We need to reserve a few extra blocks if extents are 3013 * enabled, in case we need to grow the extent tree. The more 3014 * we shrink the file system, the more space we need. 3015 * 3016 * The absolute worst case is every single data block is in 3017 * the part of the file system that needs to be evacuated, 3018 * with each data block needs to be in its own extent, and 3019 * with each inode needing at least one extent block. 3020 */ 3021 if (ext2fs_has_feature_extents(fs->super)) { 3022 blk64_t safe_margin = (ext2fs_blocks_count(fs->super) - 3023 blks_needed)/500; 3024 unsigned int exts_per_blk = (fs->blocksize / 3025 sizeof(struct ext3_extent)) - 1; 3026 blk64_t worst_case = ((data_needed + exts_per_blk - 1) / 3027 exts_per_blk); 3028 3029 if (worst_case < inode_count) 3030 worst_case = inode_count; 3031 3032 if (safe_margin > worst_case) 3033 safe_margin = worst_case; 3034 3035 #ifdef RESIZE2FS_DEBUG 3036 if (flags & RESIZE_DEBUG_MIN_CALC) 3037 printf("Extents safety margin: %llu\n", safe_margin); 3038 #endif 3039 blks_needed += safe_margin; 3040 } 3041 3042 return blks_needed; 3043 } 3044