2 * resize2fs.c --- ext2 main routine
4 * Copyright (C) 1997, 1998 by Theodore Ts'o and
7 * Copyright (C) 1999, 2000 by Theosore Ts'o
10 * This file may be redistributed under the terms of the GNU Public
16 * Resizing a filesystem consists of the following phases:
18 * 1. Adjust superblock and write out new parts of the inode
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
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.
37 #include "resize2fs.h"
40 #ifdef __linux__ /* Kludge for debugging */
41 #define RESIZE2FS_DEBUG
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);
56 * Some helper CPP macros
58 #define IS_BLOCK_BM(fs, i, blk) ((blk) == ext2fs_block_bitmap_loc((fs),(i)))
59 #define IS_INODE_BM(fs, i, blk) ((blk) == ext2fs_inode_bitmap_loc((fs),(i)))
61 #define IS_INODE_TB(fs, i, blk) (((blk) >= ext2fs_inode_table_loc((fs), (i))) && \
62 ((blk) < (ext2fs_inode_table_loc((fs), (i)) + \
63 (fs)->inode_blocks_per_group)))
68 * This is the top-level routine which does the dirty deed....
70 errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
71 errcode_t (*progress)(ext2_resize_t rfs, int pass,
73 unsigned long max_val))
77 struct resource_track rtrack, overall_track;
80 * Create the data structure
82 retval = ext2fs_get_mem(sizeof(struct ext2_resize_struct), &rfs);
86 memset(rfs, 0, sizeof(struct ext2_resize_struct));
91 rfs->progress = progress;
93 init_resource_track(&overall_track, "overall resize2fs", fs->io);
94 init_resource_track(&rtrack, "read_bitmaps", fs->io);
95 retval = ext2fs_read_bitmaps(fs);
98 print_resource_track(rfs, &rtrack, fs->io);
100 fs->super->s_state |= EXT2_ERROR_FS;
101 ext2fs_mark_super_dirty(fs);
104 init_resource_track(&rtrack, "fix_uninit_block_bitmaps 1", fs->io);
105 fix_uninit_block_bitmaps(fs);
106 print_resource_track(rfs, &rtrack, fs->io);
107 retval = ext2fs_dup_handle(fs, &rfs->new_fs);
111 init_resource_track(&rtrack, "adjust_superblock", fs->io);
112 retval = adjust_superblock(rfs, *new_size);
115 print_resource_track(rfs, &rtrack, fs->io);
118 init_resource_track(&rtrack, "fix_uninit_block_bitmaps 2", fs->io);
119 fix_uninit_block_bitmaps(rfs->new_fs);
120 print_resource_track(rfs, &rtrack, fs->io);
121 /* Clear the block bitmap uninit flag for the last block group */
122 ext2fs_bg_flags_clear(rfs->new_fs, rfs->new_fs->group_desc_count - 1,
123 EXT2_BG_BLOCK_UNINIT);
125 *new_size = ext2fs_blocks_count(rfs->new_fs->super);
127 init_resource_track(&rtrack, "blocks_to_move", fs->io);
128 retval = blocks_to_move(rfs);
131 print_resource_track(rfs, &rtrack, fs->io);
133 #ifdef RESIZE2FS_DEBUG
134 if (rfs->flags & RESIZE_DEBUG_BMOVE)
135 printf("Number of free blocks: %llu/%llu, Needed: %llu\n",
136 ext2fs_free_blocks_count(rfs->old_fs->super),
137 ext2fs_free_blocks_count(rfs->new_fs->super),
141 init_resource_track(&rtrack, "block_mover", fs->io);
142 retval = block_mover(rfs);
145 print_resource_track(rfs, &rtrack, fs->io);
147 init_resource_track(&rtrack, "inode_scan_and_fix", fs->io);
148 retval = inode_scan_and_fix(rfs);
151 print_resource_track(rfs, &rtrack, fs->io);
153 init_resource_track(&rtrack, "inode_ref_fix", fs->io);
154 retval = inode_ref_fix(rfs);
157 print_resource_track(rfs, &rtrack, fs->io);
159 init_resource_track(&rtrack, "move_itables", fs->io);
160 retval = move_itables(rfs);
163 print_resource_track(rfs, &rtrack, fs->io);
165 init_resource_track(&rtrack, "calculate_summary_stats", fs->io);
166 retval = ext2fs_calculate_summary_stats(rfs->new_fs);
169 print_resource_track(rfs, &rtrack, fs->io);
171 init_resource_track(&rtrack, "fix_resize_inode", fs->io);
172 retval = fix_resize_inode(rfs->new_fs);
175 print_resource_track(rfs, &rtrack, fs->io);
177 init_resource_track(&rtrack, "fix_sb_journal_backup", fs->io);
178 retval = fix_sb_journal_backup(rfs->new_fs);
181 print_resource_track(rfs, &rtrack, fs->io);
183 rfs->new_fs->super->s_state &= ~EXT2_ERROR_FS;
184 rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
186 print_resource_track(rfs, &overall_track, fs->io);
187 retval = ext2fs_close(rfs->new_fs);
193 ext2fs_free(rfs->old_fs);
195 ext2fs_free_mem(&rfs->itable_buf);
196 if (rfs->reserve_blocks)
197 ext2fs_free_block_bitmap(rfs->reserve_blocks);
198 if (rfs->move_blocks)
199 ext2fs_free_block_bitmap(rfs->move_blocks);
200 ext2fs_free_mem(&rfs);
206 ext2fs_free(rfs->new_fs);
208 ext2fs_free_mem(&rfs->itable_buf);
209 ext2fs_free_mem(&rfs);
214 * Clean up the bitmaps for unitialized bitmaps
216 static void fix_uninit_block_bitmaps(ext2_filsys fs)
222 if (!ext2fs_has_group_desc_csum(fs))
225 for (g=0; g < fs->group_desc_count; g++) {
226 if (!(ext2fs_bg_flags_test(fs, g, EXT2_BG_BLOCK_UNINIT)))
229 blk = ext2fs_group_first_block2(fs, g);
230 lblk = ext2fs_group_last_block2(fs, g);
231 ext2fs_unmark_block_bitmap_range2(fs->block_map, blk,
234 ext2fs_reserve_super_and_bgd(fs, g, fs->block_map);
235 ext2fs_mark_block_bitmap2(fs->block_map,
236 ext2fs_block_bitmap_loc(fs, g));
237 ext2fs_mark_block_bitmap2(fs->block_map,
238 ext2fs_inode_bitmap_loc(fs, g));
239 for (i = 0, blk = ext2fs_inode_table_loc(fs, g);
240 i < (unsigned int) fs->inode_blocks_per_group;
242 ext2fs_mark_block_bitmap2(fs->block_map, blk);
246 /* --------------------------------------------------------------------
248 * Resize processing, phase 1.
250 * In this phase we adjust the in-memory superblock information, and
251 * initialize any new parts of the inode table. The new parts of the
252 * inode table are created in virgin disk space, so we can abort here
253 * without any side effects.
254 * --------------------------------------------------------------------
258 * If the group descriptor's bitmap and inode table blocks are valid,
259 * release them in the new filesystem data structure, and mark them as
260 * reserved so the old inode table blocks don't get overwritten.
262 static void free_gdp_blocks(ext2_filsys fs,
263 ext2fs_block_bitmap reserve_blocks,
264 struct ext2_group_desc *gdp)
269 if (gdp->bg_block_bitmap &&
270 (gdp->bg_block_bitmap < ext2fs_blocks_count(fs->super))) {
271 ext2fs_block_alloc_stats(fs, gdp->bg_block_bitmap, -1);
272 ext2fs_mark_block_bitmap2(reserve_blocks,
273 gdp->bg_block_bitmap);
276 if (gdp->bg_inode_bitmap &&
277 (gdp->bg_inode_bitmap < ext2fs_blocks_count(fs->super))) {
278 ext2fs_block_alloc_stats(fs, gdp->bg_inode_bitmap, -1);
279 ext2fs_mark_block_bitmap2(reserve_blocks,
280 gdp->bg_inode_bitmap);
283 if (gdp->bg_inode_table == 0 ||
284 (gdp->bg_inode_table >= ext2fs_blocks_count(fs->super)))
287 for (blk = gdp->bg_inode_table, j = 0;
288 j < fs->inode_blocks_per_group; j++, blk++) {
289 if (blk >= ext2fs_blocks_count(fs->super))
291 ext2fs_block_alloc_stats(fs, blk, -1);
292 ext2fs_mark_block_bitmap2(reserve_blocks, blk);
297 * This routine is shared by the online and offline resize routines.
298 * All of the information which is adjusted in memory is done here.
300 * The reserve_blocks parameter is only needed when shrinking the
303 errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs,
304 ext2fs_block_bitmap reserve_blocks, blk64_t new_size)
307 blk64_t overhead = 0;
309 blk64_t blk, group_block;
311 blk64_t old_numblocks, numblocks, adjblocks;
312 unsigned long i, j, old_desc_blocks;
313 unsigned int meta_bg, meta_bg_size;
314 int has_super, csum_flag;
315 unsigned long long new_inodes; /* u64 to check for overflow */
318 ext2fs_blocks_count_set(fs->super, new_size);
321 fs->group_desc_count = ext2fs_div64_ceil(ext2fs_blocks_count(fs->super) -
322 fs->super->s_first_data_block,
323 EXT2_BLOCKS_PER_GROUP(fs->super));
324 if (fs->group_desc_count == 0)
325 return EXT2_ET_TOOSMALL;
326 fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
327 EXT2_DESC_PER_BLOCK(fs->super));
330 * Overhead is the number of bookkeeping blocks per group. It
331 * includes the superblock backup, the group descriptor
332 * backups, the inode bitmap, the block bitmap, and the inode
335 overhead = (int) (2 + fs->inode_blocks_per_group);
337 if (ext2fs_bg_has_super(fs, fs->group_desc_count - 1))
338 overhead += 1 + fs->desc_blocks +
339 fs->super->s_reserved_gdt_blocks;
342 * See if the last group is big enough to support the
343 * necessary data structures. If not, we need to get rid of
346 rem = (ext2fs_blocks_count(fs->super) - fs->super->s_first_data_block) %
347 fs->super->s_blocks_per_group;
348 if ((fs->group_desc_count == 1) && rem && (rem < overhead))
349 return EXT2_ET_TOOSMALL;
350 if ((fs->group_desc_count > 1) && rem && (rem < overhead+50)) {
351 ext2fs_blocks_count_set(fs->super,
352 ext2fs_blocks_count(fs->super) - rem);
356 * Adjust the number of inodes
358 new_inodes =(unsigned long long) fs->super->s_inodes_per_group * fs->group_desc_count;
359 if (new_inodes > ~0U) {
360 fprintf(stderr, _("inodes (%llu) must be less than %u"),
362 return EXT2_ET_TOO_MANY_INODES;
364 fs->super->s_inodes_count = fs->super->s_inodes_per_group *
365 fs->group_desc_count;
368 * Adjust the number of free blocks
370 blk = ext2fs_blocks_count(old_fs->super);
371 if (blk > ext2fs_blocks_count(fs->super))
372 ext2fs_free_blocks_count_set(fs->super,
373 ext2fs_free_blocks_count(fs->super) -
374 (blk - ext2fs_blocks_count(fs->super)));
376 ext2fs_free_blocks_count_set(fs->super,
377 ext2fs_free_blocks_count(fs->super) +
378 (ext2fs_blocks_count(fs->super) - blk));
381 * Adjust the number of reserved blocks
383 percent = (ext2fs_r_blocks_count(old_fs->super) * 100.0) /
384 ext2fs_blocks_count(old_fs->super);
385 ext2fs_r_blocks_count_set(fs->super,
386 (percent * ext2fs_blocks_count(fs->super) /
390 * Adjust the bitmaps for size
392 retval = ext2fs_resize_inode_bitmap2(fs->super->s_inodes_count,
393 fs->super->s_inodes_count,
395 if (retval) goto errout;
397 real_end = (((blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super) *
398 fs->group_desc_count)) - 1 +
399 fs->super->s_first_data_block;
400 retval = ext2fs_resize_block_bitmap2(ext2fs_blocks_count(fs->super)-1,
401 real_end, fs->block_map);
403 if (retval) goto errout;
406 * Reallocate the group descriptors as necessary.
408 if (old_fs->desc_blocks != fs->desc_blocks) {
409 retval = ext2fs_resize_mem(old_fs->desc_blocks *
411 fs->desc_blocks * fs->blocksize,
415 if (fs->desc_blocks > old_fs->desc_blocks)
416 memset((char *) fs->group_desc +
417 (old_fs->desc_blocks * fs->blocksize), 0,
418 (fs->desc_blocks - old_fs->desc_blocks) *
423 * If the resize_inode feature is set, and we are changing the
424 * number of descriptor blocks, then adjust
425 * s_reserved_gdt_blocks if possible to avoid needing to move
426 * the inode table either now or in the future.
428 if ((fs->super->s_feature_compat &
429 EXT2_FEATURE_COMPAT_RESIZE_INODE) &&
430 (old_fs->desc_blocks != fs->desc_blocks)) {
433 new = ((int) fs->super->s_reserved_gdt_blocks) +
434 (old_fs->desc_blocks - fs->desc_blocks);
437 if (new > (int) fs->blocksize/4)
438 new = fs->blocksize/4;
439 fs->super->s_reserved_gdt_blocks = new;
443 * If we are shrinking the number of block groups, we're done
446 if (old_fs->group_desc_count > fs->group_desc_count) {
448 * Check the block groups that we are chopping off
449 * and free any blocks associated with their metadata
451 for (i = fs->group_desc_count;
452 i < old_fs->group_desc_count; i++) {
453 free_gdp_blocks(fs, reserve_blocks,
454 ext2fs_group_desc(old_fs,
455 old_fs->group_desc, i));
462 * Fix the count of the last (old) block group
464 old_numblocks = (ext2fs_blocks_count(old_fs->super) -
465 old_fs->super->s_first_data_block) %
466 old_fs->super->s_blocks_per_group;
468 old_numblocks = old_fs->super->s_blocks_per_group;
469 if (old_fs->group_desc_count == fs->group_desc_count) {
470 numblocks = (ext2fs_blocks_count(fs->super) -
471 fs->super->s_first_data_block) %
472 fs->super->s_blocks_per_group;
474 numblocks = fs->super->s_blocks_per_group;
476 numblocks = fs->super->s_blocks_per_group;
477 i = old_fs->group_desc_count - 1;
478 ext2fs_bg_free_blocks_count_set(fs, i, ext2fs_bg_free_blocks_count(fs, i) + (numblocks - old_numblocks));
479 ext2fs_group_desc_csum_set(fs, i);
482 * If the number of block groups is staying the same, we're
483 * done and can exit now. (If the number block groups is
484 * shrinking, we had exited earlier.)
486 if (old_fs->group_desc_count >= fs->group_desc_count) {
492 * Initialize the new block group descriptors
494 group_block = ext2fs_group_first_block2(fs,
495 old_fs->group_desc_count);
496 csum_flag = ext2fs_has_group_desc_csum(fs);
497 if (access("/sys/fs/ext4/features/lazy_itable_init", F_OK) == 0)
498 lazy_itable_init = 1;
499 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
500 old_desc_blocks = fs->super->s_first_meta_bg;
502 old_desc_blocks = fs->desc_blocks +
503 fs->super->s_reserved_gdt_blocks;
504 for (i = old_fs->group_desc_count;
505 i < fs->group_desc_count; i++) {
506 memset(ext2fs_group_desc(fs, fs->group_desc, i), 0,
507 sizeof(struct ext2_group_desc));
510 ext2fs_bg_flags_zap(fs, i);
512 ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT);
513 if (!lazy_itable_init)
514 ext2fs_bg_flags_set(fs, i,
515 EXT2_BG_INODE_ZEROED);
516 ext2fs_bg_itable_unused_set(fs, i,
517 fs->super->s_inodes_per_group);
520 numblocks = ext2fs_group_blocks_count(fs, i);
521 if ((i < fs->group_desc_count - 1) && csum_flag)
522 ext2fs_bg_flags_set(fs, i, EXT2_BG_BLOCK_UNINIT);
524 has_super = ext2fs_bg_has_super(fs, i);
526 ext2fs_block_alloc_stats2(fs, group_block, +1);
529 meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
530 meta_bg = i / meta_bg_size;
531 if (!(fs->super->s_feature_incompat &
532 EXT2_FEATURE_INCOMPAT_META_BG) ||
533 (meta_bg < fs->super->s_first_meta_bg)) {
535 for (j=0; j < old_desc_blocks; j++)
536 ext2fs_block_alloc_stats2(fs,
537 group_block + 1 + j, +1);
538 adjblocks += old_desc_blocks;
543 if (((i % meta_bg_size) == 0) ||
544 ((i % meta_bg_size) == 1) ||
545 ((i % meta_bg_size) == (meta_bg_size-1)))
546 ext2fs_block_alloc_stats2(fs,
547 group_block + has_super, +1);
550 adjblocks += 2 + fs->inode_blocks_per_group;
552 numblocks -= adjblocks;
553 ext2fs_free_blocks_count_set(fs->super,
554 ext2fs_free_blocks_count(fs->super) - adjblocks);
555 fs->super->s_free_inodes_count +=
556 fs->super->s_inodes_per_group;
557 ext2fs_bg_free_blocks_count_set(fs, i, numblocks);
558 ext2fs_bg_free_inodes_count_set(fs, i,
559 fs->super->s_inodes_per_group);
560 ext2fs_bg_used_dirs_count_set(fs, i, 0);
561 ext2fs_group_desc_csum_set(fs, i);
563 retval = ext2fs_allocate_group_table(fs, i, 0);
564 if (retval) goto errout;
566 group_block += fs->super->s_blocks_per_group;
575 * This routine adjusts the superblock and other data structures, both
576 * in disk as well as in memory...
578 static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
585 unsigned long max_group;
588 ext2fs_mark_super_dirty(fs);
589 ext2fs_mark_bb_dirty(fs);
590 ext2fs_mark_ib_dirty(fs);
592 retval = ext2fs_allocate_block_bitmap(fs, _("reserved blocks"),
593 &rfs->reserve_blocks);
597 retval = adjust_fs_info(fs, rfs->old_fs, rfs->reserve_blocks, new_size);
602 * Check to make sure there are enough inodes
604 if ((rfs->old_fs->super->s_inodes_count -
605 rfs->old_fs->super->s_free_inodes_count) >
606 rfs->new_fs->super->s_inodes_count) {
612 * If we are shrinking the number block groups, we're done and
615 if (rfs->old_fs->group_desc_count > fs->group_desc_count) {
621 * If the number of block groups is staying the same, we're
622 * done and can exit now. (If the number block groups is
623 * shrinking, we had exited earlier.)
625 if (rfs->old_fs->group_desc_count >= fs->group_desc_count) {
631 * If we are using uninit_bg (aka GDT_CSUM) and the kernel
632 * supports lazy inode initialization, we can skip
633 * initializing the inode table.
635 if (lazy_itable_init &&
636 EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
637 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
643 * Initialize the inode table
645 retval = ext2fs_get_array(fs->blocksize, fs->inode_blocks_per_group,
650 memset(rfs->itable_buf, 0, fs->blocksize * fs->inode_blocks_per_group);
651 group_block = ext2fs_group_first_block2(fs,
652 rfs->old_fs->group_desc_count);
653 adj = rfs->old_fs->group_desc_count;
654 max_group = fs->group_desc_count - adj;
656 retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS,
661 for (i = rfs->old_fs->group_desc_count;
662 i < fs->group_desc_count; i++) {
664 * Write out the new inode table
666 retval = io_channel_write_blk64(fs->io,
667 ext2fs_inode_table_loc(fs, i),
668 fs->inode_blocks_per_group,
670 if (retval) goto errout;
672 io_channel_flush(fs->io);
674 retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS,
675 i - adj + 1, max_group);
679 group_block += fs->super->s_blocks_per_group;
681 io_channel_flush(fs->io);
688 /* --------------------------------------------------------------------
690 * Resize processing, phase 2.
692 * In this phase we adjust determine which blocks need to be moved, in
693 * blocks_to_move(). We then copy the blocks to their ultimate new
694 * destinations using block_mover(). Since we are copying blocks to
695 * their new locations, again during this pass we can abort without
697 * --------------------------------------------------------------------
701 * This helper function creates a block bitmap with all of the
702 * filesystem meta-data blocks.
704 static errcode_t mark_table_blocks(ext2_filsys fs,
705 ext2fs_block_bitmap bmap)
709 for (i = 0; i < fs->group_desc_count; i++) {
710 ext2fs_reserve_super_and_bgd(fs, i, bmap);
713 * Mark the blocks used for the inode table
715 ext2fs_mark_block_bitmap_range2(bmap,
716 ext2fs_inode_table_loc(fs, i),
717 fs->inode_blocks_per_group);
720 * Mark block used for the block bitmap
722 ext2fs_mark_block_bitmap2(bmap,
723 ext2fs_block_bitmap_loc(fs, i));
726 * Mark block used for the inode bitmap
728 ext2fs_mark_block_bitmap2(bmap,
729 ext2fs_inode_bitmap_loc(fs, i));
735 * This function checks to see if a particular block (either a
736 * superblock or a block group descriptor) overlaps with an inode or
737 * block bitmap block, or with the inode table.
739 static void mark_fs_metablock(ext2_resize_t rfs,
740 ext2fs_block_bitmap meta_bmap,
741 int group, blk64_t blk)
743 ext2_filsys fs = rfs->new_fs;
745 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
746 ext2fs_block_alloc_stats2(fs, blk, +1);
749 * Check to see if we overlap with the inode or block bitmap,
750 * or the inode tables. If not, and the block is in use, then
751 * mark it as a block to be moved.
753 if (IS_BLOCK_BM(fs, group, blk)) {
754 ext2fs_block_bitmap_loc_set(fs, group, 0);
755 rfs->needed_blocks++;
758 if (IS_INODE_BM(fs, group, blk)) {
759 ext2fs_inode_bitmap_loc_set(fs, group, 0);
760 rfs->needed_blocks++;
763 if (IS_INODE_TB(fs, group, blk)) {
764 ext2fs_inode_table_loc_set(fs, group, 0);
765 rfs->needed_blocks++;
768 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) {
771 for (i=0; i < rfs->old_fs->group_desc_count; i++) {
772 if (IS_BLOCK_BM(fs, i, blk)) {
773 ext2fs_block_bitmap_loc_set(fs, i, 0);
774 rfs->needed_blocks++;
777 if (IS_INODE_BM(fs, i, blk)) {
778 ext2fs_inode_bitmap_loc_set(fs, i, 0);
779 rfs->needed_blocks++;
782 if (IS_INODE_TB(fs, i, blk)) {
783 ext2fs_inode_table_loc_set(fs, i, 0);
784 rfs->needed_blocks++;
790 if (ext2fs_has_group_desc_csum(fs) &&
791 (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT))) {
793 * If the block bitmap is uninitialized, which means
794 * nothing other than standard metadata in use.
797 } else if (ext2fs_test_block_bitmap2(rfs->old_fs->block_map, blk) &&
798 !ext2fs_test_block_bitmap2(meta_bmap, blk)) {
799 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
800 rfs->needed_blocks++;
806 * This routine marks and unmarks reserved blocks in the new block
807 * bitmap. It also determines which blocks need to be moved and
808 * places this information into the move_blocks bitmap.
810 static errcode_t blocks_to_move(ext2_resize_t rfs)
813 dgrp_t i, max_groups, g;
814 blk64_t blk, group_blk;
815 blk64_t old_blocks, new_blocks;
816 unsigned int meta_bg, meta_bg_size;
818 ext2_filsys fs, old_fs;
819 ext2fs_block_bitmap meta_bmap;
823 old_fs = rfs->old_fs;
824 if (ext2fs_blocks_count(old_fs->super) > ext2fs_blocks_count(fs->super))
827 retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"),
832 retval = ext2fs_allocate_block_bitmap(fs, _("meta-data blocks"),
837 retval = mark_table_blocks(old_fs, meta_bmap);
844 * If we're shrinking the filesystem, we need to move all of
845 * the blocks that don't fit any more
847 for (blk = ext2fs_blocks_count(fs->super);
848 blk < ext2fs_blocks_count(old_fs->super); blk++) {
849 g = ext2fs_group_of_blk2(fs, blk);
850 if (ext2fs_has_group_desc_csum(fs) &&
851 ext2fs_bg_flags_test(old_fs, g, EXT2_BG_BLOCK_UNINIT)) {
853 * The block bitmap is uninitialized, so skip
854 * to the next block group.
856 blk = ext2fs_group_first_block2(fs, g+1) - 1;
859 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
860 !ext2fs_test_block_bitmap2(meta_bmap, blk)) {
861 ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
862 rfs->needed_blocks++;
864 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
867 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) {
868 old_blocks = old_fs->super->s_first_meta_bg;
869 new_blocks = fs->super->s_first_meta_bg;
871 old_blocks = old_fs->desc_blocks + old_fs->super->s_reserved_gdt_blocks;
872 new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
875 if (old_blocks == new_blocks) {
880 max_groups = fs->group_desc_count;
881 if (max_groups > old_fs->group_desc_count)
882 max_groups = old_fs->group_desc_count;
883 group_blk = old_fs->super->s_first_data_block;
885 * If we're reducing the number of descriptor blocks, this
886 * makes life easy. :-) We just have to mark some extra
889 if (old_blocks > new_blocks) {
890 for (i = 0; i < max_groups; i++) {
891 if (!ext2fs_bg_has_super(fs, i)) {
892 group_blk += fs->super->s_blocks_per_group;
895 for (blk = group_blk+1+new_blocks;
896 blk < group_blk+1+old_blocks; blk++) {
897 ext2fs_block_alloc_stats2(fs, blk, -1);
898 rfs->needed_blocks--;
900 group_blk += fs->super->s_blocks_per_group;
906 * If we're increasing the number of descriptor blocks, life
907 * gets interesting....
909 meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
910 flex_bg = fs->super->s_feature_incompat &
911 EXT4_FEATURE_INCOMPAT_FLEX_BG;
912 /* first reserve all of the existing fs meta blocks */
913 for (i = 0; i < max_groups; i++) {
914 has_super = ext2fs_bg_has_super(fs, i);
916 mark_fs_metablock(rfs, meta_bmap, i, group_blk);
918 meta_bg = i / meta_bg_size;
919 if (!(fs->super->s_feature_incompat &
920 EXT2_FEATURE_INCOMPAT_META_BG) ||
921 (meta_bg < fs->super->s_first_meta_bg)) {
923 for (blk = group_blk+1;
924 blk < group_blk + 1 + new_blocks; blk++)
925 mark_fs_metablock(rfs, meta_bmap,
931 if (((i % meta_bg_size) == 0) ||
932 ((i % meta_bg_size) == 1) ||
933 ((i % meta_bg_size) == (meta_bg_size-1)))
934 mark_fs_metablock(rfs, meta_bmap, i,
935 group_blk + has_super);
939 * Reserve the existing meta blocks that we know
940 * aren't to be moved.
942 * For flex_bg file systems, in order to avoid
943 * overwriting fs metadata (especially inode table
944 * blocks) belonging to a different block group when
945 * we are relocating the inode tables, we need to
946 * reserve all existing fs metadata blocks.
948 if (ext2fs_block_bitmap_loc(fs, i))
949 ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
950 ext2fs_block_bitmap_loc(fs, i));
951 else if (flex_bg && i < old_fs->group_desc_count)
952 ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
953 ext2fs_block_bitmap_loc(old_fs, i));
955 if (ext2fs_inode_bitmap_loc(fs, i))
956 ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
957 ext2fs_inode_bitmap_loc(fs, i));
958 else if (flex_bg && i < old_fs->group_desc_count)
959 ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
960 ext2fs_inode_bitmap_loc(old_fs, i));
962 if (ext2fs_inode_table_loc(fs, i))
963 ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks,
964 ext2fs_inode_table_loc(fs, i),
965 fs->inode_blocks_per_group);
966 else if (flex_bg && i < old_fs->group_desc_count)
967 ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks,
968 ext2fs_inode_table_loc(old_fs, i),
969 old_fs->inode_blocks_per_group);
971 group_blk += rfs->new_fs->super->s_blocks_per_group;
974 /* Allocate the missing data structures */
975 for (i = 0; i < max_groups; i++) {
976 if (ext2fs_inode_table_loc(fs, i) &&
977 ext2fs_inode_bitmap_loc(fs, i) &&
978 ext2fs_block_bitmap_loc(fs, i))
981 retval = ext2fs_allocate_group_table(fs, i,
982 rfs->reserve_blocks);
987 * For those structures that have changed, we need to
990 if (ext2fs_block_bitmap_loc(old_fs, i) !=
991 (blk = ext2fs_block_bitmap_loc(fs, i))) {
992 ext2fs_block_alloc_stats2(fs, blk, +1);
993 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
994 !ext2fs_test_block_bitmap2(meta_bmap, blk))
995 ext2fs_mark_block_bitmap2(rfs->move_blocks,
998 if (ext2fs_inode_bitmap_loc(old_fs, i) !=
999 (blk = ext2fs_inode_bitmap_loc(fs, i))) {
1000 ext2fs_block_alloc_stats2(fs, blk, +1);
1001 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
1002 !ext2fs_test_block_bitmap2(meta_bmap, blk))
1003 ext2fs_mark_block_bitmap2(rfs->move_blocks,
1008 * The inode table, if we need to relocate it, is
1009 * handled specially. We have to reserve the blocks
1010 * for both the old and the new inode table, since we
1011 * can't have the inode table be destroyed during the
1012 * block relocation phase.
1014 if (ext2fs_inode_table_loc(fs, i) == ext2fs_inode_table_loc(old_fs, i))
1015 continue; /* inode table not moved */
1017 rfs->needed_blocks += fs->inode_blocks_per_group;
1020 * Mark the new inode table as in use in the new block
1021 * allocation bitmap, and move any blocks that might
1024 for (blk = ext2fs_inode_table_loc(fs, i), j=0;
1025 j < fs->inode_blocks_per_group ; j++, blk++) {
1026 ext2fs_block_alloc_stats2(fs, blk, +1);
1027 if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
1028 !ext2fs_test_block_bitmap2(meta_bmap, blk))
1029 ext2fs_mark_block_bitmap2(rfs->move_blocks,
1034 * Make sure the old inode table is reserved in the
1035 * block reservation bitmap.
1037 for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0;
1038 j < fs->inode_blocks_per_group ; j++, blk++)
1039 ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
1045 ext2fs_free_block_bitmap(meta_bmap);
1051 * This helper function tries to allocate a new block. We try to
1052 * avoid hitting the original group descriptor blocks at least at
1053 * first, since we want to make it possible to recover from a badly
1054 * aborted resize operation as much as possible.
1056 * In the future, I may further modify this routine to balance out
1057 * where we get the new blocks across the various block groups.
1058 * Ideally we would allocate blocks that corresponded with the block
1059 * group of the containing inode, and keep contiguous blocks
1060 * together. However, this very difficult to do efficiently, since we
1061 * don't have the necessary information up front.
1065 #define DESPERATION 2
1067 static void init_block_alloc(ext2_resize_t rfs)
1069 rfs->alloc_state = AVOID_OLD;
1070 rfs->new_blk = rfs->new_fs->super->s_first_data_block;
1072 /* HACK for testing */
1073 if (ext2fs_blocks_count(rfs->new_fs->super) >
1074 ext2fs_blocks_count(rfs->old_fs->super))
1075 rfs->new_blk = ext2fs_blocks_count(rfs->old_fs->super);
1079 static blk64_t get_new_block(ext2_resize_t rfs)
1081 ext2_filsys fs = rfs->new_fs;
1084 if (rfs->new_blk >= ext2fs_blocks_count(fs->super)) {
1085 if (rfs->alloc_state == DESPERATION)
1088 #ifdef RESIZE2FS_DEBUG
1089 if (rfs->flags & RESIZE_DEBUG_BMOVE)
1090 printf("Going into desperation mode "
1091 "for block allocations\n");
1093 rfs->alloc_state = DESPERATION;
1094 rfs->new_blk = fs->super->s_first_data_block;
1097 if (ext2fs_test_block_bitmap2(fs->block_map, rfs->new_blk) ||
1098 ext2fs_test_block_bitmap2(rfs->reserve_blocks,
1100 ((rfs->alloc_state == AVOID_OLD) &&
1101 (rfs->new_blk < ext2fs_blocks_count(rfs->old_fs->super)) &&
1102 ext2fs_test_block_bitmap2(rfs->old_fs->block_map,
1107 return rfs->new_blk;
1111 static errcode_t resize2fs_get_alloc_block(ext2_filsys fs, blk64_t goal,
1114 ext2_resize_t rfs = (ext2_resize_t) fs->priv_data;
1117 blk = get_new_block(rfs);
1121 #ifdef RESIZE2FS_DEBUG
1122 if (rfs->flags & 0xF)
1123 printf("get_alloc_block allocating %llu\n", blk);
1126 ext2fs_mark_block_bitmap2(rfs->old_fs->block_map, blk);
1127 ext2fs_mark_block_bitmap2(rfs->new_fs->block_map, blk);
1128 *ret = (blk64_t) blk;
1132 static errcode_t block_mover(ext2_resize_t rfs)
1134 blk64_t blk, old_blk, new_blk;
1135 ext2_filsys fs = rfs->new_fs;
1136 ext2_filsys old_fs = rfs->old_fs;
1141 ext2_badblocks_list badblock_list = 0;
1142 int bb_modified = 0;
1144 fs->get_alloc_block = resize2fs_get_alloc_block;
1145 old_fs->get_alloc_block = resize2fs_get_alloc_block;
1147 retval = ext2fs_read_bb_inode(old_fs, &badblock_list);
1151 new_blk = fs->super->s_first_data_block;
1152 if (!rfs->itable_buf) {
1153 retval = ext2fs_get_array(fs->blocksize,
1154 fs->inode_blocks_per_group,
1159 retval = ext2fs_create_extent_table(&rfs->bmap, 0);
1164 * The first step is to figure out where all of the blocks
1167 to_move = moved = 0;
1168 init_block_alloc(rfs);
1169 for (blk = old_fs->super->s_first_data_block;
1170 blk < ext2fs_blocks_count(old_fs->super); blk++) {
1171 if (!ext2fs_test_block_bitmap2(old_fs->block_map, blk))
1173 if (!ext2fs_test_block_bitmap2(rfs->move_blocks, blk))
1175 if (ext2fs_badblocks_list_test(badblock_list, blk)) {
1176 ext2fs_badblocks_list_del(badblock_list, blk);
1181 new_blk = get_new_block(rfs);
1186 ext2fs_block_alloc_stats2(fs, new_blk, +1);
1187 ext2fs_add_extent_entry(rfs->bmap, blk, new_blk);
1193 ext2fs_free_extent_table(rfs->bmap);
1201 * Step two is to actually move the blocks
1203 retval = ext2fs_iterate_extent(rfs->bmap, 0, 0, 0);
1204 if (retval) goto errout;
1206 if (rfs->progress) {
1207 retval = (rfs->progress)(rfs, E2_RSZ_BLOCK_RELOC_PASS,
1213 retval = ext2fs_iterate_extent(rfs->bmap, &old_blk, &new_blk, &size);
1214 if (retval) goto errout;
1217 #ifdef RESIZE2FS_DEBUG
1218 if (rfs->flags & RESIZE_DEBUG_BMOVE)
1219 printf("Moving %llu blocks %llu->%llu\n",
1220 size, old_blk, new_blk);
1224 if (c > fs->inode_blocks_per_group)
1225 c = fs->inode_blocks_per_group;
1226 retval = io_channel_read_blk64(fs->io, old_blk, c,
1228 if (retval) goto errout;
1229 retval = io_channel_write_blk64(fs->io, new_blk, c,
1231 if (retval) goto errout;
1236 if (rfs->progress) {
1237 io_channel_flush(fs->io);
1238 retval = (rfs->progress)(rfs,
1239 E2_RSZ_BLOCK_RELOC_PASS,
1245 io_channel_flush(fs->io);
1249 if (badblock_list) {
1250 if (!retval && bb_modified)
1251 retval = ext2fs_update_bb_inode(old_fs,
1253 ext2fs_badblocks_list_free(badblock_list);
1259 /* --------------------------------------------------------------------
1261 * Resize processing, phase 3
1263 * --------------------------------------------------------------------
1267 struct process_block_struct {
1270 struct ext2_inode * inode;
1276 static int process_block(ext2_filsys fs, blk64_t *block_nr,
1277 e2_blkcnt_t blockcnt,
1278 blk64_t ref_block EXT2FS_ATTR((unused)),
1279 int ref_offset EXT2FS_ATTR((unused)), void *priv_data)
1281 struct process_block_struct *pb;
1283 blk64_t block, new_block;
1286 pb = (struct process_block_struct *) priv_data;
1288 if (pb->rfs->bmap) {
1289 new_block = ext2fs_extent_translate(pb->rfs->bmap, block);
1291 *block_nr = new_block;
1292 ret |= BLOCK_CHANGED;
1294 #ifdef RESIZE2FS_DEBUG
1295 if (pb->rfs->flags & RESIZE_DEBUG_BMOVE)
1296 printf("ino=%u, blockcnt=%lld, %llu->%llu\n",
1297 pb->ino, blockcnt, block, new_block);
1303 retval = ext2fs_add_dir_block2(fs->dblist, pb->ino,
1304 block, (int) blockcnt);
1316 static errcode_t progress_callback(ext2_filsys fs,
1317 ext2_inode_scan scan EXT2FS_ATTR((unused)),
1318 dgrp_t group, void * priv_data)
1320 ext2_resize_t rfs = (ext2_resize_t) priv_data;
1324 * This check is to protect against old ext2 libraries. It
1325 * shouldn't be needed against new libraries.
1330 if (rfs->progress) {
1331 io_channel_flush(fs->io);
1332 retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS,
1333 group+1, fs->group_desc_count);
1341 static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
1343 struct process_block_struct pb;
1344 ext2_ino_t ino, new_inode;
1345 struct ext2_inode *inode = NULL;
1346 ext2_inode_scan scan = NULL;
1348 char *block_buf = 0;
1349 ext2_ino_t start_to_move;
1354 if ((rfs->old_fs->group_desc_count <=
1355 rfs->new_fs->group_desc_count) &&
1360 * Save the original size of the old filesystem, and
1361 * temporarily set the size to be the new size if the new size
1362 * is larger. We need to do this to avoid catching an error
1363 * by the block iterator routines
1365 orig_size = ext2fs_blocks_count(rfs->old_fs->super);
1366 if (orig_size < ext2fs_blocks_count(rfs->new_fs->super))
1367 ext2fs_blocks_count_set(rfs->old_fs->super,
1368 ext2fs_blocks_count(rfs->new_fs->super));
1370 retval = ext2fs_open_inode_scan(rfs->old_fs, 0, &scan);
1371 if (retval) goto errout;
1373 retval = ext2fs_init_dblist(rfs->old_fs, 0);
1374 if (retval) goto errout;
1375 retval = ext2fs_get_array(rfs->old_fs->blocksize, 3, &block_buf);
1376 if (retval) goto errout;
1378 start_to_move = (rfs->new_fs->group_desc_count *
1379 rfs->new_fs->super->s_inodes_per_group);
1381 if (rfs->progress) {
1382 retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS,
1383 0, rfs->old_fs->group_desc_count);
1387 ext2fs_set_inode_callback(scan, progress_callback, (void *) rfs);
1391 new_inode = EXT2_FIRST_INODE(rfs->new_fs->super);
1392 inode_size = EXT2_INODE_SIZE(rfs->new_fs->super);
1393 inode = malloc(inode_size);
1399 * First, copy all of the inodes that need to be moved
1400 * elsewhere in the inode table
1403 retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size);
1404 if (retval) goto errout;
1408 if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO)
1409 continue; /* inode not in use */
1411 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
1414 if (ext2fs_file_acl_block(rfs->old_fs, inode) && rfs->bmap) {
1415 new_block = ext2fs_extent_translate(rfs->bmap,
1416 ext2fs_file_acl_block(rfs->old_fs, inode));
1418 ext2fs_file_acl_block_set(rfs->old_fs, inode,
1420 retval = ext2fs_write_inode_full(rfs->old_fs,
1421 ino, inode, inode_size);
1422 if (retval) goto errout;
1426 if (ext2fs_inode_has_valid_blocks2(rfs->old_fs, inode) &&
1427 (rfs->bmap || pb.is_dir)) {
1429 retval = ext2fs_block_iterate3(rfs->old_fs,
1431 process_block, &pb);
1440 if (ino <= start_to_move)
1441 continue; /* Don't need to move it. */
1446 retval = ext2fs_new_inode(rfs->new_fs, 0, 0, 0, &new_inode);
1450 ext2fs_inode_alloc_stats2(rfs->new_fs, new_inode, +1,
1453 /* Get the new version of the inode */
1454 retval = ext2fs_read_inode_full(rfs->old_fs, ino,
1456 if (retval) goto errout;
1458 inode->i_ctime = time(0);
1459 retval = ext2fs_write_inode_full(rfs->old_fs, new_inode,
1461 if (retval) goto errout;
1463 #ifdef RESIZE2FS_DEBUG
1464 if (rfs->flags & RESIZE_DEBUG_INODEMAP)
1465 printf("Inode moved %u->%u\n", ino, new_inode);
1468 retval = ext2fs_create_extent_table(&rfs->imap, 0);
1472 ext2fs_add_extent_entry(rfs->imap, ino, new_inode);
1474 io_channel_flush(rfs->old_fs->io);
1477 ext2fs_blocks_count_set(rfs->old_fs->super, orig_size);
1479 ext2fs_free_extent_table(rfs->bmap);
1483 ext2fs_close_inode_scan(scan);
1485 ext2fs_free_mem(&block_buf);
1490 /* --------------------------------------------------------------------
1492 * Resize processing, phase 4.
1494 * --------------------------------------------------------------------
1500 unsigned int max_dirs;
1504 static int check_and_change_inodes(ext2_ino_t dir,
1505 int entry EXT2FS_ATTR((unused)),
1506 struct ext2_dir_entry *dirent, int offset,
1507 int blocksize EXT2FS_ATTR((unused)),
1508 char *buf EXT2FS_ATTR((unused)),
1511 struct istruct *is = (struct istruct *) priv_data;
1512 struct ext2_inode inode;
1513 ext2_ino_t new_inode;
1516 if (is->rfs->progress && offset == 0) {
1517 io_channel_flush(is->rfs->old_fs->io);
1518 is->err = (is->rfs->progress)(is->rfs,
1519 E2_RSZ_INODE_REF_UPD_PASS,
1520 ++is->num, is->max_dirs);
1522 return DIRENT_ABORT;
1528 new_inode = ext2fs_extent_translate(is->rfs->imap, dirent->inode);
1532 #ifdef RESIZE2FS_DEBUG
1533 if (is->rfs->flags & RESIZE_DEBUG_INODEMAP)
1534 printf("Inode translate (dir=%u, name=%.*s, %u->%u)\n",
1535 dir, dirent->name_len&0xFF, dirent->name,
1536 dirent->inode, new_inode);
1539 dirent->inode = new_inode;
1541 /* Update the directory mtime and ctime */
1542 retval = ext2fs_read_inode(is->rfs->old_fs, dir, &inode);
1544 inode.i_mtime = inode.i_ctime = time(0);
1545 is->err = ext2fs_write_inode(is->rfs->old_fs, dir, &inode);
1547 return DIRENT_ABORT;
1550 return DIRENT_CHANGED;
1553 static errcode_t inode_ref_fix(ext2_resize_t rfs)
1562 * Now, we iterate over all of the directories to update the
1566 is.max_dirs = ext2fs_dblist_count2(rfs->old_fs->dblist);
1570 if (rfs->progress) {
1571 retval = (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS,
1577 retval = ext2fs_dblist_dir_iterate(rfs->old_fs->dblist,
1578 DIRENT_FLAG_INCLUDE_EMPTY, 0,
1579 check_and_change_inodes, &is);
1587 if (rfs->progress && (is.num < is.max_dirs))
1588 (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS,
1589 is.max_dirs, is.max_dirs);
1592 ext2fs_free_extent_table(rfs->imap);
1598 /* --------------------------------------------------------------------
1600 * Resize processing, phase 5.
1602 * In this phase we actually move the inode table around, and then
1603 * update the summary statistics. This is scary, since aborting here
1604 * will potentially scramble the filesystem. (We are moving the
1605 * inode tables around in place, and so the potential for lost data,
1606 * or at the very least scrambling the mapping between filenames and
1607 * inode numbers is very high in case of a power failure here.)
1608 * --------------------------------------------------------------------
1613 * A very scary routine --- this one moves the inode table around!!!
1615 * After this you have to use the rfs->new_fs file handle to read and
1618 static errcode_t move_itables(ext2_resize_t rfs)
1622 dgrp_t i, max_groups;
1623 ext2_filsys fs = rfs->new_fs;
1625 blk64_t old_blk, new_blk, blk;
1627 int j, to_move, moved;
1629 max_groups = fs->group_desc_count;
1630 if (max_groups > rfs->old_fs->group_desc_count)
1631 max_groups = rfs->old_fs->group_desc_count;
1633 size = fs->blocksize * fs->inode_blocks_per_group;
1634 if (!rfs->itable_buf) {
1635 retval = ext2fs_get_mem(size, &rfs->itable_buf);
1641 * Figure out how many inode tables we need to move
1643 to_move = moved = 0;
1644 for (i=0; i < max_groups; i++)
1645 if (ext2fs_inode_table_loc(rfs->old_fs, i) !=
1646 ext2fs_inode_table_loc(fs, i))
1652 if (rfs->progress) {
1653 retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS,
1659 rfs->old_fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
1661 for (i=0; i < max_groups; i++) {
1662 old_blk = ext2fs_inode_table_loc(rfs->old_fs, i);
1663 new_blk = ext2fs_inode_table_loc(fs, i);
1664 diff = new_blk - old_blk;
1666 #ifdef RESIZE2FS_DEBUG
1667 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
1668 printf("Itable move group %d block %llu->%llu (diff %lld)\n",
1669 i, old_blk, new_blk, diff);
1675 retval = io_channel_read_blk64(fs->io, old_blk,
1676 fs->inode_blocks_per_group,
1681 * The end of the inode table segment often contains
1682 * all zeros, and we're often only moving the inode
1683 * table down a block or two. If so, we can optimize
1684 * things by not rewriting blocks that we know to be zero
1687 for (cp = rfs->itable_buf+size-1, n=0; n < size; n++, cp--)
1690 n = n >> EXT2_BLOCK_SIZE_BITS(fs->super);
1691 #ifdef RESIZE2FS_DEBUG
1692 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
1693 printf("%d blocks of zeros...\n", n);
1695 num = fs->inode_blocks_per_group;
1699 retval = io_channel_write_blk64(fs->io, new_blk,
1700 num, rfs->itable_buf);
1702 io_channel_write_blk64(fs->io, old_blk,
1703 num, rfs->itable_buf);
1707 retval = io_channel_write_blk64(fs->io,
1708 old_blk + fs->inode_blocks_per_group,
1709 diff, (rfs->itable_buf +
1710 (fs->inode_blocks_per_group - diff) *
1716 for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0;
1717 j < fs->inode_blocks_per_group ; j++, blk++)
1718 ext2fs_block_alloc_stats2(fs, blk, -1);
1720 ext2fs_inode_table_loc_set(rfs->old_fs, i, new_blk);
1721 ext2fs_group_desc_csum_set(rfs->old_fs, i);
1722 ext2fs_mark_super_dirty(rfs->old_fs);
1723 ext2fs_flush(rfs->old_fs);
1725 if (rfs->progress) {
1726 retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS,
1732 mark_table_blocks(fs, fs->block_map);
1734 #ifdef RESIZE2FS_DEBUG
1735 if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
1736 printf("Inode table move finished.\n");
1745 * Fix the resize inode
1747 static errcode_t fix_resize_inode(ext2_filsys fs)
1749 struct ext2_inode inode;
1751 char *block_buf = NULL;
1753 if (!(fs->super->s_feature_compat &
1754 EXT2_FEATURE_COMPAT_RESIZE_INODE))
1757 retval = ext2fs_get_mem(fs->blocksize, &block_buf);
1758 if (retval) goto errout;
1760 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
1761 if (retval) goto errout;
1763 ext2fs_iblk_set(fs, &inode, 1);
1765 retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
1766 if (retval) goto errout;
1768 if (!inode.i_block[EXT2_DIND_BLOCK]) {
1770 * Avoid zeroing out block #0; that's rude. This
1771 * should never happen anyway since the filesystem
1772 * should be fsck'ed and we assume it is consistent.
1775 _("Should never happen: resize inode corrupt!\n"));
1779 memset(block_buf, 0, fs->blocksize);
1781 retval = io_channel_write_blk64(fs->io, inode.i_block[EXT2_DIND_BLOCK],
1783 if (retval) goto errout;
1785 retval = ext2fs_create_resize_inode(fs);
1791 ext2fs_free_mem(&block_buf);
1796 * Finally, recalculate the summary information
1798 static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs)
1802 unsigned int group = 0;
1803 unsigned int count = 0;
1804 blk64_t total_blocks_free = 0;
1805 int total_inodes_free = 0;
1808 blk64_t super_blk, old_desc_blk, new_desc_blk;
1809 int old_desc_blocks;
1812 * First calculate the block statistics
1814 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT);
1815 ext2fs_super_and_bgd_loc2(fs, group, &super_blk, &old_desc_blk,
1817 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
1818 old_desc_blocks = fs->super->s_first_meta_bg;
1820 old_desc_blocks = fs->desc_blocks +
1821 fs->super->s_reserved_gdt_blocks;
1822 for (blk = fs->super->s_first_data_block;
1823 blk < ext2fs_blocks_count(fs->super); blk++) {
1825 !((blk == super_blk) ||
1826 ((old_desc_blk && old_desc_blocks &&
1827 (blk >= old_desc_blk) &&
1828 (blk < old_desc_blk + old_desc_blocks))) ||
1829 ((new_desc_blk && (blk == new_desc_blk))) ||
1830 (blk == ext2fs_block_bitmap_loc(fs, group)) ||
1831 (blk == ext2fs_inode_bitmap_loc(fs, group)) ||
1832 ((blk >= ext2fs_inode_table_loc(fs, group) &&
1833 (blk < ext2fs_inode_table_loc(fs, group)
1834 + fs->inode_blocks_per_group))))) ||
1835 (!ext2fs_fast_test_block_bitmap2(fs->block_map, blk))) {
1837 total_blocks_free++;
1840 if ((count == fs->super->s_blocks_per_group) ||
1841 (blk == ext2fs_blocks_count(fs->super)-1)) {
1842 ext2fs_bg_free_blocks_count_set(fs, group, group_free);
1843 ext2fs_group_desc_csum_set(fs, group);
1845 if (group >= fs->group_desc_count)
1849 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT);
1850 ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
1853 if (fs->super->s_feature_incompat &
1854 EXT2_FEATURE_INCOMPAT_META_BG)
1855 old_desc_blocks = fs->super->s_first_meta_bg;
1857 old_desc_blocks = fs->desc_blocks +
1858 fs->super->s_reserved_gdt_blocks;
1861 ext2fs_free_blocks_count_set(fs->super, total_blocks_free);
1864 * Next, calculate the inode statistics
1870 /* Protect loop from wrap-around if s_inodes_count maxed */
1871 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT);
1872 for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) {
1874 !ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino)) {
1876 total_inodes_free++;
1879 if ((count == fs->super->s_inodes_per_group) ||
1880 (ino == fs->super->s_inodes_count)) {
1881 ext2fs_bg_free_inodes_count_set(fs, group, group_free);
1882 ext2fs_group_desc_csum_set(fs, group);
1884 if (group >= fs->group_desc_count)
1888 uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT);
1891 fs->super->s_free_inodes_count = total_inodes_free;
1892 ext2fs_mark_super_dirty(fs);
1897 * Journal may have been relocated; update the backup journal blocks
1898 * in the superblock.
1900 static errcode_t fix_sb_journal_backup(ext2_filsys fs)
1903 struct ext2_inode inode;
1905 if (!(fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
1908 /* External journal? Nothing to do. */
1909 if (fs->super->s_journal_dev && !fs->super->s_journal_inum)
1912 retval = ext2fs_read_inode(fs, fs->super->s_journal_inum, &inode);
1915 memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
1916 fs->super->s_jnl_blocks[15] = inode.i_size_high;
1917 fs->super->s_jnl_blocks[16] = inode.i_size;
1918 fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
1919 ext2fs_mark_super_dirty(fs);
1923 static int calc_group_overhead(ext2_filsys fs, blk64_t grp,
1924 int old_desc_blocks)
1926 blk64_t super_blk, old_desc_blk, new_desc_blk;
1929 /* inode table blocks plus allocation bitmaps */
1930 overhead = fs->inode_blocks_per_group + 2;
1932 ext2fs_super_and_bgd_loc2(fs, grp, &super_blk,
1933 &old_desc_blk, &new_desc_blk, 0);
1934 if ((grp == 0) || super_blk)
1937 overhead += old_desc_blocks;
1938 else if (new_desc_blk)
1945 * calcluate the minimum number of blocks the given fs can be resized to
1947 blk64_t calculate_minimum_resize_size(ext2_filsys fs)
1949 ext2_ino_t inode_count;
1950 blk64_t blks_needed, groups, data_blocks;
1951 blk64_t grp, data_needed, last_start;
1952 blk64_t overhead = 0;
1953 int old_desc_blocks;
1954 int extra_groups = 0;
1955 int flexbg_size = 1 << fs->super->s_log_groups_per_flex;
1958 * first figure out how many group descriptors we need to
1959 * handle the number of inodes we have
1961 inode_count = fs->super->s_inodes_count -
1962 fs->super->s_free_inodes_count;
1963 blks_needed = ext2fs_div_ceil(inode_count,
1964 fs->super->s_inodes_per_group) *
1965 EXT2_BLOCKS_PER_GROUP(fs->super);
1966 groups = ext2fs_div64_ceil(blks_needed,
1967 EXT2_BLOCKS_PER_GROUP(fs->super));
1970 * number of old-style block group descriptor blocks
1972 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
1973 old_desc_blocks = fs->super->s_first_meta_bg;
1975 old_desc_blocks = fs->desc_blocks +
1976 fs->super->s_reserved_gdt_blocks;
1978 /* calculate how many blocks are needed for data */
1979 data_needed = ext2fs_blocks_count(fs->super) -
1980 ext2fs_free_blocks_count(fs->super);
1982 for (grp = 0; grp < fs->group_desc_count; grp++)
1983 data_needed -= calc_group_overhead(fs, grp, old_desc_blocks);
1986 * For ext4 we need to allow for up to a flex_bg worth of
1987 * inode tables of slack space so the resize operation can be
1988 * guaranteed to finish.
1990 if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) {
1991 extra_groups = flexbg_size - (groups & (flexbg_size - 1));
1992 data_needed += fs->inode_blocks_per_group * extra_groups;
1993 extra_groups = groups % flexbg_size;
1997 * figure out how many data blocks we have given the number of groups
1998 * we need for our inodes
2000 data_blocks = groups * EXT2_BLOCKS_PER_GROUP(fs->super);
2002 for (grp = 0; grp < groups; grp++) {
2003 overhead = calc_group_overhead(fs, grp, old_desc_blocks);
2006 * we want to keep track of how much data we can store in
2007 * the groups leading up to the last group so we can determine
2008 * how big the last group needs to be
2010 if (grp != (groups - 1))
2011 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) -
2014 data_blocks -= overhead;
2018 * if we need more group descriptors in order to accomodate our data
2019 * then we need to add them here
2021 while (data_needed > data_blocks) {
2022 blk64_t remainder = data_needed - data_blocks;
2025 /* figure out how many more groups we need for the data */
2026 extra_grps = ext2fs_div64_ceil(remainder,
2027 EXT2_BLOCKS_PER_GROUP(fs->super));
2029 data_blocks += extra_grps * EXT2_BLOCKS_PER_GROUP(fs->super);
2031 /* ok we have to account for the last group */
2032 overhead = calc_group_overhead(fs, groups-1, old_desc_blocks);
2033 last_start += EXT2_BLOCKS_PER_GROUP(fs->super) - overhead;
2035 for (grp = groups; grp < groups+extra_grps; grp++) {
2036 overhead = calc_group_overhead(fs, grp,
2040 * again, we need to see how much data we cram into
2041 * all of the groups leading up to the last group
2043 if (grp != (groups + extra_grps - 1))
2044 last_start += EXT2_BLOCKS_PER_GROUP(fs->super)
2047 data_blocks -= overhead;
2050 groups += extra_grps;
2051 extra_groups += extra_grps;
2052 if (fs->super->s_feature_incompat
2053 & EXT4_FEATURE_INCOMPAT_FLEX_BG
2054 && extra_groups > flexbg_size) {
2056 * For ext4 we need to allow for up to a flex_bg worth
2057 * of inode tables of slack space so the resize
2058 * operation can be guaranteed to finish.
2060 extra_groups = flexbg_size -
2061 (groups & (flexbg_size - 1));
2062 data_needed += (fs->inode_blocks_per_group *
2064 extra_groups = groups % flexbg_size;
2068 /* now for the fun voodoo */
2069 overhead = calc_group_overhead(fs, groups-1, old_desc_blocks);
2072 * if this is the case then the last group is going to have data in it
2073 * so we need to adjust the size of the last group accordingly
2075 if (last_start < data_needed) {
2076 blk64_t remainder = data_needed - last_start;
2079 * 50 is a magic number that mkfs/resize uses to see if its
2080 * even worth making/resizing the fs. basically you need to
2081 * have at least 50 blocks in addition to the blocks needed
2082 * for the metadata in the last group
2085 overhead += remainder;
2091 overhead += fs->super->s_first_data_block;
2094 * since our last group doesn't have to be BLOCKS_PER_GROUP large, we
2095 * only do groups-1, and then add the number of blocks needed to
2096 * handle the group descriptor metadata+data that we need
2098 blks_needed = (groups-1) * EXT2_BLOCKS_PER_GROUP(fs->super);
2099 blks_needed += overhead;
2102 * If at this point we've already added up more "needed" than
2103 * the current size, just return current size as minimum.
2105 if (blks_needed >= ext2fs_blocks_count(fs->super))
2106 return ext2fs_blocks_count(fs->super);
2108 * We need to reserve a few extra blocks if extents are
2109 * enabled, in case we need to grow the extent tree. The more
2110 * we shrink the file system, the more space we need.
2112 if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS)
2113 blks_needed += (ext2fs_blocks_count(fs->super) -