2015-08-26 16:22:51

by Jan Kara

[permalink] [raw]
Subject: [PATCH 00/21 v2] e2fsprogs: Resizing rewrite

Hello,

this patch series factors out large parts of resizing code into libext2fs.
The motivation of this is that handling of enabling / disabling of more and
more features requires moving blocks or inodes with rewriting all the
references and using resize2fs for that is not logical from user interface
POV.

The series is structured as follows.

* Patches 1-4 are various small cleanups and improvements.

* Patches 5-6 implement the main functionality. The functionality is
implemented by two functions:

ext2fs_move_blocks() which gets filesystem and bitmap of blocks which it should
make free and the function takes care of everything needed to make the blocks
free.

ext2fs_move_inodes() which gets filesystem and bitmap of inodes which it should
make free and the function takes care of everything needed to make these inodes
free.

* Patches 7-8 implements enabling / disabling 64-bit feature in tune2fs where
it is more logical and update tests to use tune2fs instead of resize2fs.

* Patches 9-14 add support for changing number of reserved inodes in e2fsprogs,
update tests to reflect changed default number of reserved inodes and also
add some basic testing of the new functionality.

* Patches 15-16 remove some now undeeded code

* Patches 17-21 change resize2fs itself to use code from libext2fs to perform
resizing.

I have verified that all the tests in e2fsprogs now pass so things should be
working reasonably but since this is basically a complete rewrite of the
resizing code which is pretty complex, there may be bugs still lurking...

Honza


2015-08-26 16:22:51

by Jan Kara

[permalink] [raw]
Subject: [PATCH 04/21] ext2fs: Provide helper for wiping resize inode

Provide a helper function ext2fs_wipe_resize_inode() which clears resize
inode and use it from resize2fs.

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/ext2fs.h | 1 +
lib/ext2fs/res_gdt.c | 34 ++++++++++++++++++++++++++++++++++
resize/resize2fs.c | 26 ++------------------------
3 files changed, 37 insertions(+), 24 deletions(-)

diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 3eda8d1f4ad3..0b8d1f6f22b1 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1588,6 +1588,7 @@ extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,

/* res_gdt.c */
extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
+extern errcode_t ext2fs_wipe_resize_inode(ext2_filsys fs);

/*sha256.c */
#define EXT2FS_SHA256_LENGTH 32
diff --git a/lib/ext2fs/res_gdt.c b/lib/ext2fs/res_gdt.c
index 46db61c5cf0d..5a44f5676df4 100644
--- a/lib/ext2fs/res_gdt.c
+++ b/lib/ext2fs/res_gdt.c
@@ -238,3 +238,37 @@ out_free:
return retval;
}

+/* Clear resize inode so that it can be recreated */
+errcode_t ext2fs_wipe_resize_inode(ext2_filsys fs)
+{
+ struct ext2_inode inode;
+ errcode_t retval;
+
+ retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
+ if (retval)
+ goto errout;
+
+ ext2fs_iblk_set(fs, &inode, 1);
+
+ retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
+ if (retval)
+ goto errout;
+
+ /* Check resize inode is sane */
+ if (!inode.i_block[EXT2_DIND_BLOCK]) {
+ retval = EINVAL;
+ goto errout;
+ }
+
+ retval = ext2fs_zero_blocks2(fs, inode.i_block[EXT2_DIND_BLOCK], 1,
+ NULL, NULL);
+ if (retval)
+ goto errout;
+
+ retval = ext2fs_create_resize_inode(fs);
+ if (retval)
+ goto errout;
+
+errout:
+ return retval;
+}
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index df6fdf1de913..ed69646984ad 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -2569,34 +2569,12 @@ static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
*/
static errcode_t fix_resize_inode(ext2_filsys fs)
{
- struct ext2_inode inode;
errcode_t retval;

- if (!(fs->super->s_feature_compat &
- EXT2_FEATURE_COMPAT_RESIZE_INODE))
+ if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE))
return 0;

- retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
- if (retval) goto errout;
-
- ext2fs_iblk_set(fs, &inode, 1);
-
- retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
- if (retval) goto errout;
-
- if (!inode.i_block[EXT2_DIND_BLOCK]) {
- /*
- * Avoid zeroing out block #0; that's rude. This
- * should never happen anyway since the filesystem
- * should be fsck'ed and we assume it is consistent.
- */
- fprintf(stderr, "%s",
- _("Should never happen: resize inode corrupt!\n"));
- exit(1);
- }

2015-08-26 16:22:51

by Jan Kara

[permalink] [raw]
Subject: [PATCH 01/21] ext2fs: Add pointer to allocator private data into ext2_filsys

From: Jan Kara <[email protected]>

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/ext2fs.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 613f0d1bcc91..13cbe567b19c 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -279,6 +279,8 @@ struct struct_ext2_filsys {

io_channel journal_io;
char *journal_name;
+ /* Private data for use by get_alloc_block() function */
+ void *alloc_data;
};

#if EXT2_FLAT_INCLUDES
--
2.1.4


2015-08-26 16:23:02

by Jan Kara

[permalink] [raw]
Subject: [PATCH 15/21] resize2fs: Rip out 64-bit feature handling from resize2fs

Now that tune2fs is able to properly set / clear 64BIT feature, just rip
out the handling from resize2fs as it doesn't make much sense there from
user point of view. So far this functionality wasn't in any officially
released e2fsprogs so just printing message that tune2fs should be used
should be fine.

Signed-off-by: Jan Kara <[email protected]>
---
resize/main.c | 59 +--------
resize/resize2fs.8.in | 17 +--
resize/resize2fs.c | 331 +-------------------------------------------------
3 files changed, 9 insertions(+), 398 deletions(-)

diff --git a/resize/main.c b/resize/main.c
index 9da3a958cc01..2efb47d2b416 100644
--- a/resize/main.c
+++ b/resize/main.c
@@ -43,7 +43,7 @@ static char *device_name, *io_options;
static void usage (char *prog)
{
fprintf (stderr, _("Usage: %s [-d debug_flags] [-f] [-F] [-M] [-P] "
- "[-p] device [-b|-s|new_size] [-z undo_file]\n\n"),
+ "[-p] device [new_size] [-z undo_file]\n\n"),
prog);

exit (1);
@@ -280,7 +280,7 @@ int main (int argc, char ** argv)
if (argc && *argv)
program_name = *argv;

- while ((c = getopt(argc, argv, "d:fFhMPpS:bsz:")) != EOF) {
+ while ((c = getopt(argc, argv, "d:fFhMPpS:z:")) != EOF) {
switch (c) {
case 'h':
usage(program_name);
@@ -306,12 +306,6 @@ int main (int argc, char ** argv)
case 'S':
use_stride = atoi(optarg);
break;
- case 'b':
- flags |= RESIZE_ENABLE_64BIT;
- break;
- case 's':
- flags |= RESIZE_DISABLE_64BIT;
- break;
case 'z':
undo_file = optarg;
break;
@@ -503,10 +497,6 @@ int main (int argc, char ** argv)
if (sys_page_size > blocksize)
new_size &= ~((sys_page_size / blocksize)-1);
}
- /* If changing 64bit, don't change the filesystem size. */
- if (flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)) {
- new_size = ext2fs_blocks_count(fs->super);
- }
if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
EXT4_FEATURE_INCOMPAT_64BIT)) {
/* Take 16T down to 2^32-1 blocks */
@@ -558,58 +548,19 @@ int main (int argc, char ** argv)
blocksize / 1024, new_size);
exit(1);
}
- if ((flags & RESIZE_DISABLE_64BIT) && (flags & RESIZE_ENABLE_64BIT)) {
- fprintf(stderr, _("Cannot set and unset 64bit feature.\n"));
- exit(1);
- } else if (flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)) {
- if (new_size >= (1ULL << 32)) {
- fprintf(stderr, _("Cannot change the 64bit feature "
- "on a filesystem that is larger than "
- "2^32 blocks.\n"));
- exit(1);
- }
- if (mount_flags & EXT2_MF_MOUNTED) {
- fprintf(stderr, _("Cannot change the 64bit feature "
- "while the filesystem is mounted.\n"));
- exit(1);
- }
- if (flags & RESIZE_ENABLE_64BIT &&
- !EXT2_HAS_INCOMPAT_FEATURE(fs->super,
- EXT3_FEATURE_INCOMPAT_EXTENTS)) {
- fprintf(stderr, _("Please enable the extents feature "
- "with tune2fs before enabling the 64bit "
- "feature.\n"));
- exit(1);
- }
- } else if (new_size == ext2fs_blocks_count(fs->super)) {
+ if (new_size == ext2fs_blocks_count(fs->super)) {
fprintf(stderr, _("The filesystem is already %llu (%dk) "
"blocks long. Nothing to do!\n\n"), new_size,
blocksize / 1024);
exit(0);
}
- if ((flags & RESIZE_ENABLE_64BIT) &&
- EXT2_HAS_INCOMPAT_FEATURE(fs->super, EXT4_FEATURE_INCOMPAT_64BIT)) {
- fprintf(stderr, _("The filesystem is already 64-bit.\n"));
- exit(0);
- }
- if ((flags & RESIZE_DISABLE_64BIT) &&
- !EXT2_HAS_INCOMPAT_FEATURE(fs->super, EXT4_FEATURE_INCOMPAT_64BIT)) {
- fprintf(stderr, _("The filesystem is already 32-bit.\n"));
- exit(0);
- }
if (mount_flags & EXT2_MF_MOUNTED) {
bigalloc_check(fs, force);
retval = online_resize_fs(fs, mtpt, &new_size, flags);
} else {
bigalloc_check(fs, force);
- if (flags & RESIZE_ENABLE_64BIT)
- printf(_("Converting the filesystem to 64-bit.\n"));
- else if (flags & RESIZE_DISABLE_64BIT)
- printf(_("Converting the filesystem to 32-bit.\n"));
- else
- printf(_("Resizing the filesystem on "
- "%s to %llu (%dk) blocks.\n"),
- device_name, new_size, blocksize / 1024);
+ printf(_("Resizing the filesystem on %s to %llu (%dk) blocks.\n"),
+ device_name, new_size, blocksize / 1024);
retval = resize_fs(fs, &new_size, flags,
((flags & RESIZE_PERCENT_COMPLETE) ?
resize_progress_func : 0));
diff --git a/resize/resize2fs.8.in b/resize/resize2fs.8.in
index d2738e9cdf42..d9176ec7c874 100644
--- a/resize/resize2fs.8.in
+++ b/resize/resize2fs.8.in
@@ -8,7 +8,7 @@ resize2fs \- ext2/ext3/ext4 file system resizer
.SH SYNOPSIS
.B resize2fs
[
-.B \-fFpPMbs
+.B \-fFpPM
]
[
.B \-d
@@ -90,20 +90,8 @@ to shrink the size of filesystem. Then you may use
to shrink the size of the partition. When shrinking the size of
the partition, make sure you do not make it smaller than the new size
of the ext2 filesystem!
-.PP
-The
-.B \-b
-and
-.B \-s
-options enable and disable the 64bit feature, respectively. The resize2fs
-program will, of course, take care of resizing the block group descriptors
-and moving other data blocks out of the way, as needed. It is not possible
-to resize the filesystem concurrent with changing the 64bit status.
.SH OPTIONS
.TP
-.B \-b
-Turns on the 64bit feature, resizes the group descriptors as necessary, and
-moves other metadata out of the way.
.TP
.B \-d \fIdebug-flags
Turns on various resize2fs debugging features, if they have been compiled
@@ -144,9 +132,6 @@ of what the program is doing.
.B \-P
Print the minimum size of the filesystem and exit.
.TP
-.B \-s
-Turns off the 64bit feature and frees blocks that are no longer in use.
-.TP
.B \-S \fIRAID-stride
The
.B resize2fs
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index ed69646984ad..3cff977b1d53 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -56,9 +56,6 @@ static errcode_t mark_table_blocks(ext2_filsys fs,
static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs);
static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
ext2fs_block_bitmap meta_bmap);
-static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size);
-static errcode_t move_bg_metadata(ext2_resize_t rfs);
-static errcode_t zero_high_bits_in_inodes(ext2_resize_t rfs);

/*
* Some helper CPP macros
@@ -125,24 +122,6 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
if (retval)
goto errout;

- init_resource_track(&rtrack, "resize_group_descriptors", fs->io);
- retval = resize_group_descriptors(rfs, *new_size);
- if (retval)
- goto errout;
- print_resource_track(rfs, &rtrack, fs->io);
-
- init_resource_track(&rtrack, "move_bg_metadata", fs->io);
- retval = move_bg_metadata(rfs);
- if (retval)
- goto errout;
- print_resource_track(rfs, &rtrack, fs->io);
-
- init_resource_track(&rtrack, "zero_high_bits_in_metadata", fs->io);
- retval = zero_high_bits_in_inodes(rfs);
- if (retval)
- goto errout;
- print_resource_track(rfs, &rtrack, fs->io);
-
init_resource_track(&rtrack, "adjust_superblock", fs->io);
retval = adjust_superblock(rfs, *new_size);
if (retval)
@@ -273,304 +252,6 @@ static void adjust_reserved_gdt_blocks(ext2_filsys old_fs, ext2_filsys fs)
}
}

-/* Toggle 64bit mode */
-static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size)
-{
- void *o, *n, *new_group_desc;
- dgrp_t i;
- int copy_size;
- errcode_t retval;
-
- if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)))
- return 0;
-
- if (new_size != ext2fs_blocks_count(rfs->new_fs->super) ||
- ext2fs_blocks_count(rfs->new_fs->super) >= (1ULL << 32) ||
- (rfs->flags & RESIZE_DISABLE_64BIT &&
- rfs->flags & RESIZE_ENABLE_64BIT))
- return EXT2_ET_INVALID_ARGUMENT;
-
- if (rfs->flags & RESIZE_DISABLE_64BIT) {
- rfs->new_fs->super->s_feature_incompat &=
- ~EXT4_FEATURE_INCOMPAT_64BIT;
- rfs->new_fs->super->s_desc_size = EXT2_MIN_DESC_SIZE;
- } else if (rfs->flags & RESIZE_ENABLE_64BIT) {
- rfs->new_fs->super->s_feature_incompat |=
- EXT4_FEATURE_INCOMPAT_64BIT;
- rfs->new_fs->super->s_desc_size = EXT2_MIN_DESC_SIZE_64BIT;
- }
-
- if (EXT2_DESC_SIZE(rfs->old_fs->super) ==
- EXT2_DESC_SIZE(rfs->new_fs->super))
- return 0;
-
- o = rfs->new_fs->group_desc;
- rfs->new_fs->desc_blocks = ext2fs_div_ceil(
- rfs->old_fs->group_desc_count,
- EXT2_DESC_PER_BLOCK(rfs->new_fs->super));
- retval = ext2fs_get_arrayzero(rfs->new_fs->desc_blocks,
- rfs->old_fs->blocksize, &new_group_desc);
- if (retval)
- return retval;
-
- n = new_group_desc;
-
- if (EXT2_DESC_SIZE(rfs->old_fs->super) <=
- EXT2_DESC_SIZE(rfs->new_fs->super))
- copy_size = EXT2_DESC_SIZE(rfs->old_fs->super);
- else
- copy_size = EXT2_DESC_SIZE(rfs->new_fs->super);
- for (i = 0; i < rfs->old_fs->group_desc_count; i++) {
- memcpy(n, o, copy_size);
- n += EXT2_DESC_SIZE(rfs->new_fs->super);
- o += EXT2_DESC_SIZE(rfs->old_fs->super);
- }
-
- ext2fs_free_mem(&rfs->new_fs->group_desc);
- rfs->new_fs->group_desc = new_group_desc;
-
- for (i = 0; i < rfs->old_fs->group_desc_count; i++)
- ext2fs_group_desc_csum_set(rfs->new_fs, i);
-
- adjust_reserved_gdt_blocks(rfs->old_fs, rfs->new_fs);
-
- return 0;
-}
-
-/* Move bitmaps/inode tables out of the way. */
-static errcode_t move_bg_metadata(ext2_resize_t rfs)
-{
- dgrp_t i;
- blk64_t b, c, d, old_desc_blocks, new_desc_blocks, j;
- ext2fs_block_bitmap old_map, new_map;
- int old, new;
- errcode_t retval;
- int cluster_ratio;
-
- if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)))
- return 0;
-
- retval = ext2fs_allocate_block_bitmap(rfs->old_fs, "oldfs", &old_map);
- if (retval)
- return retval;
-
- retval = ext2fs_allocate_block_bitmap(rfs->new_fs, "newfs", &new_map);
- if (retval)
- goto out;
-
- if (EXT2_HAS_INCOMPAT_FEATURE(rfs->old_fs->super,
- EXT2_FEATURE_INCOMPAT_META_BG)) {
- old_desc_blocks = rfs->old_fs->super->s_first_meta_bg;
- new_desc_blocks = rfs->new_fs->super->s_first_meta_bg;
- } else {
- old_desc_blocks = rfs->old_fs->desc_blocks +
- rfs->old_fs->super->s_reserved_gdt_blocks;
- new_desc_blocks = rfs->new_fs->desc_blocks +
- rfs->new_fs->super->s_reserved_gdt_blocks;
- }
-
- /* Construct bitmaps of super/descriptor blocks in old and new fs */
- for (i = 0; i < rfs->old_fs->group_desc_count; i++) {
- retval = ext2fs_super_and_bgd_loc2(rfs->old_fs, i, &b, &c, &d,
- NULL);
- if (retval)
- goto out;
- if (b)
- ext2fs_mark_block_bitmap2(old_map, b);
- for (j = 0; c != 0 && j < old_desc_blocks; j++)
- ext2fs_mark_block_bitmap2(old_map, c + j);
- if (d)
- ext2fs_mark_block_bitmap2(old_map, d);
-
- retval = ext2fs_super_and_bgd_loc2(rfs->new_fs, i, &b, &c, &d,
- NULL);
- if (retval)
- goto out;
- if (b)
- ext2fs_mark_block_bitmap2(new_map, b);
- for (j = 0; c != 0 && j < new_desc_blocks; j++)
- ext2fs_mark_block_bitmap2(new_map, c + j);
- if (d)
- ext2fs_mark_block_bitmap2(new_map, d);
- }
-
- cluster_ratio = EXT2FS_CLUSTER_RATIO(rfs->new_fs);
-
- /* Find changes in block allocations for bg metadata */
- for (b = EXT2FS_B2C(rfs->old_fs,
- rfs->old_fs->super->s_first_data_block);
- b < ext2fs_blocks_count(rfs->new_fs->super);
- b += cluster_ratio) {
- old = ext2fs_test_block_bitmap2(old_map, b);
- new = ext2fs_test_block_bitmap2(new_map, b);
-
- if (old && !new) {
- /* mark old_map, unmark new_map */
- if (cluster_ratio == 1)
- ext2fs_unmark_block_bitmap2(
- rfs->new_fs->block_map, b);
- } else if (!old && new)
- ; /* unmark old_map, mark new_map */
- else {
- ext2fs_unmark_block_bitmap2(old_map, b);
- ext2fs_unmark_block_bitmap2(new_map, b);
- }
- }
-
- /*
- * new_map now shows blocks that have been newly allocated.
- * old_map now shows blocks that have been newly freed.
- */
-
- /*
- * Move any conflicting bitmaps and inode tables. Ensure that we
- * don't try to free clusters associated with bitmaps or tables.
- */
- for (i = 0; i < rfs->old_fs->group_desc_count; i++) {
- b = ext2fs_block_bitmap_loc(rfs->new_fs, i);
- if (ext2fs_test_block_bitmap2(new_map, b))
- ext2fs_block_bitmap_loc_set(rfs->new_fs, i, 0);
- else if (ext2fs_test_block_bitmap2(old_map, b))
- ext2fs_unmark_block_bitmap2(old_map, b);
-
- b = ext2fs_inode_bitmap_loc(rfs->new_fs, i);
- if (ext2fs_test_block_bitmap2(new_map, b))
- ext2fs_inode_bitmap_loc_set(rfs->new_fs, i, 0);
- else if (ext2fs_test_block_bitmap2(old_map, b))
- ext2fs_unmark_block_bitmap2(old_map, b);
-
- c = ext2fs_inode_table_loc(rfs->new_fs, i);
- for (b = 0;
- b < rfs->new_fs->inode_blocks_per_group;
- b++) {
- if (ext2fs_test_block_bitmap2(new_map, b + c))
- ext2fs_inode_table_loc_set(rfs->new_fs, i, 0);
- else if (ext2fs_test_block_bitmap2(old_map, b + c))
- ext2fs_unmark_block_bitmap2(old_map, b + c);
- }
- }
-
- /* Free unused clusters */
- for (b = 0;
- cluster_ratio > 1 && b < ext2fs_blocks_count(rfs->new_fs->super);
- b += cluster_ratio)
- if (ext2fs_test_block_bitmap2(old_map, b))
- ext2fs_unmark_block_bitmap2(rfs->new_fs->block_map, b);
-out:
- if (old_map)
- ext2fs_free_block_bitmap(old_map);
- if (new_map)
- ext2fs_free_block_bitmap(new_map);
- return retval;
-}
-
-/* Zero out the high bits of extent fields */
-static errcode_t zero_high_bits_in_extents(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode)
-{
- ext2_extent_handle_t handle;
- struct ext2fs_extent extent;
- int op = EXT2_EXTENT_ROOT;
- errcode_t errcode;
-
- if (!(inode->i_flags & EXT4_EXTENTS_FL))
- return 0;
-
- errcode = ext2fs_extent_open(fs, ino, &handle);
- if (errcode)
- return errcode;
-
- while (1) {
- errcode = ext2fs_extent_get(handle, op, &extent);
- if (errcode)
- break;
-
- op = EXT2_EXTENT_NEXT_SIB;
-
- if (extent.e_pblk > (1ULL << 32)) {
- extent.e_pblk &= (1ULL << 32) - 1;
- errcode = ext2fs_extent_replace(handle, 0, &extent);
- if (errcode)
- break;
- }
- }
-
- /* Ok if we run off the end */
- if (errcode == EXT2_ET_EXTENT_NO_NEXT)
- errcode = 0;
- ext2fs_extent_free(handle);
- return errcode;
-}
-
-/* Zero out the high bits of inodes. */
-static errcode_t zero_high_bits_in_inodes(ext2_resize_t rfs)
-{
- ext2_filsys fs = rfs->old_fs;
- int length = EXT2_INODE_SIZE(fs->super);
- struct ext2_inode *inode = NULL;
- ext2_inode_scan scan = NULL;
- errcode_t retval;
- ext2_ino_t ino;
-
- if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)))
- return 0;
-
- if (fs->super->s_creator_os != EXT2_OS_LINUX)
- return 0;
-
- retval = ext2fs_open_inode_scan(fs, 0, &scan);
- if (retval)
- return retval;
-
- retval = ext2fs_get_mem(length, &inode);
- if (retval)
- goto out;
-
- do {
- retval = ext2fs_get_next_inode_full(scan, &ino, inode, length);
- if (retval)
- goto out;
- if (!ino)
- break;
- if (!ext2fs_test_inode_bitmap2(fs->inode_map, ino))
- continue;
-
- /*
- * Here's how we deal with high block number fields:
- *
- * - i_size_high has been been written out with i_size_lo
- * since the ext2 days, so no conversion is needed.
- *
- * - i_blocks_hi is guarded by both the huge_file feature and
- * inode flags and has always been written out with
- * i_blocks_lo if the feature is set. The field is only
- * ever read if both feature and inode flag are set, so
- * we don't need to zero it now.
- *
- * - i_file_acl_high can be uninitialized, so zero it if
- * it isn't already.
- */
- if (inode->osd2.linux2.l_i_file_acl_high) {
- inode->osd2.linux2.l_i_file_acl_high = 0;
- retval = ext2fs_write_inode_full(fs, ino, inode,
- length);
- if (retval)
- goto out;
- }
-
- retval = zero_high_bits_in_extents(fs, ino, inode);
- if (retval)
- goto out;
- } while (ino);
-
-out:
- if (inode)
- ext2fs_free_mem(&inode);
- if (scan)
- ext2fs_close_inode_scan(scan);
- return retval;
-}
-
/*
* Clean up the bitmaps for unitialized bitmaps
*/
@@ -794,8 +475,7 @@ retry:
/*
* Reallocate the group descriptors as necessary.
*/
- if (EXT2_DESC_SIZE(old_fs->super) == EXT2_DESC_SIZE(fs->super) &&
- old_fs->desc_blocks != fs->desc_blocks) {
+ if (old_fs->desc_blocks != fs->desc_blocks) {
retval = ext2fs_resize_mem(old_fs->desc_blocks *
fs->blocksize,
fs->desc_blocks * fs->blocksize,
@@ -814,11 +494,8 @@ retry:
* number of descriptor blocks, then adjust
* s_reserved_gdt_blocks if possible to avoid needing to move
* the inode table either now or in the future.
- *
- * Note: If we're converting to 64bit mode, we did this earlier.
*/
- if (EXT2_DESC_SIZE(old_fs->super) == EXT2_DESC_SIZE(fs->super))
- adjust_reserved_gdt_blocks(old_fs, fs);
+ adjust_reserved_gdt_blocks(old_fs, fs);

if ((fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) &&
(fs->super->s_first_meta_bg > fs->desc_blocks)) {
@@ -1347,9 +1024,7 @@ static errcode_t blocks_to_move(ext2_resize_t rfs)
if (retval)
goto errout;

- if (EXT2_DESC_SIZE(rfs->old_fs->super) ==
- EXT2_DESC_SIZE(rfs->new_fs->super) &&
- old_blocks == new_blocks) {
+ if (old_blocks == new_blocks) {
retval = 0;
goto errout;
}
--
2.1.4


2015-08-26 16:22:56

by Jan Kara

[permalink] [raw]
Subject: [PATCH 08/21] tests: Convert tests for 64bit feature to use tune2fs

Convert tests which test various functionality regarding 64bit feature
to use tune2fs to enable / disable it. We also update the expected
outputs since location of some group metadata is different.

Signed-off-by: Jan Kara <[email protected]>
---
tests/r_32to64bit/expect | 94 -------------------
tests/r_32to64bit/name | 1 -
tests/r_32to64bit/script | 74 ---------------
tests/r_32to64bit_expand_full/expect | 139 ----------------------------
tests/r_32to64bit_expand_full/name | 1 -
tests/r_32to64bit_expand_full/script | 83 -----------------
tests/r_32to64bit_meta/expect | 80 ----------------
tests/r_32to64bit_meta/name | 1 -
tests/r_32to64bit_meta/script | 74 ---------------
tests/r_32to64bit_move_itable/expect | 107 ---------------------
tests/r_32to64bit_move_itable/name | 1 -
tests/r_32to64bit_move_itable/script | 74 ---------------
tests/r_64to32bit/expect | 98 --------------------
tests/r_64to32bit/name | 1 -
tests/r_64to32bit/script | 76 ---------------
tests/r_64to32bit_meta/expect | 80 ----------------
tests/r_64to32bit_meta/name | 1 -
tests/r_64to32bit_meta/script | 76 ---------------
tests/t_32to64bit/expect | 91 ++++++++++++++++++
tests/t_32to64bit/name | 1 +
tests/t_32to64bit/script | 74 +++++++++++++++
tests/t_32to64bit_expand_full/expect | 136 +++++++++++++++++++++++++++
tests/t_32to64bit_expand_full/name | 1 +
tests/t_32to64bit_expand_full/script | 83 +++++++++++++++++
tests/t_32to64bit_meta/expect | 77 +++++++++++++++
tests/t_32to64bit_meta/name | 1 +
tests/t_32to64bit_meta/script | 74 +++++++++++++++
tests/t_32to64bit_move_itable/expect | 104 +++++++++++++++++++++
tests/t_32to64bit_move_itable/name | 1 +
tests/t_32to64bit_move_itable/script | 74 +++++++++++++++
tests/t_64to32bit/expect | 95 +++++++++++++++++++
tests/t_64to32bit/name | 1 +
tests/t_64to32bit/script | 76 +++++++++++++++
tests/t_64to32bit_meta/expect | 80 ++++++++++++++++
tests/t_64to32bit_meta/name | 1 +
tests/t_64to32bit_meta/script | 76 +++++++++++++++
tests/u_onefile_bad/script | 10 +-
tests/u_revert_64bitmcsum_onefile/script | 10 +-
tests/u_revert_all_onefile/script | 10 +-
tests/u_revert_upgrade_to_64bitmcsum/script | 14 +--
40 files changed, 1068 insertions(+), 1083 deletions(-)
delete mode 100644 tests/r_32to64bit/expect
delete mode 100644 tests/r_32to64bit/name
delete mode 100644 tests/r_32to64bit/script
delete mode 100644 tests/r_32to64bit_expand_full/expect
delete mode 100644 tests/r_32to64bit_expand_full/name
delete mode 100644 tests/r_32to64bit_expand_full/script
delete mode 100644 tests/r_32to64bit_meta/expect
delete mode 100644 tests/r_32to64bit_meta/name
delete mode 100644 tests/r_32to64bit_meta/script
delete mode 100644 tests/r_32to64bit_move_itable/expect
delete mode 100644 tests/r_32to64bit_move_itable/name
delete mode 100644 tests/r_32to64bit_move_itable/script
delete mode 100644 tests/r_64to32bit/expect
delete mode 100644 tests/r_64to32bit/name
delete mode 100644 tests/r_64to32bit/script
delete mode 100644 tests/r_64to32bit_meta/expect
delete mode 100644 tests/r_64to32bit_meta/name
delete mode 100644 tests/r_64to32bit_meta/script
create mode 100644 tests/t_32to64bit/expect
create mode 100644 tests/t_32to64bit/name
create mode 100644 tests/t_32to64bit/script
create mode 100644 tests/t_32to64bit_expand_full/expect
create mode 100644 tests/t_32to64bit_expand_full/name
create mode 100644 tests/t_32to64bit_expand_full/script
create mode 100644 tests/t_32to64bit_meta/expect
create mode 100644 tests/t_32to64bit_meta/name
create mode 100644 tests/t_32to64bit_meta/script
create mode 100644 tests/t_32to64bit_move_itable/expect
create mode 100644 tests/t_32to64bit_move_itable/name
create mode 100644 tests/t_32to64bit_move_itable/script
create mode 100644 tests/t_64to32bit/expect
create mode 100644 tests/t_64to32bit/name
create mode 100644 tests/t_64to32bit/script
create mode 100644 tests/t_64to32bit_meta/expect
create mode 100644 tests/t_64to32bit_meta/name
create mode 100644 tests/t_64to32bit_meta/script

diff --git a/tests/r_32to64bit/expect b/tests/r_32to64bit/expect
deleted file mode 100644
index f5fa56bc39f7..000000000000
--- a/tests/r_32to64bit/expect
+++ /dev/null
@@ -1,94 +0,0 @@
-resize2fs test
-Creating filesystem with 524288 1k blocks and 65536 inodes
-Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
-
-Allocating group tables: done
-Writing inode tables: done
-Creating journal (16384 blocks): done
-Creating 477 huge file(s) with 1024 blocks each: done
-Writing superblocks and filesystem accounting information: done
-
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
-resize2fs test.img -b
-Converting the filesystem to 64-bit.
-The filesystem on test.img is now 524288 (1k) blocks long.
-
-Exit status is 0
-Change in FS metadata:
-@@ -2,7 +2,7 @@
- Last mounted on: <not available>
- Filesystem magic number: 0xEF53
- Filesystem revision #: 1 (dynamic)
--Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
-+Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
- Default mount options: user_xattr acl
- Filesystem state: clean
- Errors behavior: Continue
-@@ -15,7 +15,8 @@
- First block: 1
- Block size: 1024
- Fragment size: 1024
--Reserved GDT blocks: 256
-+Group descriptor size: 64
-+Reserved GDT blocks: 254
- Blocks per group: 8192
- Fragments per group: 8192
- Inodes per group: 1024
-@@ -40,16 +41,16 @@
-
-
- group:block:super:gdt:bbitmap:ibitmap:itable
--0:1:1:2-3:260:276:292
--1:8193:8193:8194-8195:261:277:548
-+0:1:1:2-5:260:276:292
-+1:8193:8193:8194-8197:261:277:548
- 2:16385:-1:-1:262:278:804
--3:24577:24577:24578-24579:263:279:1060
-+3:24577:24577:24578-24581:263:279:1060
- 4:32769:-1:-1:264:280:1316
--5:40961:40961:40962-40963:265:281:1572
-+5:40961:40961:40962-40965:265:281:1572
- 6:49153:-1:-1:266:282:1828
--7:57345:57345:57346-57347:267:283:2084
-+7:57345:57345:57346-57349:267:283:2084
- 8:65537:-1:-1:268:284:2340
--9:73729:73729:73730-73731:269:285:2596
-+9:73729:73729:73730-73733:269:285:2596
- 10:81921:-1:-1:270:286:2852
- 11:90113:-1:-1:271:287:3108
- 12:98305:-1:-1:272:288:3364
-@@ -65,9 +66,9 @@
- 22:180225:-1:-1:131079:131095:132641
- 23:188417:-1:-1:131080:131096:132897
- 24:196609:-1:-1:131081:131097:133153
--25:204801:204801:204802-204803:131082:131098:133409
-+25:204801:204801:204802-204805:131082:131098:133409
- 26:212993:-1:-1:131083:131099:133665
--27:221185:221185:221186-221187:131084:131100:133921
-+27:221185:221185:221186-221189:131084:131100:133921
- 28:229377:-1:-1:131085:131101:134177
- 29:237569:-1:-1:131086:131102:134433
- 30:245761:-1:-1:131087:131103:134689
-@@ -89,7 +90,7 @@
- 46:376833:-1:-1:262159:262175:265761
- 47:385025:-1:-1:262160:262176:266017
- 48:393217:-1:-1:393217:393233:393249
--49:401409:401409:401410-401411:393218:393234:393505
-+49:401409:401409:401410-401413:393218:393234:393505
- 50:409601:-1:-1:393219:393235:393761
- 51:417793:-1:-1:393220:393236:394017
- 52:425985:-1:-1:393221:393237:394273
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
diff --git a/tests/r_32to64bit/name b/tests/r_32to64bit/name
deleted file mode 100644
index fb45faba6468..000000000000
--- a/tests/r_32to64bit/name
+++ /dev/null
@@ -1 +0,0 @@
-convert flex_bg 32bit fs to 64bit fs
diff --git a/tests/r_32to64bit/script b/tests/r_32to64bit/script
deleted file mode 100644
index de08bfb6422a..000000000000
--- a/tests/r_32to64bit/script
+++ /dev/null
@@ -1,74 +0,0 @@
-if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
-
-FSCK_OPT=-fn
-OUT=$test_name.log
-EXP=$test_dir/expect
-CONF=$TMPFILE.conf
-
-cat > $CONF << ENDL
-[fs_types]
- ext4h = {
- features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,resize_inode
- blocksize = 1024
- inode_size = 256
- make_hugefiles = true
- hugefiles_dir = /
- hugefiles_slack = 0
- hugefiles_name = aaaaa
- hugefiles_digits = 4
- hugefiles_size = 1M
- zero_hugefiles = false
- }
-ENDL
-
-echo "resize2fs test" > $OUT
-
-MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
-rm -rf $CONF
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# resize it
-echo "resize2fs test.img -b" >> $OUT
-$RESIZE2FS -b -f $TMPFILE 2>&1 >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
-echo "Change in FS metadata:" >> $OUT
-diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-rm $TMPFILE $OUT.before $OUT.after
-
-#
-# Do the verification
-#
-
-sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
-mv $OUT.new $OUT
-
-cmp -s $OUT $EXP
-status=$?
-
-if [ "$status" = 0 ] ; then
- echo "$test_name: $test_description: ok"
- touch $test_name.ok
-else
- echo "$test_name: $test_description: failed"
- diff $DIFF_OPTS $EXP $OUT > $test_name.failed
-fi
-
-unset IMAGE FSCK_OPT OUT EXP CONF
-
-else #if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
- echo "$test_name: $test_description: skipped"
-fi
-
diff --git a/tests/r_32to64bit_expand_full/expect b/tests/r_32to64bit_expand_full/expect
deleted file mode 100644
index f9e30f34b8e7..000000000000
--- a/tests/r_32to64bit_expand_full/expect
+++ /dev/null
@@ -1,139 +0,0 @@
-resize2fs test
-Creating filesystem with 786432 1k blocks and 98304 inodes
-Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553
-
-Allocating group tables: done
-Writing inode tables: done
-Creating journal (16384 blocks): done
-Creating 727 huge file(s) with 1024 blocks each: done
-Writing superblocks and filesystem accounting information: done
-
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
-resize2fs -b test.img
-Converting the filesystem to 64-bit.
-The filesystem on test.img is now 786432 (1k) blocks long.
-
-resize2fs test.img
-Resizing the filesystem on test.img to 1179648 (1k) blocks.
-The filesystem on test.img is now 1179648 (1k) blocks long.
-
-Exit status is 0
-Change in FS metadata:
-@@ -1,15 +1,15 @@
-
- group:block:super:gdt:bbitmap:ibitmap:itable
--0:1:1:2-7:8:9:10
--1:8193:8193:8194-8199:8200:8201:8202
-+0:1:1:2-10:266:267:268
-+1:8193:8193:8194-8202:8458:8459:8460
- 2:16385:-1:-1:16385:16386:16387
--3:24577:24577:24578-24583:24584:24585:24586
-+3:24577:24577:24578-24586:24842:24843:24844
- 4:32769:-1:-1:32769:32770:32771
--5:40961:40961:40962-40967:40968:40969:40970
-+5:40961:40961:40962-40970:41226:41227:41228
- 6:49153:-1:-1:49153:49154:49155
--7:57345:57345:57346-57351:57352:57353:57354
-+7:57345:57345:57346-57354:57610:57611:57612
- 8:65537:-1:-1:65537:65538:65539
--9:73729:73729:73730-73735:73736:73737:73738
-+9:73729:73729:73730-73738:73994:73995:73996
- 10:81921:-1:-1:81921:81922:81923
- 11:90113:-1:-1:90113:90114:90115
- 12:98305:-1:-1:98305:98306:98307
-@@ -25,9 +25,9 @@
- 22:180225:-1:-1:180225:180226:180227
- 23:188417:-1:-1:188417:188418:188419
- 24:196609:-1:-1:196609:196610:196611
--25:204801:204801:204802-204807:204808:204809:204810
-+25:204801:204801:204802-204810:205066:205067:205068
- 26:212993:-1:-1:212993:212994:212995
--27:221185:221185:221186-221191:221192:221193:221194
-+27:221185:221185:221186-221194:221450:221451:221452
- 28:229377:-1:-1:229377:229378:229379
- 29:237569:-1:-1:237569:237570:237571
- 30:245761:-1:-1:245761:245762:245763
-@@ -49,7 +49,7 @@
- 46:376833:-1:-1:376833:376834:376835
- 47:385025:-1:-1:385025:385026:385027
- 48:393217:-1:-1:393217:393218:393219
--49:401409:401409:401410-401415:401416:401417:401418
-+49:401409:401409:401410-401418:401674:401675:401676
- 50:409601:-1:-1:409601:409602:409603
- 51:417793:-1:-1:417793:417794:417795
- 52:425985:-1:-1:425985:425986:425987
-@@ -81,7 +81,7 @@
- 78:638977:-1:-1:638977:638978:638979
- 79:647169:-1:-1:647169:647170:647171
- 80:655361:-1:-1:655361:655362:655363
--81:663553:663553:663554-663559:663560:663561:663562
-+81:663553:663553:663554-663562:663818:663819:663820
- 82:671745:-1:-1:671745:671746:671747
- 83:679937:-1:-1:679937:679938:679939
- 84:688129:-1:-1:688129:688130:688131
-@@ -96,3 +96,51 @@
- 93:761857:-1:-1:761857:761858:761859
- 94:770049:-1:-1:770049:770050:770051
- 95:778241:-1:-1:778241:778242:778243
-+96:786433:-1:-1:786433:786434:786435
-+97:794625:-1:-1:794625:794626:794627
-+98:802817:-1:-1:802817:802818:802819
-+99:811009:-1:-1:811009:811010:811011
-+100:819201:-1:-1:819201:819202:819203
-+101:827393:-1:-1:827393:827394:827395
-+102:835585:-1:-1:835585:835586:835587
-+103:843777:-1:-1:843777:843778:843779
-+104:851969:-1:-1:851969:851970:851971
-+105:860161:-1:-1:860161:860162:860163
-+106:868353:-1:-1:868353:868354:868355
-+107:876545:-1:-1:876545:876546:876547
-+108:884737:-1:-1:884737:884738:884739
-+109:892929:-1:-1:892929:892930:892931
-+110:901121:-1:-1:901121:901122:901123
-+111:909313:-1:-1:909313:909314:909315
-+112:917505:-1:-1:917505:917506:917507
-+113:925697:-1:-1:925697:925698:925699
-+114:933889:-1:-1:933889:933890:933891
-+115:942081:-1:-1:942081:942082:942083
-+116:950273:-1:-1:950273:950274:950275
-+117:958465:-1:-1:958465:958466:958467
-+118:966657:-1:-1:966657:966658:966659
-+119:974849:-1:-1:974849:974850:974851
-+120:983041:-1:-1:983041:983042:983043
-+121:991233:-1:-1:991233:991234:991235
-+122:999425:-1:-1:999425:999426:999427
-+123:1007617:-1:-1:1007617:1007618:1007619
-+124:1015809:-1:-1:1015809:1015810:1015811
-+125:1024001:1024001:1024002-1024010:1024011:1024012:1024013
-+126:1032193:-1:-1:1032193:1032194:1032195
-+127:1040385:-1:-1:1040385:1040386:1040387
-+128:1048577:-1:-1:1048577:1048578:1048579
-+129:1056769:-1:-1:1056769:1056770:1056771
-+130:1064961:-1:-1:1064961:1064962:1064963
-+131:1073153:-1:-1:1073153:1073154:1073155
-+132:1081345:-1:-1:1081345:1081346:1081347
-+133:1089537:-1:-1:1089537:1089538:1089539
-+134:1097729:-1:-1:1097729:1097730:1097731
-+135:1105921:-1:-1:1105921:1105922:1105923
-+136:1114113:-1:-1:1114113:1114114:1114115
-+137:1122305:-1:-1:1122305:1122306:1122307
-+138:1130497:-1:-1:1130497:1130498:1130499
-+139:1138689:-1:-1:1138689:1138690:1138691
-+140:1146881:-1:-1:1146881:1146882:1146883
-+141:1155073:-1:-1:1155073:1155074:1155075
-+142:1163265:-1:-1:1163265:1163266:1163267
-+143:1171457:-1:-1:1171457:1171458:1171459
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
diff --git a/tests/r_32to64bit_expand_full/name b/tests/r_32to64bit_expand_full/name
deleted file mode 100644
index 2f046011bcf8..000000000000
--- a/tests/r_32to64bit_expand_full/name
+++ /dev/null
@@ -1 +0,0 @@
-convert a totally full filesystem to 64bit, then expand
diff --git a/tests/r_32to64bit_expand_full/script b/tests/r_32to64bit_expand_full/script
deleted file mode 100644
index 7a570841a350..000000000000
--- a/tests/r_32to64bit_expand_full/script
+++ /dev/null
@@ -1,83 +0,0 @@
-if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
-
-FSCK_OPT=-fn
-OUT=$test_name.log
-EXP=$test_dir/expect
-CONF=$TMPFILE.conf
-
-#gzip -d < $EXP.gz > $EXP
-
-cat > $CONF << ENDL
-[fs_types]
- ext4h = {
- features = has_journal,extent,huge_file,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,^resize_inode,^meta_bg,^flex_bg
- blocksize = 1024
- inode_size = 256
- make_hugefiles = true
- hugefiles_dir = /
- hugefiles_slack = 0
- hugefiles_name = aaaaa
- hugefiles_digits = 4
- hugefiles_size = 1M
- zero_hugefiles = false
- }
-ENDL
-
-echo "resize2fs test" > $OUT
-
-MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 786432 >> $OUT 2>&1
-rm -rf $CONF
-
-# check
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# convert it
-echo "resize2fs -b test.img" >> $OUT
-$RESIZE2FS -b -f $TMPFILE 2>&1 >> $OUT 2>&1
-$DUMPE2FS -g $TMPFILE 2>&1 >> $OUT.before 2> /dev/null
-
-# grow it
-echo "resize2fs test.img" >> $OUT
-dd if=/dev/zero of=$TMPFILE conv=notrunc bs=1 count=1 seek=1207959552 2> /dev/null
-$RESIZE2FS -f $TMPFILE 2>&1 >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# dump and check
-$DUMPE2FS -g $TMPFILE 2>&1 >> $OUT.after 2> /dev/null
-echo "Change in FS metadata:" >> $OUT
-diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-rm $TMPFILE
-
-#
-# Do the verification
-#
-
-sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
-mv $OUT.new $OUT
-
-cmp -s $OUT $EXP
-status=$?
-
-if [ "$status" = 0 ] ; then
- echo "$test_name: $test_description: ok"
- touch $test_name.ok
-else
- echo "$test_name: $test_description: failed"
- diff $DIFF_OPTS $EXP $OUT > $test_name.failed
-fi
-
-rm $OUT.before $OUT.after
-
-unset IMAGE FSCK_OPT OUT EXP CONF
-
-else #if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
- echo "$test_name: $test_description: skipped"
-fi
-
diff --git a/tests/r_32to64bit_meta/expect b/tests/r_32to64bit_meta/expect
deleted file mode 100644
index 0eacd45037e4..000000000000
--- a/tests/r_32to64bit_meta/expect
+++ /dev/null
@@ -1,80 +0,0 @@
-resize2fs test
-Creating filesystem with 524288 1k blocks and 65536 inodes
-Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
-
-Allocating group tables: done
-Writing inode tables: done
-Creating journal (16384 blocks): done
-Creating 479 huge file(s) with 1024 blocks each: done
-Writing superblocks and filesystem accounting information: done
-
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
-resize2fs test.img -b
-Converting the filesystem to 64-bit.
-The filesystem on test.img is now 524288 (1k) blocks long.
-
-Exit status is 0
-Change in FS metadata:
-@@ -2,7 +2,7 @@
- Last mounted on: <not available>
- Filesystem magic number: 0xEF53
- Filesystem revision #: 1 (dynamic)
--Filesystem features: has_journal ext_attr dir_index filetype meta_bg extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
-+Filesystem features: has_journal ext_attr dir_index filetype meta_bg extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
- Default mount options: user_xattr acl
- Filesystem state: clean
- Errors behavior: Continue
-@@ -10,11 +10,12 @@
- Inode count: 65536
- Block count: 524288
- Reserved block count: 26214
--Free blocks: 858
-+Free blocks: 852
- Free inodes: 65046
- First block: 1
- Block size: 1024
- Fragment size: 1024
-+Group descriptor size: 64
- Blocks per group: 8192
- Fragments per group: 8192
- Inodes per group: 1024
-@@ -54,9 +55,9 @@
- 12:98305:-1:-1:15:31:3107
- 13:106497:-1:-1:16:32:3363
- 14:114689:-1:-1:17:33:3619
--15:122881:-1:-1:18:34:3875
--16:131073:-1:-1:131073:131089:131105
--17:139265:-1:-1:131074:131090:131361
-+15:122881:-1:122881:18:34:3875
-+16:131073:-1:131073:135201:131089:131105
-+17:139265:-1:139265:131074:131090:131361
- 18:147457:-1:-1:131075:131091:131617
- 19:155649:-1:-1:131076:131092:131873
- 20:163841:-1:-1:131077:131093:132129
-@@ -86,9 +87,9 @@
- 44:360449:-1:-1:262158:262174:265250
- 45:368641:-1:-1:262159:262175:265506
- 46:376833:-1:-1:262160:262176:265762
--47:385025:-1:-1:262161:262177:266018
--48:393217:-1:-1:393217:393233:393249
--49:401409:401409:-1:393218:393234:393505
-+47:385025:-1:385025:262161:262177:266018
-+48:393217:-1:393217:397345:393233:393249
-+49:401409:401409:401410:393218:393234:393505
- 50:409601:-1:-1:393219:393235:393761
- 51:417793:-1:-1:393220:393236:394017
- 52:425985:-1:-1:393221:393237:394273
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
diff --git a/tests/r_32to64bit_meta/name b/tests/r_32to64bit_meta/name
deleted file mode 100644
index d83492eae8cf..000000000000
--- a/tests/r_32to64bit_meta/name
+++ /dev/null
@@ -1 +0,0 @@
-convert meta_bg 32bit fs to 64bit fs
diff --git a/tests/r_32to64bit_meta/script b/tests/r_32to64bit_meta/script
deleted file mode 100644
index 25872c4d4c45..000000000000
--- a/tests/r_32to64bit_meta/script
+++ /dev/null
@@ -1,74 +0,0 @@
-if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
-
-FSCK_OPT=-fn
-OUT=$test_name.log
-EXP=$test_dir/expect
-CONF=$TMPFILE.conf
-
-cat > $CONF << ENDL
-[fs_types]
- ext4h = {
- features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,meta_bg,^resize_inode
- blocksize = 1024
- inode_size = 256
- make_hugefiles = true
- hugefiles_dir = /
- hugefiles_slack = 0
- hugefiles_name = aaaaa
- hugefiles_digits = 4
- hugefiles_size = 1M
- zero_hugefiles = false
- }
-ENDL
-
-echo "resize2fs test" > $OUT
-
-MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
-rm -rf $CONF
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# resize it
-echo "resize2fs test.img -b" >> $OUT
-$RESIZE2FS -b -f $TMPFILE 2>&1 >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
-echo "Change in FS metadata:" >> $OUT
-diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-rm $TMPFILE $OUT.before $OUT.after
-
-#
-# Do the verification
-#
-
-sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
-mv $OUT.new $OUT
-
-cmp -s $OUT $EXP
-status=$?
-
-if [ "$status" = 0 ] ; then
- echo "$test_name: $test_description: ok"
- touch $test_name.ok
-else
- echo "$test_name: $test_description: failed"
- diff $DIFF_OPTS $EXP $OUT > $test_name.failed
-fi
-
-unset IMAGE FSCK_OPT OUT EXP CONF
-
-else #if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
- echo "$test_name: $test_description: skipped"
-fi
-
diff --git a/tests/r_32to64bit_move_itable/expect b/tests/r_32to64bit_move_itable/expect
deleted file mode 100644
index b51663d5f86d..000000000000
--- a/tests/r_32to64bit_move_itable/expect
+++ /dev/null
@@ -1,107 +0,0 @@
-resize2fs test
-Creating filesystem with 786432 1k blocks and 98304 inodes
-Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553
-
-Allocating group tables: done
-Writing inode tables: done
-Creating journal (16384 blocks): done
-Creating 727 huge file(s) with 1024 blocks each: done
-Writing superblocks and filesystem accounting information: done
-
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
-resize2fs test.img -b
-Converting the filesystem to 64-bit.
-The filesystem on test.img is now 786432 (1k) blocks long.
-
-Exit status is 0
-Change in FS metadata:
-@@ -2,7 +2,7 @@
- Last mounted on: <not available>
- Filesystem magic number: 0xEF53
- Filesystem revision #: 1 (dynamic)
--Filesystem features: has_journal ext_attr dir_index filetype extent sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
-+Filesystem features: has_journal ext_attr dir_index filetype extent 64bit sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
- Default mount options: user_xattr acl
- Filesystem state: clean
- Errors behavior: Continue
-@@ -10,11 +10,12 @@
- Inode count: 98304
- Block count: 786432
- Reserved block count: 39321
--Free blocks: 764
-+Free blocks: 734
- Free inodes: 97566
- First block: 1
- Block size: 1024
- Fragment size: 1024
-+Group descriptor size: 64
- Blocks per group: 8192
- Fragments per group: 8192
- Inodes per group: 1024
-@@ -38,16 +39,16 @@
-
-
- group:block:super:gdt:bbitmap:ibitmap:itable
--0:1:1:2-4:5:6:7
--1:8193:8193:8194-8196:8197:8198:8199
-+0:1:1:2-7:8:9:10
-+1:8193:8193:8194-8199:8200:8201:8202
- 2:16385:-1:-1:16385:16386:16387
--3:24577:24577:24578-24580:24581:24582:24583
-+3:24577:24577:24578-24583:24584:24585:24586
- 4:32769:-1:-1:32769:32770:32771
--5:40961:40961:40962-40964:40965:40966:40967
-+5:40961:40961:40962-40967:40968:40969:40970
- 6:49153:-1:-1:49153:49154:49155
--7:57345:57345:57346-57348:57349:57350:57351
-+7:57345:57345:57346-57351:57352:57353:57354
- 8:65537:-1:-1:65537:65538:65539
--9:73729:73729:73730-73732:73733:73734:73735
-+9:73729:73729:73730-73735:73736:73737:73738
- 10:81921:-1:-1:81921:81922:81923
- 11:90113:-1:-1:90113:90114:90115
- 12:98305:-1:-1:98305:98306:98307
-@@ -63,9 +64,9 @@
- 22:180225:-1:-1:180225:180226:180227
- 23:188417:-1:-1:188417:188418:188419
- 24:196609:-1:-1:196609:196610:196611
--25:204801:204801:204802-204804:204805:204806:204807
-+25:204801:204801:204802-204807:204808:204809:204810
- 26:212993:-1:-1:212993:212994:212995
--27:221185:221185:221186-221188:221189:221190:221191
-+27:221185:221185:221186-221191:221192:221193:221194
- 28:229377:-1:-1:229377:229378:229379
- 29:237569:-1:-1:237569:237570:237571
- 30:245761:-1:-1:245761:245762:245763
-@@ -87,7 +88,7 @@
- 46:376833:-1:-1:376833:376834:376835
- 47:385025:-1:-1:385025:385026:385027
- 48:393217:-1:-1:393217:393218:393219
--49:401409:401409:401410-401412:401413:401414:401415
-+49:401409:401409:401410-401415:401416:401417:401418
- 50:409601:-1:-1:409601:409602:409603
- 51:417793:-1:-1:417793:417794:417795
- 52:425985:-1:-1:425985:425986:425987
-@@ -119,7 +120,7 @@
- 78:638977:-1:-1:638977:638978:638979
- 79:647169:-1:-1:647169:647170:647171
- 80:655361:-1:-1:655361:655362:655363
--81:663553:663553:663554-663556:663557:663558:663559
-+81:663553:663553:663554-663559:663560:663561:663562
- 82:671745:-1:-1:671745:671746:671747
- 83:679937:-1:-1:679937:679938:679939
- 84:688129:-1:-1:688129:688130:688131
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
diff --git a/tests/r_32to64bit_move_itable/name b/tests/r_32to64bit_move_itable/name
deleted file mode 100644
index 7e6bb254831a..000000000000
--- a/tests/r_32to64bit_move_itable/name
+++ /dev/null
@@ -1 +0,0 @@
-convert 32bit fs to 64bit fs, forcing inode table move
diff --git a/tests/r_32to64bit_move_itable/script b/tests/r_32to64bit_move_itable/script
deleted file mode 100644
index c188acdc31aa..000000000000
--- a/tests/r_32to64bit_move_itable/script
+++ /dev/null
@@ -1,74 +0,0 @@
-if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
-
-FSCK_OPT=-fn
-OUT=$test_name.log
-EXP=$test_dir/expect
-CONF=$TMPFILE.conf
-
-cat > $CONF << ENDL
-[fs_types]
- ext4h = {
- features = has_journal,extent,huge_file,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,^resize_inode,^meta_bg,^flex_bg
- blocksize = 1024
- inode_size = 256
- make_hugefiles = true
- hugefiles_dir = /
- hugefiles_slack = 0
- hugefiles_name = aaaaa
- hugefiles_digits = 4
- hugefiles_size = 1M
- zero_hugefiles = false
- }
-ENDL
-
-echo "resize2fs test" > $OUT
-
-MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 786432 >> $OUT 2>&1
-rm -rf $CONF
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# convert it
-echo "resize2fs test.img -b" >> $OUT
-$RESIZE2FS -b -f $TMPFILE 2>&1 >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
-echo "Change in FS metadata:" >> $OUT
-diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-rm $TMPFILE $OUT.before $OUT.after
-
-#
-# Do the verification
-#
-
-sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
-mv $OUT.new $OUT
-
-cmp -s $OUT $EXP
-status=$?
-
-if [ "$status" = 0 ] ; then
- echo "$test_name: $test_description: ok"
- touch $test_name.ok
-else
- echo "$test_name: $test_description: failed"
- diff $DIFF_OPTS $EXP $OUT > $test_name.failed
-fi
-
-unset IMAGE FSCK_OPT OUT EXP CONF
-
-else #if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
- echo "$test_name: $test_description: skipped"
-fi
-
diff --git a/tests/r_64to32bit/expect b/tests/r_64to32bit/expect
deleted file mode 100644
index 13e94a2d2894..000000000000
--- a/tests/r_64to32bit/expect
+++ /dev/null
@@ -1,98 +0,0 @@
-resize2fs test
-Creating filesystem with 524288 1k blocks and 65536 inodes
-Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
-
-Allocating group tables: done
-Writing inode tables: done
-Creating journal (16384 blocks): done
-Creating 477 huge file(s) with 1024 blocks each: done
-Writing superblocks and filesystem accounting information: done
-
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
-resize2fs test.img -s
-Converting the filesystem to 32-bit.
-The filesystem on test.img is now 524288 (1k) blocks long.
-
-Exit status is 0
-Change in FS metadata:
-@@ -2,7 +2,7 @@
- Last mounted on: <not available>
- Filesystem magic number: 0xEF53
- Filesystem revision #: 1 (dynamic)
--Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
-+Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
- Default mount options: user_xattr acl
- Filesystem state: clean
- Errors behavior: Continue
-@@ -10,12 +10,11 @@
- Inode count: 65536
- Block count: 524288
- Reserved block count: 26214
--Free blocks: 571
-+Free blocks: 589
- Free inodes: 65048
- First block: 1
- Block size: 1024
- Fragment size: 1024
--Group descriptor size: 64
- Reserved GDT blocks: 256
- Blocks per group: 8192
- Fragments per group: 8192
-@@ -41,16 +40,16 @@
-
-
- group:block:super:gdt:bbitmap:ibitmap:itable
--0:1:1:2-5:262:278:294
--1:8193:8193:8194-8197:263:279:550
-+0:1:1:2-3:262:278:294
-+1:8193:8193:8194-8195:263:279:550
- 2:16385:-1:-1:264:280:806
--3:24577:24577:24578-24581:265:281:1062
-+3:24577:24577:24578-24579:265:281:1062
- 4:32769:-1:-1:266:282:1318
--5:40961:40961:40962-40965:267:283:1574
-+5:40961:40961:40962-40963:267:283:1574
- 6:49153:-1:-1:268:284:1830
--7:57345:57345:57346-57349:269:285:2086
-+7:57345:57345:57346-57347:269:285:2086
- 8:65537:-1:-1:270:286:2342
--9:73729:73729:73730-73733:271:287:2598
-+9:73729:73729:73730-73731:271:287:2598
- 10:81921:-1:-1:272:288:2854
- 11:90113:-1:-1:273:289:3110
- 12:98305:-1:-1:274:290:3366
-@@ -66,9 +65,9 @@
- 22:180225:-1:-1:131079:131095:132641
- 23:188417:-1:-1:131080:131096:132897
- 24:196609:-1:-1:131081:131097:133153
--25:204801:204801:204802-204805:131082:131098:133409
-+25:204801:204801:204802-204803:131082:131098:133409
- 26:212993:-1:-1:131083:131099:133665
--27:221185:221185:221186-221189:131084:131100:133921
-+27:221185:221185:221186-221187:131084:131100:133921
- 28:229377:-1:-1:131085:131101:134177
- 29:237569:-1:-1:131086:131102:134433
- 30:245761:-1:-1:131087:131103:134689
-@@ -90,7 +89,7 @@
- 46:376833:-1:-1:262159:262175:265761
- 47:385025:-1:-1:262160:262176:266017
- 48:393217:-1:-1:393217:393233:393249
--49:401409:401409:401410-401413:393218:393234:393505
-+49:401409:401409:401410-401411:393218:393234:393505
- 50:409601:-1:-1:393219:393235:393761
- 51:417793:-1:-1:393220:393236:394017
- 52:425985:-1:-1:393221:393237:394273
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
diff --git a/tests/r_64to32bit/name b/tests/r_64to32bit/name
deleted file mode 100644
index 4c8237111295..000000000000
--- a/tests/r_64to32bit/name
+++ /dev/null
@@ -1 +0,0 @@
-convert flex_bg 64bit fs to 32bit fs
diff --git a/tests/r_64to32bit/script b/tests/r_64to32bit/script
deleted file mode 100644
index 5d959f03a6d9..000000000000
--- a/tests/r_64to32bit/script
+++ /dev/null
@@ -1,76 +0,0 @@
-if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
-
-FSCK_OPT=-fn
-OUT=$test_name.log
-EXP=$test_dir/expect
-CONF=$TMPFILE.conf
-
-cat > $CONF << ENDL
-[fs_types]
- ext4h = {
- features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,resize_inode,64bit
- blocksize = 1024
- inode_size = 256
- make_hugefiles = true
- hugefiles_dir = /
- hugefiles_slack = 0
- hugefiles_name = aaaaa
- hugefiles_digits = 4
- hugefiles_size = 1M
- zero_hugefiles = false
- }
-ENDL
-
-echo "resize2fs test" > $OUT
-
-MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
-rm -rf $CONF
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# resize it
-echo "resize2fs test.img -s" >> $OUT
-$RESIZE2FS -s -f $TMPFILE 2>&1 >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
-echo "Change in FS metadata:" >> $OUT
-diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-rm $TMPFILE
-
-#
-# Do the verification
-#
-
-sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
-mv $OUT.new $OUT
-
-cmp -s $OUT $EXP
-status=$?
-
-if [ "$status" = 0 ] ; then
- echo "$test_name: $test_description: ok"
- touch $test_name.ok
-else
- echo "$test_name: $test_description: failed"
- diff $DIFF_OPTS $EXP $OUT > $test_name.failed
-fi
-
-rm $OUT.before $OUT.after
-
-unset IMAGE FSCK_OPT OUT EXP CONF
-
-else #if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
- echo "$test_name: $test_description: skipped"
-fi
-
diff --git a/tests/r_64to32bit_meta/expect b/tests/r_64to32bit_meta/expect
deleted file mode 100644
index d6e2dccc894b..000000000000
--- a/tests/r_64to32bit_meta/expect
+++ /dev/null
@@ -1,80 +0,0 @@
-resize2fs test
-Creating filesystem with 524288 1k blocks and 65536 inodes
-Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
-
-Allocating group tables: done
-Writing inode tables: done
-Creating journal (16384 blocks): done
-Creating 479 huge file(s) with 1024 blocks each: done
-Writing superblocks and filesystem accounting information: done
-
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
-resize2fs test.img -s
-Converting the filesystem to 32-bit.
-The filesystem on test.img is now 524288 (1k) blocks long.
-
-Exit status is 0
-Change in FS metadata:
-@@ -2,7 +2,7 @@
- Last mounted on: <not available>
- Filesystem magic number: 0xEF53
- Filesystem revision #: 1 (dynamic)
--Filesystem features: has_journal ext_attr dir_index filetype meta_bg extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
-+Filesystem features: has_journal ext_attr dir_index filetype meta_bg extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
- Default mount options: user_xattr acl
- Filesystem state: clean
- Errors behavior: Continue
-@@ -10,12 +10,11 @@
- Inode count: 65536
- Block count: 524288
- Reserved block count: 26214
--Free blocks: 852
-+Free blocks: 858
- Free inodes: 65046
- First block: 1
- Block size: 1024
- Fragment size: 1024
--Group descriptor size: 64
- Blocks per group: 8192
- Fragments per group: 8192
- Inodes per group: 1024
-@@ -55,9 +54,9 @@
- 12:98305:-1:-1:15:31:3107
- 13:106497:-1:-1:16:32:3363
- 14:114689:-1:-1:17:33:3619
--15:122881:-1:122881:18:34:3875
--16:131073:-1:131073:131074:131090:131106
--17:139265:-1:139265:131075:131091:131362
-+15:122881:-1:-1:18:34:3875
-+16:131073:-1:-1:131074:131090:131106
-+17:139265:-1:-1:131075:131091:131362
- 18:147457:-1:-1:131076:131092:131618
- 19:155649:-1:-1:131077:131093:131874
- 20:163841:-1:-1:131078:131094:132130
-@@ -87,9 +86,9 @@
- 44:360449:-1:-1:262158:262174:265250
- 45:368641:-1:-1:262159:262175:265506
- 46:376833:-1:-1:262160:262176:265762
--47:385025:-1:385025:262161:262177:266018
--48:393217:-1:393217:393218:393234:393250
--49:401409:401409:401410:393219:393235:393506
-+47:385025:-1:-1:262161:262177:266018
-+48:393217:-1:-1:393218:393234:393250
-+49:401409:401409:-1:393219:393235:393506
- 50:409601:-1:-1:393220:393236:393762
- 51:417793:-1:-1:393221:393237:394018
- 52:425985:-1:-1:393222:393238:394274
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-Exit status is 0
diff --git a/tests/r_64to32bit_meta/name b/tests/r_64to32bit_meta/name
deleted file mode 100644
index e99ed8b8d1b2..000000000000
--- a/tests/r_64to32bit_meta/name
+++ /dev/null
@@ -1 +0,0 @@
-convert meta_bg 64bit fs to 32bit fs
diff --git a/tests/r_64to32bit_meta/script b/tests/r_64to32bit_meta/script
deleted file mode 100644
index 5a02e2664393..000000000000
--- a/tests/r_64to32bit_meta/script
+++ /dev/null
@@ -1,76 +0,0 @@
-if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
-
-FSCK_OPT=-fn
-OUT=$test_name.log
-EXP=$test_dir/expect
-CONF=$TMPFILE.conf
-
-cat > $CONF << ENDL
-[fs_types]
- ext4h = {
- features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,meta_bg,^resize_inode,64bit
- blocksize = 1024
- inode_size = 256
- make_hugefiles = true
- hugefiles_dir = /
- hugefiles_slack = 0
- hugefiles_name = aaaaa
- hugefiles_digits = 4
- hugefiles_size = 1M
- zero_hugefiles = false
- }
-ENDL
-
-echo "resize2fs test" > $OUT
-
-MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
-rm -rf $CONF
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# resize it
-echo "resize2fs test.img -s" >> $OUT
-$RESIZE2FS -s -f $TMPFILE 2>&1 >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-# dump and check
-($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
-echo "Change in FS metadata:" >> $OUT
-diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
-$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
-status=$?
-echo Exit status is $status >> $OUT
-
-rm $TMPFILE
-
-#
-# Do the verification
-#
-
-sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
-mv $OUT.new $OUT
-
-cmp -s $OUT $EXP
-status=$?
-
-if [ "$status" = 0 ] ; then
- echo "$test_name: $test_description: ok"
- touch $test_name.ok
-else
- echo "$test_name: $test_description: failed"
- diff $DIFF_OPTS $EXP $OUT > $test_name.failed
-fi
-
-rm $OUT.before $OUT.after
-
-unset IMAGE FSCK_OPT OUT EXP CONF
-
-else #if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
- echo "$test_name: $test_description: skipped"
-fi
-
diff --git a/tests/t_32to64bit/expect b/tests/t_32to64bit/expect
new file mode 100644
index 000000000000..4b030e4b22cd
--- /dev/null
+++ b/tests/t_32to64bit/expect
@@ -0,0 +1,91 @@
+tune2fs test
+Creating filesystem with 524288 1k blocks and 65536 inodes
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Creating 477 huge file(s) with 1024 blocks each: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
+tune2fs -O 64bit test.img
+Exit status is 0
+Change in FS metadata:
+@@ -2,7 +2,7 @@
+ Last mounted on: <not available>
+ Filesystem magic number: 0xEF53
+ Filesystem revision #: 1 (dynamic)
+-Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
++Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
+ Default mount options: user_xattr acl
+ Filesystem state: clean
+ Errors behavior: Continue
+@@ -15,7 +15,8 @@
+ First block: 1
+ Block size: 1024
+ Fragment size: 1024
+-Reserved GDT blocks: 256
++Group descriptor size: 64
++Reserved GDT blocks: 254
+ Blocks per group: 8192
+ Fragments per group: 8192
+ Inodes per group: 1024
+@@ -40,16 +41,16 @@
+
+
+ group:block:super:gdt:bbitmap:ibitmap:itable
+-0:1:1:2-3:260:276:292
+-1:8193:8193:8194-8195:261:277:548
++0:1:1:2-5:260:276:292
++1:8193:8193:8194-8197:261:277:548
+ 2:16385:-1:-1:262:278:804
+-3:24577:24577:24578-24579:263:279:1060
++3:24577:24577:24578-24581:263:279:1060
+ 4:32769:-1:-1:264:280:1316
+-5:40961:40961:40962-40963:265:281:1572
++5:40961:40961:40962-40965:265:281:1572
+ 6:49153:-1:-1:266:282:1828
+-7:57345:57345:57346-57347:267:283:2084
++7:57345:57345:57346-57349:267:283:2084
+ 8:65537:-1:-1:268:284:2340
+-9:73729:73729:73730-73731:269:285:2596
++9:73729:73729:73730-73733:269:285:2596
+ 10:81921:-1:-1:270:286:2852
+ 11:90113:-1:-1:271:287:3108
+ 12:98305:-1:-1:272:288:3364
+@@ -65,9 +66,9 @@
+ 22:180225:-1:-1:131079:131095:132641
+ 23:188417:-1:-1:131080:131096:132897
+ 24:196609:-1:-1:131081:131097:133153
+-25:204801:204801:204802-204803:131082:131098:133409
++25:204801:204801:204802-204805:131082:131098:133409
+ 26:212993:-1:-1:131083:131099:133665
+-27:221185:221185:221186-221187:131084:131100:133921
++27:221185:221185:221186-221189:131084:131100:133921
+ 28:229377:-1:-1:131085:131101:134177
+ 29:237569:-1:-1:131086:131102:134433
+ 30:245761:-1:-1:131087:131103:134689
+@@ -89,7 +90,7 @@
+ 46:376833:-1:-1:262159:262175:265761
+ 47:385025:-1:-1:262160:262176:266017
+ 48:393217:-1:-1:393217:393233:393249
+-49:401409:401409:401410-401411:393218:393234:393505
++49:401409:401409:401410-401413:393218:393234:393505
+ 50:409601:-1:-1:393219:393235:393761
+ 51:417793:-1:-1:393220:393236:394017
+ 52:425985:-1:-1:393221:393237:394273
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
diff --git a/tests/t_32to64bit/name b/tests/t_32to64bit/name
new file mode 100644
index 000000000000..fb45faba6468
--- /dev/null
+++ b/tests/t_32to64bit/name
@@ -0,0 +1 @@
+convert flex_bg 32bit fs to 64bit fs
diff --git a/tests/t_32to64bit/script b/tests/t_32to64bit/script
new file mode 100644
index 000000000000..695208cc7ec3
--- /dev/null
+++ b/tests/t_32to64bit/script
@@ -0,0 +1,74 @@
+if test -x $DEBUGFS_EXE; then
+
+FSCK_OPT=-fn
+OUT=$test_name.log
+EXP=$test_dir/expect
+CONF=$TMPFILE.conf
+
+cat > $CONF << ENDL
+[fs_types]
+ ext4h = {
+ features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,resize_inode
+ blocksize = 1024
+ inode_size = 256
+ make_hugefiles = true
+ hugefiles_dir = /
+ hugefiles_slack = 0
+ hugefiles_name = aaaaa
+ hugefiles_digits = 4
+ hugefiles_size = 1M
+ zero_hugefiles = false
+ }
+ENDL
+
+echo "tune2fs test" > $OUT
+
+MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
+rm -rf $CONF
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# resize it
+echo "tune2fs -O 64bit test.img" >> $OUT
+$TUNE2FS -O 64bit $TMPFILE 2>&1 >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
+echo "Change in FS metadata:" >> $OUT
+diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+rm $TMPFILE $OUT.before $OUT.after
+
+#
+# Do the verification
+#
+
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
+mv $OUT.new $OUT
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+unset IMAGE FSCK_OPT OUT EXP CONF
+
+else # if test -x $DEBUGFS_EXE; then
+ echo "$test_name: $test_description: skipped"
+fi
+
diff --git a/tests/t_32to64bit_expand_full/expect b/tests/t_32to64bit_expand_full/expect
new file mode 100644
index 000000000000..2093c1df2e46
--- /dev/null
+++ b/tests/t_32to64bit_expand_full/expect
@@ -0,0 +1,136 @@
+tune2fs test
+Creating filesystem with 786432 1k blocks and 98304 inodes
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Creating 727 huge file(s) with 1024 blocks each: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
+tune2fs -O 64bit test.img
+resize2fs test.img
+Resizing the filesystem on test.img to 1179648 (1k) blocks.
+The filesystem on test.img is now 1179648 (1k) blocks long.
+
+Exit status is 0
+Change in FS metadata:
+@@ -1,15 +1,15 @@
+
+ group:block:super:gdt:bbitmap:ibitmap:itable
+-0:1:1:2-7:8:9:10
+-1:8193:8193:8194-8199:8200:8201:8202
++0:1:1:2-10:266:267:268
++1:8193:8193:8194-8202:8458:8459:8460
+ 2:16385:-1:-1:16385:16386:16387
+-3:24577:24577:24578-24583:24584:24585:24586
++3:24577:24577:24578-24586:24842:24843:24844
+ 4:32769:-1:-1:32769:32770:32771
+-5:40961:40961:40962-40967:40968:40969:40970
++5:40961:40961:40962-40970:41226:41227:41228
+ 6:49153:-1:-1:49153:49154:49155
+-7:57345:57345:57346-57351:57352:57353:57354
++7:57345:57345:57346-57354:57610:57611:57612
+ 8:65537:-1:-1:65537:65538:65539
+-9:73729:73729:73730-73735:73736:73737:73738
++9:73729:73729:73730-73738:73994:73995:73996
+ 10:81921:-1:-1:81921:81922:81923
+ 11:90113:-1:-1:90113:90114:90115
+ 12:98305:-1:-1:98305:98306:98307
+@@ -25,9 +25,9 @@
+ 22:180225:-1:-1:180225:180226:180227
+ 23:188417:-1:-1:188417:188418:188419
+ 24:196609:-1:-1:196609:196610:196611
+-25:204801:204801:204802-204807:204808:204809:204810
++25:204801:204801:204802-204810:205066:205067:205068
+ 26:212993:-1:-1:212993:212994:212995
+-27:221185:221185:221186-221191:221192:221193:221194
++27:221185:221185:221186-221194:221450:221451:221452
+ 28:229377:-1:-1:229377:229378:229379
+ 29:237569:-1:-1:237569:237570:237571
+ 30:245761:-1:-1:245761:245762:245763
+@@ -49,7 +49,7 @@
+ 46:376833:-1:-1:376833:376834:376835
+ 47:385025:-1:-1:385025:385026:385027
+ 48:393217:-1:-1:393217:393218:393219
+-49:401409:401409:401410-401415:401416:401417:401418
++49:401409:401409:401410-401418:401674:401675:401676
+ 50:409601:-1:-1:409601:409602:409603
+ 51:417793:-1:-1:417793:417794:417795
+ 52:425985:-1:-1:425985:425986:425987
+@@ -81,7 +81,7 @@
+ 78:638977:-1:-1:638977:638978:638979
+ 79:647169:-1:-1:647169:647170:647171
+ 80:655361:-1:-1:655361:655362:655363
+-81:663553:663553:663554-663559:663560:663561:663562
++81:663553:663553:663554-663562:663818:663819:663820
+ 82:671745:-1:-1:671745:671746:671747
+ 83:679937:-1:-1:679937:679938:679939
+ 84:688129:-1:-1:688129:688130:688131
+@@ -96,3 +96,51 @@
+ 93:761857:-1:-1:761857:761858:761859
+ 94:770049:-1:-1:770049:770050:770051
+ 95:778241:-1:-1:778241:778242:778243
++96:786433:-1:-1:786433:786434:786435
++97:794625:-1:-1:794625:794626:794627
++98:802817:-1:-1:802817:802818:802819
++99:811009:-1:-1:811009:811010:811011
++100:819201:-1:-1:819201:819202:819203
++101:827393:-1:-1:827393:827394:827395
++102:835585:-1:-1:835585:835586:835587
++103:843777:-1:-1:843777:843778:843779
++104:851969:-1:-1:851969:851970:851971
++105:860161:-1:-1:860161:860162:860163
++106:868353:-1:-1:868353:868354:868355
++107:876545:-1:-1:876545:876546:876547
++108:884737:-1:-1:884737:884738:884739
++109:892929:-1:-1:892929:892930:892931
++110:901121:-1:-1:901121:901122:901123
++111:909313:-1:-1:909313:909314:909315
++112:917505:-1:-1:917505:917506:917507
++113:925697:-1:-1:925697:925698:925699
++114:933889:-1:-1:933889:933890:933891
++115:942081:-1:-1:942081:942082:942083
++116:950273:-1:-1:950273:950274:950275
++117:958465:-1:-1:958465:958466:958467
++118:966657:-1:-1:966657:966658:966659
++119:974849:-1:-1:974849:974850:974851
++120:983041:-1:-1:983041:983042:983043
++121:991233:-1:-1:991233:991234:991235
++122:999425:-1:-1:999425:999426:999427
++123:1007617:-1:-1:1007617:1007618:1007619
++124:1015809:-1:-1:1015809:1015810:1015811
++125:1024001:1024001:1024002-1024010:1024011:1024012:1024013
++126:1032193:-1:-1:1032193:1032194:1032195
++127:1040385:-1:-1:1040385:1040386:1040387
++128:1048577:-1:-1:1048577:1048578:1048579
++129:1056769:-1:-1:1056769:1056770:1056771
++130:1064961:-1:-1:1064961:1064962:1064963
++131:1073153:-1:-1:1073153:1073154:1073155
++132:1081345:-1:-1:1081345:1081346:1081347
++133:1089537:-1:-1:1089537:1089538:1089539
++134:1097729:-1:-1:1097729:1097730:1097731
++135:1105921:-1:-1:1105921:1105922:1105923
++136:1114113:-1:-1:1114113:1114114:1114115
++137:1122305:-1:-1:1122305:1122306:1122307
++138:1130497:-1:-1:1130497:1130498:1130499
++139:1138689:-1:-1:1138689:1138690:1138691
++140:1146881:-1:-1:1146881:1146882:1146883
++141:1155073:-1:-1:1155073:1155074:1155075
++142:1163265:-1:-1:1163265:1163266:1163267
++143:1171457:-1:-1:1171457:1171458:1171459
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
diff --git a/tests/t_32to64bit_expand_full/name b/tests/t_32to64bit_expand_full/name
new file mode 100644
index 000000000000..2f046011bcf8
--- /dev/null
+++ b/tests/t_32to64bit_expand_full/name
@@ -0,0 +1 @@
+convert a totally full filesystem to 64bit, then expand
diff --git a/tests/t_32to64bit_expand_full/script b/tests/t_32to64bit_expand_full/script
new file mode 100644
index 000000000000..603c5818c1c3
--- /dev/null
+++ b/tests/t_32to64bit_expand_full/script
@@ -0,0 +1,83 @@
+if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
+
+FSCK_OPT=-fn
+OUT=$test_name.log
+EXP=$test_dir/expect
+CONF=$TMPFILE.conf
+
+#gzip -d < $EXP.gz > $EXP
+
+cat > $CONF << ENDL
+[fs_types]
+ ext4h = {
+ features = has_journal,extent,huge_file,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,^resize_inode,^meta_bg,^flex_bg
+ blocksize = 1024
+ inode_size = 256
+ make_hugefiles = true
+ hugefiles_dir = /
+ hugefiles_slack = 0
+ hugefiles_name = aaaaa
+ hugefiles_digits = 4
+ hugefiles_size = 1M
+ zero_hugefiles = false
+ }
+ENDL
+
+echo "tune2fs test" > $OUT
+
+MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 786432 >> $OUT 2>&1
+rm -rf $CONF
+
+# check
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# convert it
+echo "tune2fs -O 64bit test.img" >> $OUT
+$TUNE2FS -O 64bit $TMPFILE 2>&1 >> $OUT 2>&1
+$DUMPE2FS -g $TMPFILE 2>&1 >> $OUT.before 2> /dev/null
+
+# grow it
+echo "resize2fs test.img" >> $OUT
+dd if=/dev/zero of=$TMPFILE conv=notrunc bs=1 count=1 seek=1207959552 2> /dev/null
+$RESIZE2FS -f $TMPFILE 2>&1 >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# dump and check
+$DUMPE2FS -g $TMPFILE 2>&1 >> $OUT.after 2> /dev/null
+echo "Change in FS metadata:" >> $OUT
+diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+rm $TMPFILE
+
+#
+# Do the verification
+#
+
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
+mv $OUT.new $OUT
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+rm $OUT.before $OUT.after
+
+unset IMAGE FSCK_OPT OUT EXP CONF
+
+else #if test -x $RESIZE2FS_EXE -a -x $DEBUGFS_EXE; then
+ echo "$test_name: $test_description: skipped"
+fi
+
diff --git a/tests/t_32to64bit_meta/expect b/tests/t_32to64bit_meta/expect
new file mode 100644
index 000000000000..28e328c524a8
--- /dev/null
+++ b/tests/t_32to64bit_meta/expect
@@ -0,0 +1,77 @@
+tune2fs test
+Creating filesystem with 524288 1k blocks and 65536 inodes
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Creating 479 huge file(s) with 1024 blocks each: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
+tune2fs -O 64bit test.img
+Exit status is 0
+Change in FS metadata:
+@@ -2,7 +2,7 @@
+ Last mounted on: <not available>
+ Filesystem magic number: 0xEF53
+ Filesystem revision #: 1 (dynamic)
+-Filesystem features: has_journal ext_attr dir_index filetype meta_bg extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
++Filesystem features: has_journal ext_attr dir_index filetype meta_bg extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
+ Default mount options: user_xattr acl
+ Filesystem state: clean
+ Errors behavior: Continue
+@@ -10,11 +10,12 @@
+ Inode count: 65536
+ Block count: 524288
+ Reserved block count: 26214
+-Free blocks: 858
++Free blocks: 852
+ Free inodes: 65046
+ First block: 1
+ Block size: 1024
+ Fragment size: 1024
++Group descriptor size: 64
+ Blocks per group: 8192
+ Fragments per group: 8192
+ Inodes per group: 1024
+@@ -54,9 +55,9 @@
+ 12:98305:-1:-1:15:31:3107
+ 13:106497:-1:-1:16:32:3363
+ 14:114689:-1:-1:17:33:3619
+-15:122881:-1:-1:18:34:3875
+-16:131073:-1:-1:131073:131089:131105
+-17:139265:-1:-1:131074:131090:131361
++15:122881:-1:122881:18:34:3875
++16:131073:-1:131073:135201:131089:131105
++17:139265:-1:139265:131074:131090:131361
+ 18:147457:-1:-1:131075:131091:131617
+ 19:155649:-1:-1:131076:131092:131873
+ 20:163841:-1:-1:131077:131093:132129
+@@ -86,9 +87,9 @@
+ 44:360449:-1:-1:262158:262174:265250
+ 45:368641:-1:-1:262159:262175:265506
+ 46:376833:-1:-1:262160:262176:265762
+-47:385025:-1:-1:262161:262177:266018
+-48:393217:-1:-1:393217:393233:393249
+-49:401409:401409:-1:393218:393234:393505
++47:385025:-1:385025:262161:262177:266018
++48:393217:-1:393217:397345:393233:393249
++49:401409:401409:401410:393218:393234:393505
+ 50:409601:-1:-1:393219:393235:393761
+ 51:417793:-1:-1:393220:393236:394017
+ 52:425985:-1:-1:393221:393237:394273
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
diff --git a/tests/t_32to64bit_meta/name b/tests/t_32to64bit_meta/name
new file mode 100644
index 000000000000..d83492eae8cf
--- /dev/null
+++ b/tests/t_32to64bit_meta/name
@@ -0,0 +1 @@
+convert meta_bg 32bit fs to 64bit fs
diff --git a/tests/t_32to64bit_meta/script b/tests/t_32to64bit_meta/script
new file mode 100644
index 000000000000..9b02266e64c6
--- /dev/null
+++ b/tests/t_32to64bit_meta/script
@@ -0,0 +1,74 @@
+if test -x $DEBUGFS_EXE; then
+
+FSCK_OPT=-fn
+OUT=$test_name.log
+EXP=$test_dir/expect
+CONF=$TMPFILE.conf
+
+cat > $CONF << ENDL
+[fs_types]
+ ext4h = {
+ features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,meta_bg,^resize_inode
+ blocksize = 1024
+ inode_size = 256
+ make_hugefiles = true
+ hugefiles_dir = /
+ hugefiles_slack = 0
+ hugefiles_name = aaaaa
+ hugefiles_digits = 4
+ hugefiles_size = 1M
+ zero_hugefiles = false
+ }
+ENDL
+
+echo "tune2fs test" > $OUT
+
+MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
+rm -rf $CONF
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# resize it
+echo "tune2fs -O 64bit test.img" >> $OUT
+$TUNE2FS -O 64bit $TMPFILE 2>&1 >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
+echo "Change in FS metadata:" >> $OUT
+diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+rm $TMPFILE $OUT.before $OUT.after
+
+#
+# Do the verification
+#
+
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
+mv $OUT.new $OUT
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+unset IMAGE FSCK_OPT OUT EXP CONF
+
+else #if test -x $DEBUGFS_EXE; then
+ echo "$test_name: $test_description: skipped"
+fi
+
diff --git a/tests/t_32to64bit_move_itable/expect b/tests/t_32to64bit_move_itable/expect
new file mode 100644
index 000000000000..e4fa55432bb3
--- /dev/null
+++ b/tests/t_32to64bit_move_itable/expect
@@ -0,0 +1,104 @@
+tune2fs test
+Creating filesystem with 786432 1k blocks and 98304 inodes
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Creating 727 huge file(s) with 1024 blocks each: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
+tune2fs -O 64bit test.img
+Exit status is 0
+Change in FS metadata:
+@@ -2,7 +2,7 @@
+ Last mounted on: <not available>
+ Filesystem magic number: 0xEF53
+ Filesystem revision #: 1 (dynamic)
+-Filesystem features: has_journal ext_attr dir_index filetype extent sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
++Filesystem features: has_journal ext_attr dir_index filetype extent 64bit sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
+ Default mount options: user_xattr acl
+ Filesystem state: clean
+ Errors behavior: Continue
+@@ -10,11 +10,12 @@
+ Inode count: 98304
+ Block count: 786432
+ Reserved block count: 39321
+-Free blocks: 764
++Free blocks: 734
+ Free inodes: 97566
+ First block: 1
+ Block size: 1024
+ Fragment size: 1024
++Group descriptor size: 64
+ Blocks per group: 8192
+ Fragments per group: 8192
+ Inodes per group: 1024
+@@ -38,16 +39,16 @@
+
+
+ group:block:super:gdt:bbitmap:ibitmap:itable
+-0:1:1:2-4:5:6:7
+-1:8193:8193:8194-8196:8197:8198:8199
++0:1:1:2-7:8:9:10
++1:8193:8193:8194-8199:8200:8201:8202
+ 2:16385:-1:-1:16385:16386:16387
+-3:24577:24577:24578-24580:24581:24582:24583
++3:24577:24577:24578-24583:24584:24585:24586
+ 4:32769:-1:-1:32769:32770:32771
+-5:40961:40961:40962-40964:40965:40966:40967
++5:40961:40961:40962-40967:40968:40969:40970
+ 6:49153:-1:-1:49153:49154:49155
+-7:57345:57345:57346-57348:57349:57350:57351
++7:57345:57345:57346-57351:57352:57353:57354
+ 8:65537:-1:-1:65537:65538:65539
+-9:73729:73729:73730-73732:73733:73734:73735
++9:73729:73729:73730-73735:73736:73737:73738
+ 10:81921:-1:-1:81921:81922:81923
+ 11:90113:-1:-1:90113:90114:90115
+ 12:98305:-1:-1:98305:98306:98307
+@@ -63,9 +64,9 @@
+ 22:180225:-1:-1:180225:180226:180227
+ 23:188417:-1:-1:188417:188418:188419
+ 24:196609:-1:-1:196609:196610:196611
+-25:204801:204801:204802-204804:204805:204806:204807
++25:204801:204801:204802-204807:204808:204809:204810
+ 26:212993:-1:-1:212993:212994:212995
+-27:221185:221185:221186-221188:221189:221190:221191
++27:221185:221185:221186-221191:221192:221193:221194
+ 28:229377:-1:-1:229377:229378:229379
+ 29:237569:-1:-1:237569:237570:237571
+ 30:245761:-1:-1:245761:245762:245763
+@@ -87,7 +88,7 @@
+ 46:376833:-1:-1:376833:376834:376835
+ 47:385025:-1:-1:385025:385026:385027
+ 48:393217:-1:-1:393217:393218:393219
+-49:401409:401409:401410-401412:401413:401414:401415
++49:401409:401409:401410-401415:401416:401417:401418
+ 50:409601:-1:-1:409601:409602:409603
+ 51:417793:-1:-1:417793:417794:417795
+ 52:425985:-1:-1:425985:425986:425987
+@@ -119,7 +120,7 @@
+ 78:638977:-1:-1:638977:638978:638979
+ 79:647169:-1:-1:647169:647170:647171
+ 80:655361:-1:-1:655361:655362:655363
+-81:663553:663553:663554-663556:663557:663558:663559
++81:663553:663553:663554-663559:663560:663561:663562
+ 82:671745:-1:-1:671745:671746:671747
+ 83:679937:-1:-1:679937:679938:679939
+ 84:688129:-1:-1:688129:688130:688131
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
diff --git a/tests/t_32to64bit_move_itable/name b/tests/t_32to64bit_move_itable/name
new file mode 100644
index 000000000000..7e6bb254831a
--- /dev/null
+++ b/tests/t_32to64bit_move_itable/name
@@ -0,0 +1 @@
+convert 32bit fs to 64bit fs, forcing inode table move
diff --git a/tests/t_32to64bit_move_itable/script b/tests/t_32to64bit_move_itable/script
new file mode 100644
index 000000000000..b0ac6e1d375d
--- /dev/null
+++ b/tests/t_32to64bit_move_itable/script
@@ -0,0 +1,74 @@
+if test -x $DEBUGFS_EXE; then
+
+FSCK_OPT=-fn
+OUT=$test_name.log
+EXP=$test_dir/expect
+CONF=$TMPFILE.conf
+
+cat > $CONF << ENDL
+[fs_types]
+ ext4h = {
+ features = has_journal,extent,huge_file,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,^resize_inode,^meta_bg,^flex_bg
+ blocksize = 1024
+ inode_size = 256
+ make_hugefiles = true
+ hugefiles_dir = /
+ hugefiles_slack = 0
+ hugefiles_name = aaaaa
+ hugefiles_digits = 4
+ hugefiles_size = 1M
+ zero_hugefiles = false
+ }
+ENDL
+
+echo "tune2fs test" > $OUT
+
+MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 786432 >> $OUT 2>&1
+rm -rf $CONF
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# convert it
+echo "tune2fs -O 64bit test.img" >> $OUT
+$TUNE2FS -O 64bit $TMPFILE 2>&1 >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
+echo "Change in FS metadata:" >> $OUT
+diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+rm $TMPFILE $OUT.before $OUT.after
+
+#
+# Do the verification
+#
+
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
+mv $OUT.new $OUT
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+unset IMAGE FSCK_OPT OUT EXP CONF
+
+else #if -x $DEBUGFS_EXE; then
+ echo "$test_name: $test_description: skipped"
+fi
+
diff --git a/tests/t_64to32bit/expect b/tests/t_64to32bit/expect
new file mode 100644
index 000000000000..6d8ff8011a7c
--- /dev/null
+++ b/tests/t_64to32bit/expect
@@ -0,0 +1,95 @@
+tune2fs test
+Creating filesystem with 524288 1k blocks and 65536 inodes
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Creating 477 huge file(s) with 1024 blocks each: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
+tune2fs test.img -s
+Exit status is 0
+Change in FS metadata:
+@@ -2,7 +2,7 @@
+ Last mounted on: <not available>
+ Filesystem magic number: 0xEF53
+ Filesystem revision #: 1 (dynamic)
+-Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
++Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
+ Default mount options: user_xattr acl
+ Filesystem state: clean
+ Errors behavior: Continue
+@@ -10,12 +10,11 @@
+ Inode count: 65536
+ Block count: 524288
+ Reserved block count: 26214
+-Free blocks: 571
++Free blocks: 589
+ Free inodes: 65048
+ First block: 1
+ Block size: 1024
+ Fragment size: 1024
+-Group descriptor size: 64
+ Reserved GDT blocks: 256
+ Blocks per group: 8192
+ Fragments per group: 8192
+@@ -41,16 +40,16 @@
+
+
+ group:block:super:gdt:bbitmap:ibitmap:itable
+-0:1:1:2-5:262:278:294
+-1:8193:8193:8194-8197:263:279:550
++0:1:1:2-3:262:278:294
++1:8193:8193:8194-8195:263:279:550
+ 2:16385:-1:-1:264:280:806
+-3:24577:24577:24578-24581:265:281:1062
++3:24577:24577:24578-24579:265:281:1062
+ 4:32769:-1:-1:266:282:1318
+-5:40961:40961:40962-40965:267:283:1574
++5:40961:40961:40962-40963:267:283:1574
+ 6:49153:-1:-1:268:284:1830
+-7:57345:57345:57346-57349:269:285:2086
++7:57345:57345:57346-57347:269:285:2086
+ 8:65537:-1:-1:270:286:2342
+-9:73729:73729:73730-73733:271:287:2598
++9:73729:73729:73730-73731:271:287:2598
+ 10:81921:-1:-1:272:288:2854
+ 11:90113:-1:-1:273:289:3110
+ 12:98305:-1:-1:274:290:3366
+@@ -66,9 +65,9 @@
+ 22:180225:-1:-1:131079:131095:132641
+ 23:188417:-1:-1:131080:131096:132897
+ 24:196609:-1:-1:131081:131097:133153
+-25:204801:204801:204802-204805:131082:131098:133409
++25:204801:204801:204802-204803:131082:131098:133409
+ 26:212993:-1:-1:131083:131099:133665
+-27:221185:221185:221186-221189:131084:131100:133921
++27:221185:221185:221186-221187:131084:131100:133921
+ 28:229377:-1:-1:131085:131101:134177
+ 29:237569:-1:-1:131086:131102:134433
+ 30:245761:-1:-1:131087:131103:134689
+@@ -90,7 +89,7 @@
+ 46:376833:-1:-1:262159:262175:265761
+ 47:385025:-1:-1:262160:262176:266017
+ 48:393217:-1:-1:393217:393233:393249
+-49:401409:401409:401410-401413:393218:393234:393505
++49:401409:401409:401410-401411:393218:393234:393505
+ 50:409601:-1:-1:393219:393235:393761
+ 51:417793:-1:-1:393220:393236:394017
+ 52:425985:-1:-1:393221:393237:394273
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
diff --git a/tests/t_64to32bit/name b/tests/t_64to32bit/name
new file mode 100644
index 000000000000..4c8237111295
--- /dev/null
+++ b/tests/t_64to32bit/name
@@ -0,0 +1 @@
+convert flex_bg 64bit fs to 32bit fs
diff --git a/tests/t_64to32bit/script b/tests/t_64to32bit/script
new file mode 100644
index 000000000000..dd01a9c1cfd8
--- /dev/null
+++ b/tests/t_64to32bit/script
@@ -0,0 +1,76 @@
+if test -x $DEBUGFS_EXE; then
+
+FSCK_OPT=-fn
+OUT=$test_name.log
+EXP=$test_dir/expect
+CONF=$TMPFILE.conf
+
+cat > $CONF << ENDL
+[fs_types]
+ ext4h = {
+ features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,resize_inode,64bit
+ blocksize = 1024
+ inode_size = 256
+ make_hugefiles = true
+ hugefiles_dir = /
+ hugefiles_slack = 0
+ hugefiles_name = aaaaa
+ hugefiles_digits = 4
+ hugefiles_size = 1M
+ zero_hugefiles = false
+ }
+ENDL
+
+echo "tune2fs test" > $OUT
+
+MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
+rm -rf $CONF
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# resize it
+echo "tune2fs test.img -s" >> $OUT
+$TUNE2FS -O ^64bit $TMPFILE 2>&1 >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
+echo "Change in FS metadata:" >> $OUT
+diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+rm $TMPFILE
+
+#
+# Do the verification
+#
+
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
+mv $OUT.new $OUT
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+rm $OUT.before $OUT.after
+
+unset IMAGE FSCK_OPT OUT EXP CONF
+
+else #if test -x $DEBUGFS_EXE; then
+ echo "$test_name: $test_description: skipped"
+fi
+
diff --git a/tests/t_64to32bit_meta/expect b/tests/t_64to32bit_meta/expect
new file mode 100644
index 000000000000..d6e2dccc894b
--- /dev/null
+++ b/tests/t_64to32bit_meta/expect
@@ -0,0 +1,80 @@
+resize2fs test
+Creating filesystem with 524288 1k blocks and 65536 inodes
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Creating 479 huge file(s) with 1024 blocks each: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
+resize2fs test.img -s
+Converting the filesystem to 32-bit.
+The filesystem on test.img is now 524288 (1k) blocks long.
+
+Exit status is 0
+Change in FS metadata:
+@@ -2,7 +2,7 @@
+ Last mounted on: <not available>
+ Filesystem magic number: 0xEF53
+ Filesystem revision #: 1 (dynamic)
+-Filesystem features: has_journal ext_attr dir_index filetype meta_bg extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
++Filesystem features: has_journal ext_attr dir_index filetype meta_bg extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
+ Default mount options: user_xattr acl
+ Filesystem state: clean
+ Errors behavior: Continue
+@@ -10,12 +10,11 @@
+ Inode count: 65536
+ Block count: 524288
+ Reserved block count: 26214
+-Free blocks: 852
++Free blocks: 858
+ Free inodes: 65046
+ First block: 1
+ Block size: 1024
+ Fragment size: 1024
+-Group descriptor size: 64
+ Blocks per group: 8192
+ Fragments per group: 8192
+ Inodes per group: 1024
+@@ -55,9 +54,9 @@
+ 12:98305:-1:-1:15:31:3107
+ 13:106497:-1:-1:16:32:3363
+ 14:114689:-1:-1:17:33:3619
+-15:122881:-1:122881:18:34:3875
+-16:131073:-1:131073:131074:131090:131106
+-17:139265:-1:139265:131075:131091:131362
++15:122881:-1:-1:18:34:3875
++16:131073:-1:-1:131074:131090:131106
++17:139265:-1:-1:131075:131091:131362
+ 18:147457:-1:-1:131076:131092:131618
+ 19:155649:-1:-1:131077:131093:131874
+ 20:163841:-1:-1:131078:131094:132130
+@@ -87,9 +86,9 @@
+ 44:360449:-1:-1:262158:262174:265250
+ 45:368641:-1:-1:262159:262175:265506
+ 46:376833:-1:-1:262160:262176:265762
+-47:385025:-1:385025:262161:262177:266018
+-48:393217:-1:393217:393218:393234:393250
+-49:401409:401409:401410:393219:393235:393506
++47:385025:-1:-1:262161:262177:266018
++48:393217:-1:-1:393218:393234:393250
++49:401409:401409:-1:393219:393235:393506
+ 50:409601:-1:-1:393220:393236:393762
+ 51:417793:-1:-1:393221:393237:394018
+ 52:425985:-1:-1:393222:393238:394274
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
diff --git a/tests/t_64to32bit_meta/name b/tests/t_64to32bit_meta/name
new file mode 100644
index 000000000000..e99ed8b8d1b2
--- /dev/null
+++ b/tests/t_64to32bit_meta/name
@@ -0,0 +1 @@
+convert meta_bg 64bit fs to 32bit fs
diff --git a/tests/t_64to32bit_meta/script b/tests/t_64to32bit_meta/script
new file mode 100644
index 000000000000..478709e0c3c1
--- /dev/null
+++ b/tests/t_64to32bit_meta/script
@@ -0,0 +1,76 @@
+if -x $DEBUGFS_EXE; then
+
+FSCK_OPT=-fn
+OUT=$test_name.log
+EXP=$test_dir/expect
+CONF=$TMPFILE.conf
+
+cat > $CONF << ENDL
+[fs_types]
+ ext4h = {
+ features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,meta_bg,^resize_inode,64bit
+ blocksize = 1024
+ inode_size = 256
+ make_hugefiles = true
+ hugefiles_dir = /
+ hugefiles_slack = 0
+ hugefiles_name = aaaaa
+ hugefiles_digits = 4
+ hugefiles_size = 1M
+ zero_hugefiles = false
+ }
+ENDL
+
+echo "tune2fs test" > $OUT
+
+MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
+rm -rf $CONF
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.before
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# resize it
+echo "tune2fs test.img -s" >> $OUT
+$TUNE2FS -O ^64bit $TMPFILE 2>&1 >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# dump and check
+($DUMPE2FS -h $TMPFILE; $DUMPE2FS -g $TMPFILE) 2> /dev/null | sed -f $cmd_dir/filter.sed > $OUT.after
+echo "Change in FS metadata:" >> $OUT
+diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+rm $TMPFILE
+
+#
+# Do the verification
+#
+
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
+mv $OUT.new $OUT
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+rm $OUT.before $OUT.after
+
+unset IMAGE FSCK_OPT OUT EXP CONF
+
+else #if test -x $DEBUGFS_EXE; then
+ echo "$test_name: $test_description: skipped"
+fi
+
diff --git a/tests/u_onefile_bad/script b/tests/u_onefile_bad/script
index 60c9a2e64a26..090deb619e6f 100644
--- a/tests/u_onefile_bad/script
+++ b/tests/u_onefile_bad/script
@@ -1,7 +1,7 @@
test_description="check that we cant append a bad undo file"
-if test -x $RESIZE2FS_EXE -a -x $E2UNDO_EXE; then
+if -x $E2UNDO_EXE; then

-TDB_FILE=${TMPDIR:-/tmp}/resize2fs-$(basename $TMPFILE).e2undo
+TDB_FILE=${TMPDIR:-/tmp}/tune2fs-$(basename $TMPFILE).e2undo
OUT=$test_name.log
rm -f $TDB_FILE >/dev/null 2>&1
fail=0
@@ -41,10 +41,10 @@ if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${f
fi
$FSCK -f -n $TMPFILE >> $OUT 2>&1 || fail=1

-echo using resize2fs to test e2undo >> $OUT
-$RESIZE2FS -z $TDB_FILE.1 -b $TMPFILE >> $OUT 2>&1
+echo using tune2fs to test e2undo >> $OUT
+$TUNE2FS -z $TDB_FILE.1 -O 64bit $TMPFILE >> $OUT 2>&1
crc2=`$CRCSUM $TMPFILE`
-echo $CRCSUM after resize2fs $crc2 >> $OUT
+echo $CRCSUM after tune2fs $crc2 >> $OUT
features="$($DUMPE2FS -h $TMPFILE 2> /dev/null | grep 'Filesystem features:')"
if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${features}" | grep 64bit -c)" -lt 1 ]; then
echo "FS features: ${features}" >> $OUT
diff --git a/tests/u_revert_64bitmcsum_onefile/script b/tests/u_revert_64bitmcsum_onefile/script
index f1d7c2bc9d3f..ae80ecd5c3c6 100644
--- a/tests/u_revert_64bitmcsum_onefile/script
+++ b/tests/u_revert_64bitmcsum_onefile/script
@@ -1,7 +1,7 @@
test_description="convert fs to 64bit,metadata_csum and revert as one undo file"
-if test -x $RESIZE2FS_EXE -a -x $E2UNDO_EXE; then
+if test -x $E2UNDO_EXE; then

-TDB_FILE=${TMPDIR:-/tmp}/resize2fs-$(basename $TMPFILE).e2undo
+TDB_FILE=${TMPDIR:-/tmp}/tune2fs-$(basename $TMPFILE).e2undo
OUT=$test_name.log
rm -f $TDB_FILE >/dev/null 2>&1
fail=0
@@ -41,10 +41,10 @@ if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${f
fi
$FSCK -f -n $TMPFILE >> $OUT 2>&1 || fail=1

-echo using resize2fs to test e2undo >> $OUT
-$RESIZE2FS -z $TDB_FILE.1 -b $TMPFILE >> $OUT 2>&1
+echo using tune2fs to test e2undo >> $OUT
+$TUNE2FS -z $TDB_FILE.1 -O 64bit $TMPFILE >> $OUT 2>&1
crc2=`$CRCSUM $TMPFILE`
-echo $CRCSUM after resize2fs $crc2 >> $OUT
+echo $CRCSUM after tune2fs $crc2 >> $OUT
features="$($DUMPE2FS -h $TMPFILE 2> /dev/null | grep 'Filesystem features:')"
if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${features}" | grep 64bit -c)" -lt 1 ]; then
echo "FS features: ${features}" >> $OUT
diff --git a/tests/u_revert_all_onefile/script b/tests/u_revert_all_onefile/script
index 27b3b23557fa..c748b81ee275 100644
--- a/tests/u_revert_all_onefile/script
+++ b/tests/u_revert_all_onefile/script
@@ -1,7 +1,7 @@
test_description="convert fs to 64bit,metadata_csum and revert as one undo file"
-if test -x $RESIZE2FS_EXE -a -x $E2UNDO_EXE; then
+if test -x $E2UNDO_EXE; then

-TDB_FILE=${TMPDIR:-/tmp}/resize2fs-$(basename $TMPFILE).e2undo
+TDB_FILE=${TMPDIR:-/tmp}/tune2fs-$(basename $TMPFILE).e2undo
OUT=$test_name.log
rm -f $TDB_FILE >/dev/null 2>&1
fail=0
@@ -41,10 +41,10 @@ if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${f
fi
$FSCK -f -n $TMPFILE >> $OUT 2>&1 || fail=1

-echo using resize2fs to test e2undo >> $OUT
-$RESIZE2FS -z $TDB_FILE.0 -b $TMPFILE >> $OUT 2>&1
+echo using tune2fs to test e2undo >> $OUT
+$TUNE2FS -z $TDB_FILE.0 -O 64bit $TMPFILE >> $OUT 2>&1
crc2=`$CRCSUM $TMPFILE`
-echo $CRCSUM after resize2fs $crc2 >> $OUT
+echo $CRCSUM after tune2fs $crc2 >> $OUT
features="$($DUMPE2FS -h $TMPFILE 2> /dev/null | grep 'Filesystem features:')"
if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${features}" | grep 64bit -c)" -lt 1 ]; then
echo "FS features: ${features}" >> $OUT
diff --git a/tests/u_revert_upgrade_to_64bitmcsum/script b/tests/u_revert_upgrade_to_64bitmcsum/script
index 6120d00f6386..3e1817e32eb5 100644
--- a/tests/u_revert_upgrade_to_64bitmcsum/script
+++ b/tests/u_revert_upgrade_to_64bitmcsum/script
@@ -1,7 +1,7 @@
test_description="convert fs to 64bit,metadata_csum and revert both changes"
-if test -x $RESIZE2FS_EXE -a -x $E2UNDO_EXE; then
+if test -x $E2UNDO_EXE; then

-TDB_FILE=${TMPDIR:-/tmp}/resize2fs-$(basename $TMPFILE).e2undo
+TDB_FILE=${TMPDIR:-/tmp}/tune2fs-$(basename $TMPFILE).e2undo
OUT=$test_name.log
rm -f $TDB_FILE >/dev/null 2>&1
fail=0
@@ -41,10 +41,10 @@ if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${f
fi
$FSCK -f -n $TMPFILE >> $OUT 2>&1 || fail=1

-echo using resize2fs to test e2undo >> $OUT
-$RESIZE2FS -z $TDB_FILE.1 -b $TMPFILE >> $OUT 2>&1
+echo using tune2fs to test e2undo >> $OUT
+$TUNE2FS -z $TDB_FILE.1 -O 64bit $TMPFILE >> $OUT 2>&1
crc2=`$CRCSUM $TMPFILE`
-echo $CRCSUM after resize2fs $crc2 >> $OUT
+echo $CRCSUM after tune2fs $crc2 >> $OUT
features="$($DUMPE2FS -h $TMPFILE 2> /dev/null | grep 'Filesystem features:')"
if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${features}" | grep 64bit -c)" -lt 1 ]; then
echo "FS features: ${features}" >> $OUT
@@ -101,10 +101,10 @@ if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${f
fi
$FSCK -f -n $TMPFILE >> $OUT 2>&1 || fail=1

-echo roll back resize2fs >> $OUT
+echo roll back tune2fs >> $OUT
$E2UNDO $TDB_FILE.1 $TMPFILE >> $OUT 2>&1
crc1_2=`$CRCSUM $TMPFILE`
-echo $CRCSUM after e2undo resize2fs $crc1_2 >> $OUT
+echo $CRCSUM after e2undo tune2fs $crc1_2 >> $OUT
features="$($DUMPE2FS -h $TMPFILE 2> /dev/null | grep 'Filesystem features:')"
if [ "$(echo "${features}" | grep "metadata_csum" -c)" -gt 0 ] || [ "$(echo "${features}" | grep 64bit -c)" -gt 0 ]; then
echo "FS features: ${features}" >> $OUT
--
2.1.4


2015-08-26 16:22:57

by Jan Kara

[permalink] [raw]
Subject: [PATCH 14/21] mke2fs, tune2fs: Tests for handling reserved_inodes option

Signed-off-by: Jan Kara <[email protected]>
---
tests/m_reserved_inodes/expect.1 | 837 +++++++++++++++++++++++++++
tests/m_reserved_inodes/script | 7 +
tests/t_reserved_inodes_decrease/expect | 68 +++
tests/t_reserved_inodes_decrease/name | 1 +
tests/t_reserved_inodes_decrease/script | 71 +++
tests/t_reserved_inodes_increase/expect | 59 ++
tests/t_reserved_inodes_increase/name | 1 +
tests/t_reserved_inodes_increase/script | 71 +++
tests/t_reserved_inodes_increase_csum/expect | 60 ++
tests/t_reserved_inodes_increase_csum/name | 1 +
tests/t_reserved_inodes_increase_csum/script | 71 +++
11 files changed, 1247 insertions(+)
create mode 100644 tests/m_reserved_inodes/expect.1
create mode 100644 tests/m_reserved_inodes/script
create mode 100644 tests/t_reserved_inodes_decrease/expect
create mode 100644 tests/t_reserved_inodes_decrease/name
create mode 100644 tests/t_reserved_inodes_decrease/script
create mode 100644 tests/t_reserved_inodes_increase/expect
create mode 100644 tests/t_reserved_inodes_increase/name
create mode 100644 tests/t_reserved_inodes_increase/script
create mode 100644 tests/t_reserved_inodes_increase_csum/expect
create mode 100644 tests/t_reserved_inodes_increase_csum/name
create mode 100644 tests/t_reserved_inodes_increase_csum/script

diff --git a/tests/m_reserved_inodes/expect.1 b/tests/m_reserved_inodes/expect.1
new file mode 100644
index 000000000000..6cd183170b6e
--- /dev/null
+++ b/tests/m_reserved_inodes/expect.1
@@ -0,0 +1,837 @@
+Creating filesystem with 131072 1k blocks and 8192 inodes
+Superblock backups stored on blocks:
+ 1025, 3073, 5121, 7169, 9217, 25601, 27649, 50177, 82945, 128001
+
+Allocating group tables: done
+Writing inode tables: done
+Writing superblocks and filesystem accounting information: done
+
+Filesystem features: ext_attr resize_inode dir_index filetype sparse_super
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 78/8192 files (0.0% non-contiguous), 4166/131072 blocks
+Exit status is 0
+Filesystem volume name: <none>
+Last mounted on: <not available>
+Filesystem magic number: 0xEF53
+Filesystem revision #: 1 (dynamic)
+Filesystem features: ext_attr resize_inode dir_index filetype sparse_super
+Default mount options: (none)
+Filesystem state: clean
+Errors behavior: Continue
+Filesystem OS type: Linux
+Inode count: 8192
+Block count: 131072
+Reserved block count: 6553
+Free blocks: 126906
+Free inodes: 8114
+First block: 1
+Block size: 1024
+Fragment size: 1024
+Reserved GDT blocks: 256
+Blocks per group: 1024
+Fragments per group: 1024
+Inodes per group: 64
+Inode blocks per group: 8
+Mount count: 0
+Check interval: 15552000 (6 months)
+Reserved blocks uid: 0
+Reserved blocks gid: 0
+First inode: 78
+Inode size: 128
+Default directory hash: half_md4
+
+
+Group 0: (Blocks 1-1024)
+ Primary superblock at 1, Group descriptors at 2-5
+ Reserved GDT blocks at 6-261
+ Block bitmap at 262 (+261), Inode bitmap at 263 (+262)
+ Inode table at 264-271 (+263)
+ 751 free blocks, 0 free inodes, 1 directories
+ Free blocks: 274-1024
+ Free inodes:
+Group 1: (Blocks 1025-2048)
+ Backup superblock at 1025, Group descriptors at 1026-1029
+ Reserved GDT blocks at 1030-1285
+ Block bitmap at 1286 (+261), Inode bitmap at 1287 (+262)
+ Inode table at 1288-1295 (+263)
+ 741 free blocks, 50 free inodes, 1 directories
+ Free blocks: 1308-2048
+ Free inodes: 79-128
+Group 2: (Blocks 2049-3072)
+ Block bitmap at 2049 (+0), Inode bitmap at 2050 (+1)
+ Inode table at 2051-2058 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 2059-3072
+ Free inodes: 129-192
+Group 3: (Blocks 3073-4096)
+ Backup superblock at 3073, Group descriptors at 3074-3077
+ Reserved GDT blocks at 3078-3333
+ Block bitmap at 3334 (+261), Inode bitmap at 3335 (+262)
+ Inode table at 3336-3343 (+263)
+ 753 free blocks, 64 free inodes, 0 directories
+ Free blocks: 3344-4096
+ Free inodes: 193-256
+Group 4: (Blocks 4097-5120)
+ Block bitmap at 4097 (+0), Inode bitmap at 4098 (+1)
+ Inode table at 4099-4106 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 4107-5120
+ Free inodes: 257-320
+Group 5: (Blocks 5121-6144)
+ Backup superblock at 5121, Group descriptors at 5122-5125
+ Reserved GDT blocks at 5126-5381
+ Block bitmap at 5382 (+261), Inode bitmap at 5383 (+262)
+ Inode table at 5384-5391 (+263)
+ 753 free blocks, 64 free inodes, 0 directories
+ Free blocks: 5392-6144
+ Free inodes: 321-384
+Group 6: (Blocks 6145-7168)
+ Block bitmap at 6145 (+0), Inode bitmap at 6146 (+1)
+ Inode table at 6147-6154 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 6155-7168
+ Free inodes: 385-448
+Group 7: (Blocks 7169-8192)
+ Backup superblock at 7169, Group descriptors at 7170-7173
+ Reserved GDT blocks at 7174-7429
+ Block bitmap at 7430 (+261), Inode bitmap at 7431 (+262)
+ Inode table at 7432-7439 (+263)
+ 753 free blocks, 64 free inodes, 0 directories
+ Free blocks: 7440-8192
+ Free inodes: 449-512
+Group 8: (Blocks 8193-9216)
+ Block bitmap at 8193 (+0), Inode bitmap at 8194 (+1)
+ Inode table at 8195-8202 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 8203-9216
+ Free inodes: 513-576
+Group 9: (Blocks 9217-10240)
+ Backup superblock at 9217, Group descriptors at 9218-9221
+ Reserved GDT blocks at 9222-9477
+ Block bitmap at 9478 (+261), Inode bitmap at 9479 (+262)
+ Inode table at 9480-9487 (+263)
+ 753 free blocks, 64 free inodes, 0 directories
+ Free blocks: 9488-10240
+ Free inodes: 577-640
+Group 10: (Blocks 10241-11264)
+ Block bitmap at 10241 (+0), Inode bitmap at 10242 (+1)
+ Inode table at 10243-10250 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 10251-11264
+ Free inodes: 641-704
+Group 11: (Blocks 11265-12288)
+ Block bitmap at 11265 (+0), Inode bitmap at 11266 (+1)
+ Inode table at 11267-11274 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 11275-12288
+ Free inodes: 705-768
+Group 12: (Blocks 12289-13312)
+ Block bitmap at 12289 (+0), Inode bitmap at 12290 (+1)
+ Inode table at 12291-12298 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 12299-13312
+ Free inodes: 769-832
+Group 13: (Blocks 13313-14336)
+ Block bitmap at 13313 (+0), Inode bitmap at 13314 (+1)
+ Inode table at 13315-13322 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 13323-14336
+ Free inodes: 833-896
+Group 14: (Blocks 14337-15360)
+ Block bitmap at 14337 (+0), Inode bitmap at 14338 (+1)
+ Inode table at 14339-14346 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 14347-15360
+ Free inodes: 897-960
+Group 15: (Blocks 15361-16384)
+ Block bitmap at 15361 (+0), Inode bitmap at 15362 (+1)
+ Inode table at 15363-15370 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 15371-16384
+ Free inodes: 961-1024
+Group 16: (Blocks 16385-17408)
+ Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
+ Inode table at 16387-16394 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 16395-17408
+ Free inodes: 1025-1088
+Group 17: (Blocks 17409-18432)
+ Block bitmap at 17409 (+0), Inode bitmap at 17410 (+1)
+ Inode table at 17411-17418 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 17419-18432
+ Free inodes: 1089-1152
+Group 18: (Blocks 18433-19456)
+ Block bitmap at 18433 (+0), Inode bitmap at 18434 (+1)
+ Inode table at 18435-18442 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 18443-19456
+ Free inodes: 1153-1216
+Group 19: (Blocks 19457-20480)
+ Block bitmap at 19457 (+0), Inode bitmap at 19458 (+1)
+ Inode table at 19459-19466 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 19467-20480
+ Free inodes: 1217-1280
+Group 20: (Blocks 20481-21504)
+ Block bitmap at 20481 (+0), Inode bitmap at 20482 (+1)
+ Inode table at 20483-20490 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 20491-21504
+ Free inodes: 1281-1344
+Group 21: (Blocks 21505-22528)
+ Block bitmap at 21505 (+0), Inode bitmap at 21506 (+1)
+ Inode table at 21507-21514 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 21515-22528
+ Free inodes: 1345-1408
+Group 22: (Blocks 22529-23552)
+ Block bitmap at 22529 (+0), Inode bitmap at 22530 (+1)
+ Inode table at 22531-22538 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 22539-23552
+ Free inodes: 1409-1472
+Group 23: (Blocks 23553-24576)
+ Block bitmap at 23553 (+0), Inode bitmap at 23554 (+1)
+ Inode table at 23555-23562 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 23563-24576
+ Free inodes: 1473-1536
+Group 24: (Blocks 24577-25600)
+ Block bitmap at 24577 (+0), Inode bitmap at 24578 (+1)
+ Inode table at 24579-24586 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 24587-25600
+ Free inodes: 1537-1600
+Group 25: (Blocks 25601-26624)
+ Backup superblock at 25601, Group descriptors at 25602-25605
+ Reserved GDT blocks at 25606-25861
+ Block bitmap at 25862 (+261), Inode bitmap at 25863 (+262)
+ Inode table at 25864-25871 (+263)
+ 753 free blocks, 64 free inodes, 0 directories
+ Free blocks: 25872-26624
+ Free inodes: 1601-1664
+Group 26: (Blocks 26625-27648)
+ Block bitmap at 26625 (+0), Inode bitmap at 26626 (+1)
+ Inode table at 26627-26634 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 26635-27648
+ Free inodes: 1665-1728
+Group 27: (Blocks 27649-28672)
+ Backup superblock at 27649, Group descriptors at 27650-27653
+ Reserved GDT blocks at 27654-27909
+ Block bitmap at 27910 (+261), Inode bitmap at 27911 (+262)
+ Inode table at 27912-27919 (+263)
+ 753 free blocks, 64 free inodes, 0 directories
+ Free blocks: 27920-28672
+ Free inodes: 1729-1792
+Group 28: (Blocks 28673-29696)
+ Block bitmap at 28673 (+0), Inode bitmap at 28674 (+1)
+ Inode table at 28675-28682 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 28683-29696
+ Free inodes: 1793-1856
+Group 29: (Blocks 29697-30720)
+ Block bitmap at 29697 (+0), Inode bitmap at 29698 (+1)
+ Inode table at 29699-29706 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 29707-30720
+ Free inodes: 1857-1920
+Group 30: (Blocks 30721-31744)
+ Block bitmap at 30721 (+0), Inode bitmap at 30722 (+1)
+ Inode table at 30723-30730 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 30731-31744
+ Free inodes: 1921-1984
+Group 31: (Blocks 31745-32768)
+ Block bitmap at 31745 (+0), Inode bitmap at 31746 (+1)
+ Inode table at 31747-31754 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 31755-32768
+ Free inodes: 1985-2048
+Group 32: (Blocks 32769-33792)
+ Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
+ Inode table at 32771-32778 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 32779-33792
+ Free inodes: 2049-2112
+Group 33: (Blocks 33793-34816)
+ Block bitmap at 33793 (+0), Inode bitmap at 33794 (+1)
+ Inode table at 33795-33802 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 33803-34816
+ Free inodes: 2113-2176
+Group 34: (Blocks 34817-35840)
+ Block bitmap at 34817 (+0), Inode bitmap at 34818 (+1)
+ Inode table at 34819-34826 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 34827-35840
+ Free inodes: 2177-2240
+Group 35: (Blocks 35841-36864)
+ Block bitmap at 35841 (+0), Inode bitmap at 35842 (+1)
+ Inode table at 35843-35850 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 35851-36864
+ Free inodes: 2241-2304
+Group 36: (Blocks 36865-37888)
+ Block bitmap at 36865 (+0), Inode bitmap at 36866 (+1)
+ Inode table at 36867-36874 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 36875-37888
+ Free inodes: 2305-2368
+Group 37: (Blocks 37889-38912)
+ Block bitmap at 37889 (+0), Inode bitmap at 37890 (+1)
+ Inode table at 37891-37898 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 37899-38912
+ Free inodes: 2369-2432
+Group 38: (Blocks 38913-39936)
+ Block bitmap at 38913 (+0), Inode bitmap at 38914 (+1)
+ Inode table at 38915-38922 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 38923-39936
+ Free inodes: 2433-2496
+Group 39: (Blocks 39937-40960)
+ Block bitmap at 39937 (+0), Inode bitmap at 39938 (+1)
+ Inode table at 39939-39946 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 39947-40960
+ Free inodes: 2497-2560
+Group 40: (Blocks 40961-41984)
+ Block bitmap at 40961 (+0), Inode bitmap at 40962 (+1)
+ Inode table at 40963-40970 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 40971-41984
+ Free inodes: 2561-2624
+Group 41: (Blocks 41985-43008)
+ Block bitmap at 41985 (+0), Inode bitmap at 41986 (+1)
+ Inode table at 41987-41994 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 41995-43008
+ Free inodes: 2625-2688
+Group 42: (Blocks 43009-44032)
+ Block bitmap at 43009 (+0), Inode bitmap at 43010 (+1)
+ Inode table at 43011-43018 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 43019-44032
+ Free inodes: 2689-2752
+Group 43: (Blocks 44033-45056)
+ Block bitmap at 44033 (+0), Inode bitmap at 44034 (+1)
+ Inode table at 44035-44042 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 44043-45056
+ Free inodes: 2753-2816
+Group 44: (Blocks 45057-46080)
+ Block bitmap at 45057 (+0), Inode bitmap at 45058 (+1)
+ Inode table at 45059-45066 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 45067-46080
+ Free inodes: 2817-2880
+Group 45: (Blocks 46081-47104)
+ Block bitmap at 46081 (+0), Inode bitmap at 46082 (+1)
+ Inode table at 46083-46090 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 46091-47104
+ Free inodes: 2881-2944
+Group 46: (Blocks 47105-48128)
+ Block bitmap at 47105 (+0), Inode bitmap at 47106 (+1)
+ Inode table at 47107-47114 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 47115-48128
+ Free inodes: 2945-3008
+Group 47: (Blocks 48129-49152)
+ Block bitmap at 48129 (+0), Inode bitmap at 48130 (+1)
+ Inode table at 48131-48138 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 48139-49152
+ Free inodes: 3009-3072
+Group 48: (Blocks 49153-50176)
+ Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
+ Inode table at 49155-49162 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 49163-50176
+ Free inodes: 3073-3136
+Group 49: (Blocks 50177-51200)
+ Backup superblock at 50177, Group descriptors at 50178-50181
+ Reserved GDT blocks at 50182-50437
+ Block bitmap at 50438 (+261), Inode bitmap at 50439 (+262)
+ Inode table at 50440-50447 (+263)
+ 753 free blocks, 64 free inodes, 0 directories
+ Free blocks: 50448-51200
+ Free inodes: 3137-3200
+Group 50: (Blocks 51201-52224)
+ Block bitmap at 51201 (+0), Inode bitmap at 51202 (+1)
+ Inode table at 51203-51210 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 51211-52224
+ Free inodes: 3201-3264
+Group 51: (Blocks 52225-53248)
+ Block bitmap at 52225 (+0), Inode bitmap at 52226 (+1)
+ Inode table at 52227-52234 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 52235-53248
+ Free inodes: 3265-3328
+Group 52: (Blocks 53249-54272)
+ Block bitmap at 53249 (+0), Inode bitmap at 53250 (+1)
+ Inode table at 53251-53258 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 53259-54272
+ Free inodes: 3329-3392
+Group 53: (Blocks 54273-55296)
+ Block bitmap at 54273 (+0), Inode bitmap at 54274 (+1)
+ Inode table at 54275-54282 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 54283-55296
+ Free inodes: 3393-3456
+Group 54: (Blocks 55297-56320)
+ Block bitmap at 55297 (+0), Inode bitmap at 55298 (+1)
+ Inode table at 55299-55306 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 55307-56320
+ Free inodes: 3457-3520
+Group 55: (Blocks 56321-57344)
+ Block bitmap at 56321 (+0), Inode bitmap at 56322 (+1)
+ Inode table at 56323-56330 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 56331-57344
+ Free inodes: 3521-3584
+Group 56: (Blocks 57345-58368)
+ Block bitmap at 57345 (+0), Inode bitmap at 57346 (+1)
+ Inode table at 57347-57354 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 57355-58368
+ Free inodes: 3585-3648
+Group 57: (Blocks 58369-59392)
+ Block bitmap at 58369 (+0), Inode bitmap at 58370 (+1)
+ Inode table at 58371-58378 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 58379-59392
+ Free inodes: 3649-3712
+Group 58: (Blocks 59393-60416)
+ Block bitmap at 59393 (+0), Inode bitmap at 59394 (+1)
+ Inode table at 59395-59402 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 59403-60416
+ Free inodes: 3713-3776
+Group 59: (Blocks 60417-61440)
+ Block bitmap at 60417 (+0), Inode bitmap at 60418 (+1)
+ Inode table at 60419-60426 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 60427-61440
+ Free inodes: 3777-3840
+Group 60: (Blocks 61441-62464)
+ Block bitmap at 61441 (+0), Inode bitmap at 61442 (+1)
+ Inode table at 61443-61450 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 61451-62464
+ Free inodes: 3841-3904
+Group 61: (Blocks 62465-63488)
+ Block bitmap at 62465 (+0), Inode bitmap at 62466 (+1)
+ Inode table at 62467-62474 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 62475-63488
+ Free inodes: 3905-3968
+Group 62: (Blocks 63489-64512)
+ Block bitmap at 63489 (+0), Inode bitmap at 63490 (+1)
+ Inode table at 63491-63498 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 63499-64512
+ Free inodes: 3969-4032
+Group 63: (Blocks 64513-65536)
+ Block bitmap at 64513 (+0), Inode bitmap at 64514 (+1)
+ Inode table at 64515-64522 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 64523-65536
+ Free inodes: 4033-4096
+Group 64: (Blocks 65537-66560)
+ Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
+ Inode table at 65539-65546 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 65547-66560
+ Free inodes: 4097-4160
+Group 65: (Blocks 66561-67584)
+ Block bitmap at 66561 (+0), Inode bitmap at 66562 (+1)
+ Inode table at 66563-66570 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 66571-67584
+ Free inodes: 4161-4224
+Group 66: (Blocks 67585-68608)
+ Block bitmap at 67585 (+0), Inode bitmap at 67586 (+1)
+ Inode table at 67587-67594 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 67595-68608
+ Free inodes: 4225-4288
+Group 67: (Blocks 68609-69632)
+ Block bitmap at 68609 (+0), Inode bitmap at 68610 (+1)
+ Inode table at 68611-68618 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 68619-69632
+ Free inodes: 4289-4352
+Group 68: (Blocks 69633-70656)
+ Block bitmap at 69633 (+0), Inode bitmap at 69634 (+1)
+ Inode table at 69635-69642 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 69643-70656
+ Free inodes: 4353-4416
+Group 69: (Blocks 70657-71680)
+ Block bitmap at 70657 (+0), Inode bitmap at 70658 (+1)
+ Inode table at 70659-70666 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 70667-71680
+ Free inodes: 4417-4480
+Group 70: (Blocks 71681-72704)
+ Block bitmap at 71681 (+0), Inode bitmap at 71682 (+1)
+ Inode table at 71683-71690 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 71691-72704
+ Free inodes: 4481-4544
+Group 71: (Blocks 72705-73728)
+ Block bitmap at 72705 (+0), Inode bitmap at 72706 (+1)
+ Inode table at 72707-72714 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 72715-73728
+ Free inodes: 4545-4608
+Group 72: (Blocks 73729-74752)
+ Block bitmap at 73729 (+0), Inode bitmap at 73730 (+1)
+ Inode table at 73731-73738 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 73739-74752
+ Free inodes: 4609-4672
+Group 73: (Blocks 74753-75776)
+ Block bitmap at 74753 (+0), Inode bitmap at 74754 (+1)
+ Inode table at 74755-74762 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 74763-75776
+ Free inodes: 4673-4736
+Group 74: (Blocks 75777-76800)
+ Block bitmap at 75777 (+0), Inode bitmap at 75778 (+1)
+ Inode table at 75779-75786 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 75787-76800
+ Free inodes: 4737-4800
+Group 75: (Blocks 76801-77824)
+ Block bitmap at 76801 (+0), Inode bitmap at 76802 (+1)
+ Inode table at 76803-76810 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 76811-77824
+ Free inodes: 4801-4864
+Group 76: (Blocks 77825-78848)
+ Block bitmap at 77825 (+0), Inode bitmap at 77826 (+1)
+ Inode table at 77827-77834 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 77835-78848
+ Free inodes: 4865-4928
+Group 77: (Blocks 78849-79872)
+ Block bitmap at 78849 (+0), Inode bitmap at 78850 (+1)
+ Inode table at 78851-78858 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 78859-79872
+ Free inodes: 4929-4992
+Group 78: (Blocks 79873-80896)
+ Block bitmap at 79873 (+0), Inode bitmap at 79874 (+1)
+ Inode table at 79875-79882 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 79883-80896
+ Free inodes: 4993-5056
+Group 79: (Blocks 80897-81920)
+ Block bitmap at 80897 (+0), Inode bitmap at 80898 (+1)
+ Inode table at 80899-80906 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 80907-81920
+ Free inodes: 5057-5120
+Group 80: (Blocks 81921-82944)
+ Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
+ Inode table at 81923-81930 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 81931-82944
+ Free inodes: 5121-5184
+Group 81: (Blocks 82945-83968)
+ Backup superblock at 82945, Group descriptors at 82946-82949
+ Reserved GDT blocks at 82950-83205
+ Block bitmap at 83206 (+261), Inode bitmap at 83207 (+262)
+ Inode table at 83208-83215 (+263)
+ 753 free blocks, 64 free inodes, 0 directories
+ Free blocks: 83216-83968
+ Free inodes: 5185-5248
+Group 82: (Blocks 83969-84992)
+ Block bitmap at 83969 (+0), Inode bitmap at 83970 (+1)
+ Inode table at 83971-83978 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 83979-84992
+ Free inodes: 5249-5312
+Group 83: (Blocks 84993-86016)
+ Block bitmap at 84993 (+0), Inode bitmap at 84994 (+1)
+ Inode table at 84995-85002 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 85003-86016
+ Free inodes: 5313-5376
+Group 84: (Blocks 86017-87040)
+ Block bitmap at 86017 (+0), Inode bitmap at 86018 (+1)
+ Inode table at 86019-86026 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 86027-87040
+ Free inodes: 5377-5440
+Group 85: (Blocks 87041-88064)
+ Block bitmap at 87041 (+0), Inode bitmap at 87042 (+1)
+ Inode table at 87043-87050 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 87051-88064
+ Free inodes: 5441-5504
+Group 86: (Blocks 88065-89088)
+ Block bitmap at 88065 (+0), Inode bitmap at 88066 (+1)
+ Inode table at 88067-88074 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 88075-89088
+ Free inodes: 5505-5568
+Group 87: (Blocks 89089-90112)
+ Block bitmap at 89089 (+0), Inode bitmap at 89090 (+1)
+ Inode table at 89091-89098 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 89099-90112
+ Free inodes: 5569-5632
+Group 88: (Blocks 90113-91136)
+ Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
+ Inode table at 90115-90122 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 90123-91136
+ Free inodes: 5633-5696
+Group 89: (Blocks 91137-92160)
+ Block bitmap at 91137 (+0), Inode bitmap at 91138 (+1)
+ Inode table at 91139-91146 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 91147-92160
+ Free inodes: 5697-5760
+Group 90: (Blocks 92161-93184)
+ Block bitmap at 92161 (+0), Inode bitmap at 92162 (+1)
+ Inode table at 92163-92170 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 92171-93184
+ Free inodes: 5761-5824
+Group 91: (Blocks 93185-94208)
+ Block bitmap at 93185 (+0), Inode bitmap at 93186 (+1)
+ Inode table at 93187-93194 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 93195-94208
+ Free inodes: 5825-5888
+Group 92: (Blocks 94209-95232)
+ Block bitmap at 94209 (+0), Inode bitmap at 94210 (+1)
+ Inode table at 94211-94218 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 94219-95232
+ Free inodes: 5889-5952
+Group 93: (Blocks 95233-96256)
+ Block bitmap at 95233 (+0), Inode bitmap at 95234 (+1)
+ Inode table at 95235-95242 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 95243-96256
+ Free inodes: 5953-6016
+Group 94: (Blocks 96257-97280)
+ Block bitmap at 96257 (+0), Inode bitmap at 96258 (+1)
+ Inode table at 96259-96266 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 96267-97280
+ Free inodes: 6017-6080
+Group 95: (Blocks 97281-98304)
+ Block bitmap at 97281 (+0), Inode bitmap at 97282 (+1)
+ Inode table at 97283-97290 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 97291-98304
+ Free inodes: 6081-6144
+Group 96: (Blocks 98305-99328)
+ Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
+ Inode table at 98307-98314 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 98315-99328
+ Free inodes: 6145-6208
+Group 97: (Blocks 99329-100352)
+ Block bitmap at 99329 (+0), Inode bitmap at 99330 (+1)
+ Inode table at 99331-99338 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 99339-100352
+ Free inodes: 6209-6272
+Group 98: (Blocks 100353-101376)
+ Block bitmap at 100353 (+0), Inode bitmap at 100354 (+1)
+ Inode table at 100355-100362 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 100363-101376
+ Free inodes: 6273-6336
+Group 99: (Blocks 101377-102400)
+ Block bitmap at 101377 (+0), Inode bitmap at 101378 (+1)
+ Inode table at 101379-101386 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 101387-102400
+ Free inodes: 6337-6400
+Group 100: (Blocks 102401-103424)
+ Block bitmap at 102401 (+0), Inode bitmap at 102402 (+1)
+ Inode table at 102403-102410 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 102411-103424
+ Free inodes: 6401-6464
+Group 101: (Blocks 103425-104448)
+ Block bitmap at 103425 (+0), Inode bitmap at 103426 (+1)
+ Inode table at 103427-103434 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 103435-104448
+ Free inodes: 6465-6528
+Group 102: (Blocks 104449-105472)
+ Block bitmap at 104449 (+0), Inode bitmap at 104450 (+1)
+ Inode table at 104451-104458 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 104459-105472
+ Free inodes: 6529-6592
+Group 103: (Blocks 105473-106496)
+ Block bitmap at 105473 (+0), Inode bitmap at 105474 (+1)
+ Inode table at 105475-105482 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 105483-106496
+ Free inodes: 6593-6656
+Group 104: (Blocks 106497-107520)
+ Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
+ Inode table at 106499-106506 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 106507-107520
+ Free inodes: 6657-6720
+Group 105: (Blocks 107521-108544)
+ Block bitmap at 107521 (+0), Inode bitmap at 107522 (+1)
+ Inode table at 107523-107530 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 107531-108544
+ Free inodes: 6721-6784
+Group 106: (Blocks 108545-109568)
+ Block bitmap at 108545 (+0), Inode bitmap at 108546 (+1)
+ Inode table at 108547-108554 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 108555-109568
+ Free inodes: 6785-6848
+Group 107: (Blocks 109569-110592)
+ Block bitmap at 109569 (+0), Inode bitmap at 109570 (+1)
+ Inode table at 109571-109578 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 109579-110592
+ Free inodes: 6849-6912
+Group 108: (Blocks 110593-111616)
+ Block bitmap at 110593 (+0), Inode bitmap at 110594 (+1)
+ Inode table at 110595-110602 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 110603-111616
+ Free inodes: 6913-6976
+Group 109: (Blocks 111617-112640)
+ Block bitmap at 111617 (+0), Inode bitmap at 111618 (+1)
+ Inode table at 111619-111626 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 111627-112640
+ Free inodes: 6977-7040
+Group 110: (Blocks 112641-113664)
+ Block bitmap at 112641 (+0), Inode bitmap at 112642 (+1)
+ Inode table at 112643-112650 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 112651-113664
+ Free inodes: 7041-7104
+Group 111: (Blocks 113665-114688)
+ Block bitmap at 113665 (+0), Inode bitmap at 113666 (+1)
+ Inode table at 113667-113674 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 113675-114688
+ Free inodes: 7105-7168
+Group 112: (Blocks 114689-115712)
+ Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
+ Inode table at 114691-114698 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 114699-115712
+ Free inodes: 7169-7232
+Group 113: (Blocks 115713-116736)
+ Block bitmap at 115713 (+0), Inode bitmap at 115714 (+1)
+ Inode table at 115715-115722 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 115723-116736
+ Free inodes: 7233-7296
+Group 114: (Blocks 116737-117760)
+ Block bitmap at 116737 (+0), Inode bitmap at 116738 (+1)
+ Inode table at 116739-116746 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 116747-117760
+ Free inodes: 7297-7360
+Group 115: (Blocks 117761-118784)
+ Block bitmap at 117761 (+0), Inode bitmap at 117762 (+1)
+ Inode table at 117763-117770 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 117771-118784
+ Free inodes: 7361-7424
+Group 116: (Blocks 118785-119808)
+ Block bitmap at 118785 (+0), Inode bitmap at 118786 (+1)
+ Inode table at 118787-118794 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 118795-119808
+ Free inodes: 7425-7488
+Group 117: (Blocks 119809-120832)
+ Block bitmap at 119809 (+0), Inode bitmap at 119810 (+1)
+ Inode table at 119811-119818 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 119819-120832
+ Free inodes: 7489-7552
+Group 118: (Blocks 120833-121856)
+ Block bitmap at 120833 (+0), Inode bitmap at 120834 (+1)
+ Inode table at 120835-120842 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 120843-121856
+ Free inodes: 7553-7616
+Group 119: (Blocks 121857-122880)
+ Block bitmap at 121857 (+0), Inode bitmap at 121858 (+1)
+ Inode table at 121859-121866 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 121867-122880
+ Free inodes: 7617-7680
+Group 120: (Blocks 122881-123904)
+ Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
+ Inode table at 122883-122890 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 122891-123904
+ Free inodes: 7681-7744
+Group 121: (Blocks 123905-124928)
+ Block bitmap at 123905 (+0), Inode bitmap at 123906 (+1)
+ Inode table at 123907-123914 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 123915-124928
+ Free inodes: 7745-7808
+Group 122: (Blocks 124929-125952)
+ Block bitmap at 124929 (+0), Inode bitmap at 124930 (+1)
+ Inode table at 124931-124938 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 124939-125952
+ Free inodes: 7809-7872
+Group 123: (Blocks 125953-126976)
+ Block bitmap at 125953 (+0), Inode bitmap at 125954 (+1)
+ Inode table at 125955-125962 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 125963-126976
+ Free inodes: 7873-7936
+Group 124: (Blocks 126977-128000)
+ Block bitmap at 126977 (+0), Inode bitmap at 126978 (+1)
+ Inode table at 126979-126986 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 126987-128000
+ Free inodes: 7937-8000
+Group 125: (Blocks 128001-129024)
+ Backup superblock at 128001, Group descriptors at 128002-128005
+ Reserved GDT blocks at 128006-128261
+ Block bitmap at 128262 (+261), Inode bitmap at 128263 (+262)
+ Inode table at 128264-128271 (+263)
+ 753 free blocks, 64 free inodes, 0 directories
+ Free blocks: 128272-129024
+ Free inodes: 8001-8064
+Group 126: (Blocks 129025-130048)
+ Block bitmap at 129025 (+0), Inode bitmap at 129026 (+1)
+ Inode table at 129027-129034 (+2)
+ 1014 free blocks, 64 free inodes, 0 directories
+ Free blocks: 129035-130048
+ Free inodes: 8065-8128
+Group 127: (Blocks 130049-131071)
+ Block bitmap at 130049 (+0), Inode bitmap at 130050 (+1)
+ Inode table at 130051-130058 (+2)
+ 1013 free blocks, 64 free inodes, 0 directories
+ Free blocks: 130059-131071
+ Free inodes: 8129-8192
diff --git a/tests/m_reserved_inodes/script b/tests/m_reserved_inodes/script
new file mode 100644
index 000000000000..070c08a07d6f
--- /dev/null
+++ b/tests/m_reserved_inodes/script
@@ -0,0 +1,7 @@
+DESCRIPTION="set number of reserved inodes on mkfs"
+FS_SIZE=131072
+DUMPE2FS_IGNORE_80COL=1
+export DUMPE2FS_IGNORE_80COL
+MKE2FS_OPTS="-b 1024 -g 1024 -N 8192 -E reserved_inodes=77"
+. $cmd_dir/run_mke2fs
+unset DUMPE2FS_IGNORE_80COL
diff --git a/tests/t_reserved_inodes_decrease/expect b/tests/t_reserved_inodes_decrease/expect
new file mode 100644
index 000000000000..fe6ace681018
--- /dev/null
+++ b/tests/t_reserved_inodes_decrease/expect
@@ -0,0 +1,68 @@
+tune2fs reserved_inodes decreasing test
+Creating filesystem with 524288 1k blocks and 65536 inodes
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Creating 477 huge file(s) with 1024 blocks each: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
+tune2fs -E reserved_inodes=64 test.img
+Exit status is 0
+
+Change in FS metadata:
+@@ -11,7 +11,7 @@
+ Block count: 524288
+ Reserved block count: 26214
+ Free blocks: 588
+-Free inodes: 64929
++Free inodes: 64993
+ First block: 1
+ Block size: 1024
+ Fragment size: 1024
+@@ -25,7 +25,7 @@
+ Check interval: 0 (<none>)
+ Reserved blocks uid: 0
+ Reserved blocks gid: 0
+-First inode: 129
++First inode: 65
+ Inode size: 256
+ Required extra isize: 28
+ Desired extra isize: 28
+@@ -45,7 +45,7 @@
+ Block bitmap at 260 (+259)
+ Inode bitmap at 276 (+275)
+ Inode table at 292-547 (+291)
+- 21 free blocks, 417 free inodes, 3 directories, 417 unused inodes
++ 21 free blocks, 481 free inodes, 3 directories, 417 unused inodes
+ Free blocks: 4412-4432
+ Free inodes: 608-1024
+ Group 1: (Blocks 8193-16384) [INODE_UNINIT]
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+Inode bitmap differences: -(65--128)
+Fix? no
+
+Free inodes count wrong for group #0 (481, counted=417).
+Fix? no
+
+Free inodes count wrong (64993, counted=64929).
+Fix? no
+
+
+
+
+
+Exit status is 4
diff --git a/tests/t_reserved_inodes_decrease/name b/tests/t_reserved_inodes_decrease/name
new file mode 100644
index 000000000000..8f9e66179e4a
--- /dev/null
+++ b/tests/t_reserved_inodes_decrease/name
@@ -0,0 +1 @@
+test decreasing number of reserved inodes
diff --git a/tests/t_reserved_inodes_decrease/script b/tests/t_reserved_inodes_decrease/script
new file mode 100644
index 000000000000..0e91558ed612
--- /dev/null
+++ b/tests/t_reserved_inodes_decrease/script
@@ -0,0 +1,71 @@
+FSCK_OPT=-fn
+OUT=$test_name.log
+EXP=$test_dir/expect
+CONF=$TMPFILE.conf
+
+cat > $CONF << ENDL
+[fs_types]
+ ext4h = {
+ features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,resize_inode
+ options = reserved_inodes=128
+ blocksize = 1024
+ inode_size = 256
+ make_hugefiles = true
+ hugefiles_dir = /xyz
+ hugefiles_slack = 0
+ hugefiles_name = aaaaa
+ hugefiles_digits = 4
+ hugefiles_size = 1M
+ zero_hugefiles = false
+ }
+ENDL
+
+echo "tune2fs reserved_inodes decreasing test" > $OUT
+
+MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
+rm -rf $CONF
+
+# dump and check
+$DUMPE2FS $TMPFILE 2> /dev/null | grep '^Group 0:' -B99 -A20 | sed -f $cmd_dir/filter.sed > $OUT.before
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# increase number of reserved inodes
+echo "tune2fs -E reserved_inodes=64 test.img" >> $OUT
+$TUNE2FS -E reserved_inodes=64 $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# check
+$FSCK -yD -N test_filesys $TMPFILE >> $OUT 2>&1
+
+# dump and check
+$DUMPE2FS $TMPFILE 2> /dev/null | grep '^Group 0:' -B99 -A20 | sed -f $cmd_dir/filter.sed > $OUT.after
+echo "Change in FS metadata:" >> $OUT
+diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+rm $TMPFILE $OUT.before $OUT.after
+
+#
+# Do the verification
+#
+
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
+mv $OUT.new $OUT
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+unset IMAGE FSCK_OPT OUT EXP CONF
diff --git a/tests/t_reserved_inodes_increase/expect b/tests/t_reserved_inodes_increase/expect
new file mode 100644
index 000000000000..1e15df1b1a23
--- /dev/null
+++ b/tests/t_reserved_inodes_increase/expect
@@ -0,0 +1,59 @@
+tune2fs reserved_inodes increasing test
+Creating filesystem with 524288 1k blocks and 65536 inodes
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Creating 477 huge file(s) with 1024 blocks each: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
+tune2fs -E reserved_inodes=128 test.img
+Exit status is 0
+
+Change in FS metadata:
+@@ -11,7 +11,7 @@
+ Block count: 524288
+ Reserved block count: 26214
+ Free blocks: 588
+-Free inodes: 64993
++Free inodes: 64929
+ First block: 1
+ Block size: 1024
+ Fragment size: 1024
+@@ -25,7 +25,7 @@
+ Check interval: 0 (<none>)
+ Reserved blocks uid: 0
+ Reserved blocks gid: 0
+-First inode: 65
++First inode: 129
+ Inode size: 256
+ Required extra isize: 28
+ Desired extra isize: 28
+@@ -45,9 +45,9 @@
+ Block bitmap at 260 (+259)
+ Inode bitmap at 276 (+275)
+ Inode table at 292-547 (+291)
+- 21 free blocks, 481 free inodes, 3 directories, 481 unused inodes
++ 21 free blocks, 417 free inodes, 3 directories, 417 unused inodes
+ Free blocks: 4412-4432
+- Free inodes: 544-1024
++ Free inodes: 608-1024
+ Group 1: (Blocks 8193-16384) [INODE_UNINIT]
+ Backup superblock at 8193, Group descriptors at 8194-8195
+ Reserved GDT blocks at 8196-8451
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
diff --git a/tests/t_reserved_inodes_increase/name b/tests/t_reserved_inodes_increase/name
new file mode 100644
index 000000000000..66fa663cce18
--- /dev/null
+++ b/tests/t_reserved_inodes_increase/name
@@ -0,0 +1 @@
+test increasing number of reserved inodes
diff --git a/tests/t_reserved_inodes_increase/script b/tests/t_reserved_inodes_increase/script
new file mode 100644
index 000000000000..e75baa2a06fd
--- /dev/null
+++ b/tests/t_reserved_inodes_increase/script
@@ -0,0 +1,71 @@
+FSCK_OPT=-fn
+OUT=$test_name.log
+EXP=$test_dir/expect
+CONF=$TMPFILE.conf
+
+cat > $CONF << ENDL
+[fs_types]
+ ext4h = {
+ features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,resize_inode
+ options = reserved_inodes=64
+ blocksize = 1024
+ inode_size = 256
+ make_hugefiles = true
+ hugefiles_dir = /xyz
+ hugefiles_slack = 0
+ hugefiles_name = aaaaa
+ hugefiles_digits = 4
+ hugefiles_size = 1M
+ zero_hugefiles = false
+ }
+ENDL
+
+echo "tune2fs reserved_inodes increasing test" > $OUT
+
+MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
+rm -rf $CONF
+
+# dump and check
+$DUMPE2FS $TMPFILE 2> /dev/null | grep '^Group 0:' -B99 -A20 | sed -f $cmd_dir/filter.sed > $OUT.before
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# increase number of reserved inodes
+echo "tune2fs -E reserved_inodes=128 test.img" >> $OUT
+$TUNE2FS -E reserved_inodes=128 $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# check
+$FSCK -yD -N test_filesys $TMPFILE >> $OUT 2>&1
+
+# dump and check
+$DUMPE2FS $TMPFILE 2> /dev/null | grep '^Group 0:' -B99 -A20 | sed -f $cmd_dir/filter.sed > $OUT.after
+echo "Change in FS metadata:" >> $OUT
+diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+rm $TMPFILE $OUT.before $OUT.after
+
+#
+# Do the verification
+#
+
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
+mv $OUT.new $OUT
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+unset IMAGE FSCK_OPT OUT EXP CONF
diff --git a/tests/t_reserved_inodes_increase_csum/expect b/tests/t_reserved_inodes_increase_csum/expect
new file mode 100644
index 000000000000..2b18f8ddc3fd
--- /dev/null
+++ b/tests/t_reserved_inodes_increase_csum/expect
@@ -0,0 +1,60 @@
+tune2fs reserved_inodes increasing test
+64-bit filesystem support is not enabled. The larger fields afforded by this feature enable full-strength checksumming. Pass -O 64bit to rectify.
+Creating filesystem with 524288 1k blocks and 65536 inodes
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Creating 477 huge file(s) with 1024 blocks each: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
+tune2fs -E reserved_inodes=128 test.img
+Exit status is 0
+
+Change in FS metadata:
+@@ -11,7 +11,7 @@
+ Block count: 524288
+ Reserved block count: 26214
+ Free blocks: 588
+-Free inodes: 64993
++Free inodes: 64929
+ First block: 1
+ Block size: 1024
+ Fragment size: 1024
+@@ -25,7 +25,7 @@
+ Check interval: 0 (<none>)
+ Reserved blocks uid: 0
+ Reserved blocks gid: 0
+-First inode: 65
++First inode: 129
+ Inode size: 256
+ Required extra isize: 28
+ Desired extra isize: 28
+@@ -46,9 +46,9 @@
+ Block bitmap at 260 (+259)
+ Inode bitmap at 276 (+275)
+ Inode table at 292-547 (+291)
+- 21 free blocks, 481 free inodes, 3 directories, 481 unused inodes
++ 21 free blocks, 417 free inodes, 3 directories, 417 unused inodes
+ Free blocks: 4412-4432
+- Free inodes: 544-1024
++ Free inodes: 608-1024
+ Group 1: (Blocks 8193-16384) [INODE_UNINIT]
+ Backup superblock at 8193, Group descriptors at 8194-8195
+ Reserved GDT blocks at 8196-8451
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+Exit status is 0
diff --git a/tests/t_reserved_inodes_increase_csum/name b/tests/t_reserved_inodes_increase_csum/name
new file mode 100644
index 000000000000..f9da1331a093
--- /dev/null
+++ b/tests/t_reserved_inodes_increase_csum/name
@@ -0,0 +1 @@
+test increasing number of reserved inodes on fs with metadata_csum
diff --git a/tests/t_reserved_inodes_increase_csum/script b/tests/t_reserved_inodes_increase_csum/script
new file mode 100644
index 000000000000..a4dbe369e4c6
--- /dev/null
+++ b/tests/t_reserved_inodes_increase_csum/script
@@ -0,0 +1,71 @@
+FSCK_OPT=-fn
+OUT=$test_name.log
+EXP=$test_dir/expect
+CONF=$TMPFILE.conf
+
+cat > $CONF << ENDL
+[fs_types]
+ ext4h = {
+ features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,sparse_super,filetype,dir_index,ext_attr,resize_inode,metadata_csum
+ options = reserved_inodes=64
+ blocksize = 1024
+ inode_size = 256
+ make_hugefiles = true
+ hugefiles_dir = /xyz
+ hugefiles_slack = 0
+ hugefiles_name = aaaaa
+ hugefiles_digits = 4
+ hugefiles_size = 1M
+ zero_hugefiles = false
+ }
+ENDL
+
+echo "tune2fs reserved_inodes increasing test" > $OUT
+
+MKE2FS_CONFIG=$CONF $MKE2FS -F -T ext4h $TMPFILE 524288 >> $OUT 2>&1
+rm -rf $CONF
+
+# dump and check
+$DUMPE2FS $TMPFILE 2> /dev/null | grep '^Group 0:' -B99 -A20 | sed -f $cmd_dir/filter.sed > $OUT.before
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# increase number of reserved inodes
+echo "tune2fs -E reserved_inodes=128 test.img" >> $OUT
+$TUNE2FS -E reserved_inodes=128 $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+# check
+$FSCK -yD -N test_filesys $TMPFILE >> $OUT 2>&1
+
+# dump and check
+$DUMPE2FS $TMPFILE 2> /dev/null | grep '^Group 0:' -B99 -A20 | sed -f $cmd_dir/filter.sed > $OUT.after
+echo "Change in FS metadata:" >> $OUT
+diff -u $OUT.before $OUT.after | tail -n +3 >> $OUT
+$FSCK $FSCK_OPT -N test_filesys $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+rm $TMPFILE $OUT.before $OUT.after
+
+#
+# Do the verification
+#
+
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" -e 's/test_filesys:.*//g' < $OUT > $OUT.new
+mv $OUT.new $OUT
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+fi
+
+unset IMAGE FSCK_OPT OUT EXP CONF
--
2.1.4


2015-08-26 16:22:57

by Jan Kara

[permalink] [raw]
Subject: [PATCH 12/21] libext2fs: Bump default number of reserved inodes to 64

From: Jan Kara <[email protected]>

We ran out of reserved inodes so bump the default number of reserved
inodes to 64 to get some breathing space. Otherwise we have to do a full
fs scan when increasing number of reserved inodes when some feature
needing another reserved inode is enabled. This consumes 13.5 KB on a
filesystem which is negligible these days.

Also update expected output for e2fsprogs tests since the number of used
inodes changes (yes, I went through all changed outputs and verified
that the changes are there only because of changed number of reserved
inodes).

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/initialize.c | 8 ++++-
misc/mke2fs.8.in | 8 ++---
tests/d_dumpe2fs_group_only/expect | 2 +-
tests/d_loaddump/expect | 4 +--
tests/d_xattr_edits/expect | 2 +-
tests/f_create_symlinks/expect | 12 +++----
tests/f_dup_resize/expect.1 | 6 ++--
tests/f_dup_resize/expect.2 | 2 +-
tests/f_extent_oobounds/expect.1 | 12 +++----
tests/f_extent_oobounds/expect.2 | 2 +-
tests/f_mmp_garbage/expect.1 | 2 +-
tests/f_mmp_garbage/expect.2 | 2 +-
tests/f_opt_extent/expect | 8 ++---
tests/f_resize_inode/expect | 20 +++++------
tests/j_ext_long_revoke_trans/expect | 4 +--
tests/j_ext_long_trans/expect | 10 +++---
tests/j_long_revoke_trans/expect | 4 +--
tests/j_long_revoke_trans_mcsum_32bit/expect | 4 +--
tests/j_long_revoke_trans_mcsum_64bit/expect | 4 +--
tests/j_long_trans/expect | 10 +++---
tests/j_long_trans_mcsum_32bit/expect | 10 +++---
tests/j_long_trans_mcsum_64bit/expect | 10 +++---
tests/j_short_revoke_trans/expect | 4 +--
tests/j_short_revoke_trans_mcsum_64bit/expect | 4 +--
tests/j_short_trans/expect | 6 ++--
tests/j_short_trans_64bit/expect | 6 ++--
tests/j_short_trans_mcsum_64bit/expect | 6 ++--
tests/j_short_trans_old_csum/expect | 6 ++--
tests/j_short_trans_open_recover/expect | 6 ++--
tests/j_short_trans_recover/expect | 6 ++--
tests/j_short_trans_recover_mcsum_64bit/expect | 6 ++--
tests/j_short_uncommitted_trans/expect | 4 +--
tests/j_short_uncommitted_trans_mcsum_64bit/expect | 4 +--
tests/m_64bit_flexbg/expect.1 | 10 +++---
tests/m_dasd_bs/expect.1 | 10 +++---
tests/m_desc_size_128/expect.1 | 10 +++---
tests/m_extent_journal/expect.1 | 10 +++---
tests/m_large_file/expect.1 | 24 ++++++-------
tests/m_meta_bg/expect.1 | 10 +++---
tests/m_minrootdir/expect | 42 +++++++++++-----------
tests/m_mmp/expect.1 | 10 +++---
tests/m_no_opt/expect.1 | 10 +++---
tests/m_raid_opt/expect.1 | 10 +++---
tests/m_root_owner/expect.1 | 10 +++---
tests/m_rootdir/expect | 10 +++---
tests/m_std/expect.1 | 10 +++---
tests/m_uninit/expect.1 | 10 +++---
tests/r_fixup_lastbg/expect | 2 +-
tests/r_fixup_lastbg_big/expect | 2 +-
tests/r_resize_inode/expect | 30 ++++++++--------
tests/t_32to64bit_meta/expect | 2 +-
tests/t_32to64bit_move_itable/expect | 2 +-
tests/t_64to32bit/expect | 2 +-
tests/t_64to32bit_meta/expect | 2 +-
tests/t_disable_mcsum_noinitbg/expect | 6 ++--
tests/t_enable_mcsum/expect | 8 ++---
tests/t_enable_mcsum_ext3/expect | 4 +--
tests/t_enable_mcsum_initbg/expect | 8 ++---
tests/t_uninit_bg_rm/expect | 4 +--
59 files changed, 234 insertions(+), 228 deletions(-)

diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index 75fbf8ee0061..23432571dac6 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -81,6 +81,12 @@ static unsigned int calc_reserved_gdt_blocks(ext2_filsys fs)
return rsv_gdb;
}

+/*
+ * Default for the first inode available for allocation (the previous ones are
+ * reserved for system files).
+ */
+#define EXT2_DEF_FIRST_INO 64
+
errcode_t ext2fs_initialize(const char *name, int flags,
struct ext2_super_block *param,
io_manager manager, ext2_filsys *ret_fs)
@@ -186,7 +192,7 @@ errcode_t ext2fs_initialize(const char *name, int flags,

set_field(s_rev_level, EXT2_GOOD_OLD_REV);
if (super->s_rev_level >= EXT2_DYNAMIC_REV) {
- set_field(s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
+ set_field(s_first_ino, EXT2_DEF_FIRST_INO);
set_field(s_inode_size, EXT2_GOOD_OLD_INODE_SIZE);
if (super->s_inode_size >= sizeof(struct ext2_inode_large)) {
int extra_isize = sizeof(struct ext2_inode_large) -
diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
index 4165c0a9d051..1a13e1a5b835 100644
--- a/misc/mke2fs.8.in
+++ b/misc/mke2fs.8.in
@@ -386,10 +386,10 @@ Do not attempt to discard blocks at mkfs time.
@QUOTA_MAN_COMMENT@behavior is to initialize both user and group quotas.
.TP
.BI reserved_inodes= number
-Specify the number of inodes reserved for system files. This number must be
-at least 10. Currently 10 is enough but future features may require additional
-reserved inodes. Reserving more inodes after the file system is created
-requires full file system scan which can take a long time.
+Specify the number of inodes reserved for system files. This number must be at
+least 10, default is 64. Currently 10 is enough but future features may require
+additional reserved inodes. Reserving more inodes after the file system is
+created requires full file system scan which can take a long time.
.RE
.TP
.BI \-f " fragment-size"
diff --git a/tests/d_dumpe2fs_group_only/expect b/tests/d_dumpe2fs_group_only/expect
index 78f97a2bafcc..ea8b8310719b 100644
--- a/tests/d_dumpe2fs_group_only/expect
+++ b/tests/d_dumpe2fs_group_only/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/262144 files (0.0% non-contiguous), 51278/1048576 blocks
+test_filesys: 64/262144 files (0.0% non-contiguous), 51278/1048576 blocks
Exit status is 0
dumpe2fs output

diff --git a/tests/d_loaddump/expect b/tests/d_loaddump/expect
index f70df88d2263..6d39cbe0408a 100644
--- a/tests/d_loaddump/expect
+++ b/tests/d_loaddump/expect
@@ -2,7 +2,7 @@ debugfs load/dump test
mke2fs -Fq -b 1024 test.img 512
Exit status is 0
debugfs -R ''write d_loaddump.tmp test_data'' -w test.img
-Allocated inode: 12
+Allocated inode: 65
Exit status is 0
e2fsck -yf -N test_filesys
Pass 1: Checking inodes, blocks, and sizes
@@ -10,7 +10,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 12/64 files (0.0% non-contiguous), 158/512 blocks
+test_filesys: 65/72 files (0.0% non-contiguous), 159/512 blocks
Exit status is 0
debugfs -R ''dump test_data d_loaddump.ver.tmp'' test.img
Exit status is 0
diff --git a/tests/d_xattr_edits/expect b/tests/d_xattr_edits/expect
index 4db54142b5fc..d729e264b736 100644
--- a/tests/d_xattr_edits/expect
+++ b/tests/d_xattr_edits/expect
@@ -46,5 +46,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/64 files (0.0% non-contiguous), 29/512 blocks
+test_filesys: 64/72 files (0.0% non-contiguous), 30/512 blocks
Exit status is 0
diff --git a/tests/f_create_symlinks/expect b/tests/f_create_symlinks/expect
index 47fa46827f6e..aab2f8615ff6 100644
--- a/tests/f_create_symlinks/expect
+++ b/tests/f_create_symlinks/expect
@@ -4,7 +4,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/128 files (0.0% non-contiguous), 441/1024 blocks
+test_filesys: 64/128 files (0.0% non-contiguous), 441/1024 blocks
Exit status is 0
debugfs -R "symlink /l_30 /xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" test.img
debugfs -R "symlink /l_70 /xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" test.img
@@ -17,7 +17,7 @@ debugfs -R "symlink /l_1500 /xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ext2fs_symlink: Invalid argument passed to ext2 library while creating symlink "l_1500"
symlink: Invalid argument passed to ext2 library
debugfs -R "stat /l_30" test.img
-Inode: 12 Type: symlink Mode: 0777 Flags: 0x0
+Inode: 65 Type: symlink Mode: 0777 Flags: 0x0
Generation: 0 Version: 0x00000000:00000000
User: 0 Group: 0 Size: 31
File ACL: 0 Directory ACL: 0
@@ -26,7 +26,7 @@ Fragment: Address: 0 Number: 0 Size: 0
Size of extra inode fields: 28
Fast link dest: "/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
debugfs -R "stat /l_70" test.img
-Inode: 13 Type: symlink Mode: 0777 Flags: 0x10000000
+Inode: 66 Type: symlink Mode: 0777 Flags: 0x10000000
Generation: 0 Version: 0x00000000:00000000
User: 0 Group: 0 Size: 71
File ACL: 0 Directory ACL: 0
@@ -37,7 +37,7 @@ Extended attributes:
system.data (11)
Fast link dest: "/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
debugfs -R "stat /l_500" test.img
-Inode: 14 Type: symlink Mode: 0777 Flags: 0x80000
+Inode: 67 Type: symlink Mode: 0777 Flags: 0x80000
Generation: 0 Version: 0x00000000:00000000
User: 0 Group: 0 Size: 501
File ACL: 0 Directory ACL: 0
@@ -47,7 +47,7 @@ Size of extra inode fields: 28
EXTENTS:
(0):153
debugfs -R "stat /l_1023" test.img
-Inode: 15 Type: symlink Mode: 0777 Flags: 0x80000
+Inode: 68 Type: symlink Mode: 0777 Flags: 0x80000
Generation: 0 Version: 0x00000000:00000000
User: 0 Group: 0 Size: 1024
File ACL: 0 Directory ACL: 0
@@ -65,5 +65,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 15/128 files (0.0% non-contiguous), 443/1024 blocks
+test_filesys: 68/128 files (0.0% non-contiguous), 443/1024 blocks
Exit status is 0
diff --git a/tests/f_dup_resize/expect.1 b/tests/f_dup_resize/expect.1
index aaf7769cbcd7..f7e46cf54824 100644
--- a/tests/f_dup_resize/expect.1
+++ b/tests/f_dup_resize/expect.1
@@ -5,12 +5,12 @@ Pass 1: Checking inodes, blocks, and sizes
Running additional passes to resolve blocks claimed by more than one inode...
Pass 1B: Rescanning for multiply-claimed blocks
Multiply-claimed block(s) in inode 7: 4--7
-Multiply-claimed block(s) in inode 12: 4--7
+Multiply-claimed block(s) in inode 65: 4--7
Pass 1C: Scanning directories for inodes with multiply-claimed blocks
Pass 1D: Reconciling multiply-claimed blocks
(There are 1 inodes containing multiply-claimed blocks.)

-File /debugfs (inode #12, mod time Mon Apr 11 00:00:00 2005)
+File /debugfs (inode #65, mod time Mon Apr 11 00:00:00 2005)
has 4 multiply-claimed block(s), shared with 1 file(s):
<The group descriptor inode> (inode #7, mod time Mon Apr 11 06:13:20 2005)
Clone multiply-claimed blocks? yes
@@ -30,5 +30,5 @@ Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 12/2560 files (8.3% non-contiguous), 485/10240 blocks
+test_filesys: 65/2560 files (1.5% non-contiguous), 485/10240 blocks
Exit status is 1
diff --git a/tests/f_dup_resize/expect.2 b/tests/f_dup_resize/expect.2
index 198acb958f5c..a3c97a77108c 100644
--- a/tests/f_dup_resize/expect.2
+++ b/tests/f_dup_resize/expect.2
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 12/2560 files (8.3% non-contiguous), 485/10240 blocks
+test_filesys: 65/2560 files (1.5% non-contiguous), 485/10240 blocks
Exit status is 0
diff --git a/tests/f_extent_oobounds/expect.1 b/tests/f_extent_oobounds/expect.1
index 59e1952cc695..fb4789026acc 100644
--- a/tests/f_extent_oobounds/expect.1
+++ b/tests/f_extent_oobounds/expect.1
@@ -1,11 +1,11 @@
Pass 1: Checking inodes, blocks, and sizes
-Inode 12, end of extent exceeds allowed value
+Inode 65, end of extent exceeds allowed value
(logical block 15, physical block 200, len 30)
Clear? yes

-Inode 12 extent tree (at (level 1) could be narrower. Fix? yes
+Inode 65 extent tree (at (level 1) could be narrower. Fix? yes

-Inode 12, i_blocks is 154, should be 94. Fix? yes
+Inode 65, i_blocks is 154, should be 94. Fix? yes

Pass 1E: Optimizing extent trees
Pass 2: Checking directory structure
@@ -15,13 +15,13 @@ Pass 5: Checking group summary information
Block bitmap differences: -(200--229)
Fix? yes

-Free blocks count wrong for group #0 (158, counted=188).
+Free blocks count wrong for group #0 (158, counted=183).
Fix? yes

-Free blocks count wrong (158, counted=188).
+Free blocks count wrong (158, counted=183).
Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 12/32 files (8.3% non-contiguous), 68/256 blocks
+test_filesys: 65/72 files (1.5% non-contiguous), 73/256 blocks
Exit status is 1
diff --git a/tests/f_extent_oobounds/expect.2 b/tests/f_extent_oobounds/expect.2
index 072928316833..8a48f36bfa8c 100644
--- a/tests/f_extent_oobounds/expect.2
+++ b/tests/f_extent_oobounds/expect.2
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 12/32 files (8.3% non-contiguous), 68/256 blocks
+test_filesys: 65/72 files (1.5% non-contiguous), 73/256 blocks
Exit status is 0
diff --git a/tests/f_mmp_garbage/expect.1 b/tests/f_mmp_garbage/expect.1
index a8add10175d0..b0904fa61dfc 100644
--- a/tests/f_mmp_garbage/expect.1
+++ b/tests/f_mmp_garbage/expect.1
@@ -5,5 +5,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/64 files (0.0% non-contiguous), 13/100 blocks
+test_filesys: 64/96 files (0.0% non-contiguous), 14/100 blocks
Exit status is 0
diff --git a/tests/f_mmp_garbage/expect.2 b/tests/f_mmp_garbage/expect.2
index 66300025e546..e6df796c08b3 100644
--- a/tests/f_mmp_garbage/expect.2
+++ b/tests/f_mmp_garbage/expect.2
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/64 files (0.0% non-contiguous), 13/100 blocks
+test_filesys: 64/96 files (0.0% non-contiguous), 14/100 blocks
Exit status is 0
diff --git a/tests/f_opt_extent/expect b/tests/f_opt_extent/expect
index 6d4863b51b2b..e9413b1c441d 100644
--- a/tests/f_opt_extent/expect
+++ b/tests/f_opt_extent/expect
@@ -32,18 +32,18 @@ Change in FS metadata:
Reserved block count: 26214
-Free blocks: 570
+Free blocks: 567
- Free inodes: 65047
+ Free inodes: 64994
First block: 1
Block size: 1024
@@ -47,8 +47,8 @@
Block bitmap at 262 (+261)
Inode bitmap at 278 (+277)
Inode table at 294-549 (+293)
-- 21 free blocks, 535 free inodes, 3 directories, 535 unused inodes
+- 21 free blocks, 482 free inodes, 3 directories, 482 unused inodes
- Free blocks: 4414-4434
-+ 18 free blocks, 535 free inodes, 3 directories, 535 unused inodes
++ 18 free blocks, 482 free inodes, 3 directories, 482 unused inodes
+ Free blocks: 4417-4434
- Free inodes: 490-1024
+ Free inodes: 543-1024
Group 1: (Blocks 8193-16384) [INODE_UNINIT]
Backup superblock at 8193, Group descriptors at 8194-8197
Pass 1: Checking inodes, blocks, and sizes
diff --git a/tests/f_resize_inode/expect b/tests/f_resize_inode/expect
index db57ed651ab0..d3c6ae27d767 100644
--- a/tests/f_resize_inode/expect
+++ b/tests/f_resize_inode/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 2107/16384 blocks
Exit status is 0
-----------------------------------------------

@@ -33,14 +33,14 @@ Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 2107/16384 blocks
Exit status is 1
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 2107/16384 blocks
Exit status is 0
-----------------------------------------------

@@ -61,14 +61,14 @@ Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 2107/16384 blocks
Exit status is 1
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 2107/16384 blocks
Exit status is 0
-----------------------------------------------

@@ -89,14 +89,14 @@ Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 2107/16384 blocks
Exit status is 1
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 2107/16384 blocks
Exit status is 0
-----------------------------------------------

@@ -111,7 +111,7 @@ Pass 4: Checking reference counts
Pass 5: Checking group summary information

test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 2107/16384 blocks
Exit status is 1
-----------------------------------------------

@@ -148,12 +148,12 @@ Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/4096 files (0.0% non-contiguous), 763/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 763/16384 blocks
Exit status is 1
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/4096 files (0.0% non-contiguous), 763/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 763/16384 blocks
Exit status is 0
diff --git a/tests/j_ext_long_revoke_trans/expect b/tests/j_ext_long_revoke_trans/expect
index ed198725ff05..80c703c3a05e 100644
--- a/tests/j_ext_long_revoke_trans/expect
+++ b/tests/j_ext_long_revoke_trans/expect
@@ -20,7 +20,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 6239/262144 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 6239/262144 blocks
Exit status is 0
debugfs write journal
debugfs: logdump -c
@@ -87,5 +87,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 6239/262144 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 6239/262144 blocks
Exit status is 0
diff --git a/tests/j_ext_long_trans/expect b/tests/j_ext_long_trans/expect
index d379610e7c2a..8aac7a6ec6b7 100644
--- a/tests/j_ext_long_trans/expect
+++ b/tests/j_ext_long_trans/expect
@@ -20,7 +20,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 6239/262144 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 6239/262144 blocks
Exit status is 0
debugfs write journal
debugfs: logdump -c
@@ -86,19 +86,19 @@ Fix? yes
Free blocks count wrong (255903, counted=255916).
Fix? yes

-Inode bitmap differences: +1 +(3--10)
+Inode bitmap differences: +1 +(3--63)
Fix? yes

-Free inodes count wrong for group #0 (500, counted=501).
+Free inodes count wrong for group #0 (447, counted=448).
Fix? yes

Directories count wrong for group #0 (3, counted=2).
Fix? yes

-Free inodes count wrong (16372, counted=16373).
+Free inodes count wrong (16319, counted=16320).
Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/16384 files (0.0% non-contiguous), 6228/262144 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 6228/262144 blocks
Exit status is 1
diff --git a/tests/j_long_revoke_trans/expect b/tests/j_long_revoke_trans/expect
index c0730e609383..c499f724ae9d 100644
--- a/tests/j_long_revoke_trans/expect
+++ b/tests/j_long_revoke_trans/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 14431/262144 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 14431/262144 blocks
Exit status is 0
debugfs write journal
debugfs: logdump -c
@@ -77,5 +77,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 14431/262144 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 14431/262144 blocks
Exit status is 0
diff --git a/tests/j_long_revoke_trans_mcsum_32bit/expect b/tests/j_long_revoke_trans_mcsum_32bit/expect
index 664a301d0dae..8e8d6ab021de 100644
--- a/tests/j_long_revoke_trans_mcsum_32bit/expect
+++ b/tests/j_long_revoke_trans_mcsum_32bit/expect
@@ -13,7 +13,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 27050/524288 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 27050/524288 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -113,5 +113,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 27050/524288 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 27050/524288 blocks
Exit status is 0
diff --git a/tests/j_long_revoke_trans_mcsum_64bit/expect b/tests/j_long_revoke_trans_mcsum_64bit/expect
index 29dc407d1269..76baf1a2641f 100644
--- a/tests/j_long_revoke_trans_mcsum_64bit/expect
+++ b/tests/j_long_revoke_trans_mcsum_64bit/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 27068/524288 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 27068/524288 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -128,5 +128,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 27068/524288 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 27068/524288 blocks
Exit status is 0
diff --git a/tests/j_long_trans/expect b/tests/j_long_trans/expect
index 7a175414be5f..991cea18a6bd 100644
--- a/tests/j_long_trans/expect
+++ b/tests/j_long_trans/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 14431/262144 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 14431/262144 blocks
Exit status is 0
debugfs write journal
debugfs: logdump -c
@@ -84,16 +84,16 @@ Fix? yes
Free blocks count wrong (247711, counted=255916).
Fix? yes

-Inode bitmap differences: +1 +(3--10)
+Inode bitmap differences: +1 +(3--63)
Fix? yes

-Free inodes count wrong for group #0 (500, counted=501).
+Free inodes count wrong for group #0 (447, counted=448).
Fix? yes

Directories count wrong for group #0 (3, counted=2).
Fix? yes

-Free inodes count wrong (16372, counted=16373).
+Free inodes count wrong (16319, counted=16320).
Fix? yes

Recreate journal? yes
@@ -103,5 +103,5 @@ Creating journal (8192 blocks): Done.
*** journal has been regenerated ***

test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/16384 files (0.0% non-contiguous), 14420/262144 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 14420/262144 blocks
Exit status is 1
diff --git a/tests/j_long_trans_mcsum_32bit/expect b/tests/j_long_trans_mcsum_32bit/expect
index a808d9f4d706..ef4969a04dcb 100644
--- a/tests/j_long_trans_mcsum_32bit/expect
+++ b/tests/j_long_trans_mcsum_32bit/expect
@@ -13,7 +13,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 27050/524288 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 27050/524288 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -123,16 +123,16 @@ Fix? yes
Free blocks count wrong (497236, counted=513633).
Fix? yes

-Inode bitmap differences: +1 +(3--10)
+Inode bitmap differences: +1 +(3--63)
Fix? yes

-Free inodes count wrong for group #0 (500, counted=501).
+Free inodes count wrong for group #0 (447, counted=448).
Fix? yes

Directories count wrong for group #0 (3, counted=2).
Fix? yes

-Free inodes count wrong (32756, counted=32757).
+Free inodes count wrong (32703, counted=32704).
Fix? yes

Recreate journal? yes
@@ -142,5 +142,5 @@ Creating journal (16384 blocks): Done.
*** journal has been regenerated ***

test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/32768 files (0.0% non-contiguous), 27039/524288 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 27039/524288 blocks
Exit status is 1
diff --git a/tests/j_long_trans_mcsum_64bit/expect b/tests/j_long_trans_mcsum_64bit/expect
index 76e109a42102..27d38cf7d12b 100644
--- a/tests/j_long_trans_mcsum_64bit/expect
+++ b/tests/j_long_trans_mcsum_64bit/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 27068/524288 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 27068/524288 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -122,16 +122,16 @@ Fix? yes
Free blocks count wrong (497218, counted=513615).
Fix? yes

-Inode bitmap differences: +1 +(3--10)
+Inode bitmap differences: +1 +(3--63)
Fix? yes

-Free inodes count wrong for group #0 (500, counted=501).
+Free inodes count wrong for group #0 (447, counted=448).
Fix? yes

Directories count wrong for group #0 (3, counted=2).
Fix? yes

-Free inodes count wrong (32756, counted=32757).
+Free inodes count wrong (32703, counted=32704).
Fix? yes

Recreate journal? yes
@@ -141,5 +141,5 @@ Creating journal (16384 blocks): Done.
*** journal has been regenerated ***

test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/32768 files (0.0% non-contiguous), 27057/524288 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 27057/524288 blocks
Exit status is 1
diff --git a/tests/j_short_revoke_trans/expect b/tests/j_short_revoke_trans/expect
index e83c5ea8414d..dd6104ded65d 100644
--- a/tests/j_short_revoke_trans/expect
+++ b/tests/j_short_revoke_trans/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 0
debugfs write journal
debugfs: logdump -c
@@ -28,5 +28,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 0
diff --git a/tests/j_short_revoke_trans_mcsum_64bit/expect b/tests/j_short_revoke_trans_mcsum_64bit/expect
index 2b0eeb3676ef..542ec17b49af 100644
--- a/tests/j_short_revoke_trans_mcsum_64bit/expect
+++ b/tests/j_short_revoke_trans_mcsum_64bit/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 6353/131072 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -30,5 +30,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 6353/131072 blocks
Exit status is 0
diff --git a/tests/j_short_trans/expect b/tests/j_short_trans/expect
index bcc8fe82a57a..fda0c1ebdef9 100644
--- a/tests/j_short_trans/expect
+++ b/tests/j_short_trans/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 0
debugfs write journal
debugfs: logdump -c
@@ -29,10 +29,10 @@ Pass 5: Checking group summary information
Block bitmap differences: +(0--1050) +(32768--36880)
Fix? yes

-Inode bitmap differences: +(1--11)
+Inode bitmap differences: +(1--64)
Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 1
diff --git a/tests/j_short_trans_64bit/expect b/tests/j_short_trans_64bit/expect
index f9971eba383a..9833b848a037 100644
--- a/tests/j_short_trans_64bit/expect
+++ b/tests/j_short_trans_64bit/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 5196/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5196/65536 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -31,10 +31,10 @@ Pass 5: Checking group summary information
Block bitmap differences: +(0--1066) +(32768--36896)
Fix? yes

-Inode bitmap differences: +(1--11)
+Inode bitmap differences: +(1--64)
Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/16384 files (0.0% non-contiguous), 5196/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5196/65536 blocks
Exit status is 1
diff --git a/tests/j_short_trans_mcsum_64bit/expect b/tests/j_short_trans_mcsum_64bit/expect
index d876ff095542..bc0fd309454b 100644
--- a/tests/j_short_trans_mcsum_64bit/expect
+++ b/tests/j_short_trans_mcsum_64bit/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 6353/131072 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -31,10 +31,10 @@ Pass 5: Checking group summary information
Block bitmap differences: +(0--65) +(67--69) +(71--584) +(1097--2126) +(65536--69631) +(98304--98368)
Fix? yes

-Inode bitmap differences: +(1--11)
+Inode bitmap differences: +(1--64)
Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 6353/131072 blocks
Exit status is 1
diff --git a/tests/j_short_trans_old_csum/expect b/tests/j_short_trans_old_csum/expect
index 29ac27fb3c9c..9d9148bed943 100644
--- a/tests/j_short_trans_old_csum/expect
+++ b/tests/j_short_trans_old_csum/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -31,10 +31,10 @@ Pass 5: Checking group summary information
Block bitmap differences: +(0--1050) +(32768--36880)
Fix? yes

-Inode bitmap differences: +(1--11)
+Inode bitmap differences: +(1--64)
Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 1
diff --git a/tests/j_short_trans_open_recover/expect b/tests/j_short_trans_open_recover/expect
index be6e363dc8ac..6673ccea503a 100644
--- a/tests/j_short_trans_open_recover/expect
+++ b/tests/j_short_trans_open_recover/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 0
debugfs write journal
debugfs: logdump -c
@@ -34,10 +34,10 @@ Pass 5: Checking group summary information
Block bitmap differences: +(0--1050) +(32768--36880)
Fix? yes

-Inode bitmap differences: +(1--11)
+Inode bitmap differences: +(1--64)
Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 1
diff --git a/tests/j_short_trans_recover/expect b/tests/j_short_trans_recover/expect
index 75867337fafd..b0eecef78cd6 100644
--- a/tests/j_short_trans_recover/expect
+++ b/tests/j_short_trans_recover/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 0
debugfs write journal
debugfs: logdump -c
@@ -31,10 +31,10 @@ Pass 5: Checking group summary information
Block bitmap differences: +(0--1050) +(32768--36880)
Fix? yes

-Inode bitmap differences: +(1--11)
+Inode bitmap differences: +(1--64)
Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 1
diff --git a/tests/j_short_trans_recover_mcsum_64bit/expect b/tests/j_short_trans_recover_mcsum_64bit/expect
index 9cc330978560..02decee3c0c7 100644
--- a/tests/j_short_trans_recover_mcsum_64bit/expect
+++ b/tests/j_short_trans_recover_mcsum_64bit/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 6353/131072 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -33,10 +33,10 @@ Pass 5: Checking group summary information
Block bitmap differences: +(0--65) +(67--69) +(71--584) +(1097--2126) +(65536--69631) +(98304--98368)
Fix? yes

-Inode bitmap differences: +(1--11)
+Inode bitmap differences: +(1--64)
Fix? yes


test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 6353/131072 blocks
Exit status is 1
diff --git a/tests/j_short_uncommitted_trans/expect b/tests/j_short_uncommitted_trans/expect
index dedddb5b373a..db8a18f7a85d 100644
--- a/tests/j_short_uncommitted_trans/expect
+++ b/tests/j_short_uncommitted_trans/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 0
debugfs write journal
debugfs: logdump -c
@@ -22,5 +22,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 5164/65536 blocks
Exit status is 0
diff --git a/tests/j_short_uncommitted_trans_mcsum_64bit/expect b/tests/j_short_uncommitted_trans_mcsum_64bit/expect
index 3effc94fec5d..2504838fc963 100644
--- a/tests/j_short_uncommitted_trans_mcsum_64bit/expect
+++ b/tests/j_short_uncommitted_trans_mcsum_64bit/expect
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 6353/131072 blocks
Exit status is 0
Journal features: (none)
debugfs write journal
@@ -24,5 +24,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 6353/131072 blocks
Exit status is 0
diff --git a/tests/m_64bit_flexbg/expect.1 b/tests/m_64bit_flexbg/expect.1
index cfa3bc9bf336..1d731def1699 100644
--- a/tests/m_64bit_flexbg/expect.1
+++ b/tests/m_64bit_flexbg/expect.1
@@ -10,7 +10,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/128 files (0.0% non-contiguous), 42/1024 blocks
+test_filesys: 64/128 files (0.0% non-contiguous), 42/1024 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -25,7 +25,7 @@ Inode count: 128
Block count: 1024
Reserved block count: 51
Free blocks: 982
-Free inodes: 117
+Free inodes: 64
First block: 1
Block size: 1024
Fragment size: 1024
@@ -40,7 +40,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -51,6 +51,6 @@ Group 0: (Blocks 1-1023)
Block bitmap at 10 (+9)
Inode bitmap at 26 (+25)
Inode table at 42-57 (+41)
- 982 free blocks, 117 free inodes, 2 directories
+ 982 free blocks, 64 free inodes, 2 directories
Free blocks: 24-25, 28-41, 58-1023
- Free inodes: 12-128
+ Free inodes: 65-128
diff --git a/tests/m_dasd_bs/expect.1 b/tests/m_dasd_bs/expect.1
index 0e55e8f7e127..14808ed41b2c 100644
--- a/tests/m_dasd_bs/expect.1
+++ b/tests/m_dasd_bs/expect.1
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 1104/32768 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 1104/32768 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -27,7 +27,7 @@ Inode count: 16384
Block count: 32768
Reserved block count: 1638
Free blocks: 31664
-Free inodes: 16373
+Free inodes: 16320
First block: 0
Block size: 2048
Fragment size: 2048
@@ -40,7 +40,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -51,9 +51,9 @@ Group 0: (Blocks 0-16383)
Block bitmap at 33 (+33)
Inode bitmap at 34 (+34)
Inode table at 35-546 (+35)
- 15827 free blocks, 8181 free inodes, 2 directories
+ 15827 free blocks, 8128 free inodes, 2 directories
Free blocks: 557-16383
- Free inodes: 12-8192
+ Free inodes: 65-8192
Group 1: (Blocks 16384-32767)
Backup superblock at 16384, Group descriptors at 16385-16385
Reserved GDT blocks at 16386-16416
diff --git a/tests/m_desc_size_128/expect.1 b/tests/m_desc_size_128/expect.1
index 5a7da87b72d1..9b6f5647df92 100644
--- a/tests/m_desc_size_128/expect.1
+++ b/tests/m_desc_size_128/expect.1
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/8192 files (0.0% non-contiguous), 4298/131072 blocks
+test_filesys: 64/8192 files (0.0% non-contiguous), 4298/131072 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -27,7 +27,7 @@ Inode count: 8192
Block count: 131072
Reserved block count: 6553
Free blocks: 126774
-Free inodes: 8181
+Free inodes: 8128
First block: 1
Block size: 1024
Fragment size: 1024
@@ -41,7 +41,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -51,9 +51,9 @@ Group 0: (Blocks 1-1024)
Reserved GDT blocks at 18-273
Block bitmap at 274 (+273), Inode bitmap at 275 (+274)
Inode table at 276-283 (+275)
- 727 free blocks, 53 free inodes, 2 directories
+ 727 free blocks, 0 free inodes, 2 directories
Free blocks: 298-1024
- Free inodes: 12-64
+ Free inodes:
Group 1: (Blocks 1025-2048)
Backup superblock at 1025, Group descriptors at 1026-1041
Reserved GDT blocks at 1042-1297
diff --git a/tests/m_extent_journal/expect.1 b/tests/m_extent_journal/expect.1
index 34e8a80d353d..f3a74084a270 100644
--- a/tests/m_extent_journal/expect.1
+++ b/tests/m_extent_journal/expect.1
@@ -13,7 +13,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 7460/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 7460/65536 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -28,7 +28,7 @@ Inode count: 16384
Block count: 65536
Reserved block count: 3276
Free blocks: 58076
-Free inodes: 16373
+Free inodes: 16320
First block: 1
Block size: 1024
Fragment size: 1024
@@ -41,7 +41,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Journal inode: 8
Default directory hash: half_md4
@@ -58,9 +58,9 @@ Group 0: (Blocks 1-8192)
Reserved GDT blocks at 3-257
Block bitmap at 258 (+257), Inode bitmap at 259 (+258)
Inode table at 260-515 (+259)
- 7663 free blocks, 2037 free inodes, 2 directories
+ 7663 free blocks, 1984 free inodes, 2 directories
Free blocks: 530-8192
- Free inodes: 12-2048
+ Free inodes: 65-2048
Group 1: (Blocks 8193-16384)
Backup superblock at 8193, Group descriptors at 8194-8194
Reserved GDT blocks at 8195-8449
diff --git a/tests/m_large_file/expect.1 b/tests/m_large_file/expect.1
index 4acca41ce520..840c2fe934b1 100644
--- a/tests/m_large_file/expect.1
+++ b/tests/m_large_file/expect.1
@@ -1,4 +1,4 @@
-Creating filesystem with 16384 4k blocks and 64 inodes
+Creating filesystem with 16384 4k blocks and 80 inodes

Allocating group tables: done
Writing inode tables: done
@@ -10,7 +10,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/64 files (0.0% non-contiguous), 17/16384 blocks
+test_filesys: 64/80 files (0.0% non-contiguous), 18/16384 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -21,24 +21,24 @@ Default mount options: (none)
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
-Inode count: 64
+Inode count: 80
Block count: 16384
Reserved block count: 819
-Free blocks: 16367
-Free inodes: 53
+Free blocks: 16366
+Free inodes: 16
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 3
Blocks per group: 32768
Fragments per group: 32768
-Inodes per group: 64
-Inode blocks per group: 4
+Inodes per group: 80
+Inode blocks per group: 5
Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
@@ -50,7 +50,7 @@ Group 0: (Blocks 0-16383)
Reserved GDT blocks at 2-4
Block bitmap at 5 (+5)
Inode bitmap at 6 (+6)
- Inode table at 7-10 (+7)
- 16367 free blocks, 53 free inodes, 2 directories
- Free blocks: 17-16383
- Free inodes: 12-64
+ Inode table at 7-11 (+7)
+ 16366 free blocks, 16 free inodes, 2 directories
+ Free blocks: 18-16383
+ Free inodes: 65-80
diff --git a/tests/m_meta_bg/expect.1 b/tests/m_meta_bg/expect.1
index 7df4230ca0bd..568c43514780 100644
--- a/tests/m_meta_bg/expect.1
+++ b/tests/m_meta_bg/expect.1
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 4389/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 4389/131072 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -27,7 +27,7 @@ Inode count: 32768
Block count: 131072
Reserved block count: 6553
Free blocks: 126683
-Free inodes: 32757
+Free inodes: 32704
First block: 1
Block size: 1024
Fragment size: 1024
@@ -39,7 +39,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -48,9 +48,9 @@ Group 0: (Blocks 1-1024)
Primary superblock at 1, Group descriptor at 2
Block bitmap at 3 (+2), Inode bitmap at 4 (+3)
Inode table at 5-36 (+4)
- 975 free blocks, 245 free inodes, 2 directories
+ 975 free blocks, 192 free inodes, 2 directories
Free blocks: 50-1024
- Free inodes: 12-256
+ Free inodes: 65-256
Group 1: (Blocks 1025-2048)
Backup superblock at 1025, Group descriptor at 1026
Block bitmap at 1027 (+2), Inode bitmap at 1028 (+3)
diff --git a/tests/m_minrootdir/expect b/tests/m_minrootdir/expect
index 41a713fd02ca..953df9b2db0f 100644
--- a/tests/m_minrootdir/expect
+++ b/tests/m_minrootdir/expect
@@ -12,7 +12,7 @@ Inode count: 1024
Block count: 16384
Reserved block count: 819
Free blocks: 16065
-Free inodes: 1006
+Free inodes: 953
First block: 1
Block size: 1024
Fragment size: 1024
@@ -26,7 +26,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
@@ -39,9 +39,9 @@ Group 0: (Blocks 1-8192)
Block bitmap at 3 (+2)
Inode bitmap at 5 (+4)
Inode table at 7-134 (+6)
- 7876 free blocks, 494 free inodes, 4 directories, 494 unused inodes
+ 7876 free blocks, 441 free inodes, 4 directories, 441 unused inodes
Free blocks: 317-8192
- Free inodes: 19-512
+ Free inodes: 72-512
Group 1: (Blocks 8193-16383) [INODE_UNINIT]
Backup superblock at 8193, Group descriptors at 8194-8194
Block bitmap at 4 (bg #0 + 3)
@@ -105,11 +105,11 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test.img: 18/1024 files (0.0% non-contiguous), 319/16384 blocks
+test.img: 71/1024 files (0.0% non-contiguous), 319/16384 blocks
minify fs
Setting reserved blocks percentage to 0% (0 blocks)
-Resizing the filesystem on test.img to 338 (1k) blocks.
-The filesystem on test.img is now 338 (1k) blocks long.
+Resizing the filesystem on test.img to 352 (1k) blocks.
+The filesystem on test.img is now 352 (1k) blocks long.

Filesystem volume name: <none>
Last mounted on: <not available>
@@ -121,10 +121,10 @@ Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 512
-Block count: 338
+Block count: 352
Reserved block count: 0
-Free blocks: 151
-Free inodes: 494
+Free blocks: 165
+Free inodes: 441
First block: 1
Block size: 1024
Fragment size: 1024
@@ -138,7 +138,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
@@ -146,20 +146,20 @@ Default directory hash: half_md4
Checksum type: crc32c


-Group 0: (Blocks 1-337)
+Group 0: (Blocks 1-351)
Primary superblock at 1, Group descriptors at 2-2
Block bitmap at 3 (+2)
Inode bitmap at 5 (+4)
Inode table at 7-134 (+6)
- 151 free blocks, 494 free inodes, 4 directories, 494 unused inodes
- Free blocks: 4, 6, 135-262, 317-337
- Free inodes: 19-512
+ 165 free blocks, 441 free inodes, 4 directories, 441 unused inodes
+ Free blocks: 4, 6, 135-262, 317-351
+ Free inodes: 72-512
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test.img: 18/512 files (0.0% non-contiguous), 187/338 blocks
+test.img: 71/512 files (0.0% non-contiguous), 187/352 blocks
minify fs (2)
Setting reserved blocks percentage to 0% (0 blocks)
Resizing the filesystem on test.img to 188 (1k) blocks.
@@ -178,7 +178,7 @@ Inode count: 512
Block count: 188
Reserved block count: 0
Free blocks: 1
-Free inodes: 494
+Free inodes: 441
First block: 1
Block size: 1024
Fragment size: 1024
@@ -192,7 +192,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
@@ -205,12 +205,12 @@ Group 0: (Blocks 1-187)
Block bitmap at 3 (+2)
Inode bitmap at 5 (+4)
Inode table at 7-134 (+6)
- 1 free blocks, 494 free inodes, 4 directories, 494 unused inodes
+ 1 free blocks, 441 free inodes, 4 directories, 441 unused inodes
Free blocks: 187
- Free inodes: 19-512
+ Free inodes: 72-512
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test.img: 18/512 files (5.6% non-contiguous), 187/188 blocks
+test.img: 71/512 files (1.4% non-contiguous), 187/188 blocks
diff --git a/tests/m_mmp/expect.1 b/tests/m_mmp/expect.1
index a1452e6ba795..396e608dd02b 100644
--- a/tests/m_mmp/expect.1
+++ b/tests/m_mmp/expect.1
@@ -13,7 +13,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/65536 files (0.0% non-contiguous), 2093/65536 blocks
+test_filesys: 64/65536 files (0.0% non-contiguous), 2093/65536 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -28,7 +28,7 @@ Inode count: 65536
Block count: 65536
Reserved block count: 3276
Free blocks: 63443
-Free inodes: 65525
+Free inodes: 65472
First block: 0
Block size: 4096
Fragment size: 4096
@@ -41,7 +41,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4
MMP block number: 1049
@@ -54,9 +54,9 @@ Group 0: (Blocks 0-32767)
Block bitmap at 17 (+17)
Inode bitmap at 18 (+18)
Inode table at 19-1042 (+19)
- 31718 free blocks, 32757 free inodes, 2 directories
+ 31718 free blocks, 32704 free inodes, 2 directories
Free blocks: 1050-32767
- Free inodes: 12-32768
+ Free inodes: 65-32768
Group 1: (Blocks 32768-65535)
Backup superblock at 32768, Group descriptors at 32769-32769
Reserved GDT blocks at 32770-32784
diff --git a/tests/m_no_opt/expect.1 b/tests/m_no_opt/expect.1
index 58b311c4eddf..4a9733735d47 100644
--- a/tests/m_no_opt/expect.1
+++ b/tests/m_no_opt/expect.1
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 2094/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 2094/65536 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -27,7 +27,7 @@ Inode count: 16384
Block count: 65536
Reserved block count: 3276
Free blocks: 63442
-Free inodes: 16373
+Free inodes: 16320
First block: 1
Block size: 1024
Fragment size: 1024
@@ -39,7 +39,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -48,9 +48,9 @@ Group 0: (Blocks 1-8192)
Primary superblock at 1, Group descriptors at 2-2
Block bitmap at 3 (+2), Inode bitmap at 4 (+3)
Inode table at 5-260 (+4)
- 7919 free blocks, 2037 free inodes, 2 directories
+ 7919 free blocks, 1984 free inodes, 2 directories
Free blocks: 274-8192
- Free inodes: 12-2048
+ Free inodes: 65-2048
Group 1: (Blocks 8193-16384)
Backup superblock at 8193, Group descriptors at 8194-8194
Block bitmap at 8195 (+2), Inode bitmap at 8196 (+3)
diff --git a/tests/m_raid_opt/expect.1 b/tests/m_raid_opt/expect.1
index 0fccb7cadcbc..8385089d01d0 100644
--- a/tests/m_raid_opt/expect.1
+++ b/tests/m_raid_opt/expect.1
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 7238/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 7238/131072 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -27,7 +27,7 @@ Inode count: 32768
Block count: 131072
Reserved block count: 6553
Free blocks: 123834
-Free inodes: 32757
+Free inodes: 32704
First block: 1
Block size: 1024
Fragment size: 1024
@@ -41,7 +41,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -51,9 +51,9 @@ Group 0: (Blocks 1-1024)
Reserved GDT blocks at 6-261
Block bitmap at 294 (+293), Inode bitmap at 295 (+294)
Inode table at 262-293 (+261)
- 715 free blocks, 245 free inodes, 2 directories
+ 715 free blocks, 192 free inodes, 2 directories
Free blocks: 310-1024
- Free inodes: 12-256
+ Free inodes: 65-256
Group 1: (Blocks 1025-2048)
Backup superblock at 1025, Group descriptors at 1026-1029
Reserved GDT blocks at 1030-1285
diff --git a/tests/m_root_owner/expect.1 b/tests/m_root_owner/expect.1
index 30d119e22c99..7a83f962c869 100644
--- a/tests/m_root_owner/expect.1
+++ b/tests/m_root_owner/expect.1
@@ -10,7 +10,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/128 files (0.0% non-contiguous), 38/1024 blocks
+test_filesys: 64/128 files (0.0% non-contiguous), 38/1024 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -25,7 +25,7 @@ Inode count: 128
Block count: 1024
Reserved block count: 51
Free blocks: 986
-Free inodes: 117
+Free inodes: 64
First block: 1
Block size: 1024
Fragment size: 1024
@@ -38,7 +38,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -49,6 +49,6 @@ Group 0: (Blocks 1-1023)
Block bitmap at 6 (+5)
Inode bitmap at 7 (+6)
Inode table at 8-23 (+7)
- 986 free blocks, 117 free inodes, 2 directories
+ 986 free blocks, 64 free inodes, 2 directories
Free blocks: 38-1023
- Free inodes: 12-128
+ Free inodes: 65-128
diff --git a/tests/m_rootdir/expect b/tests/m_rootdir/expect
index a5314f14366f..cc150d234fb1 100644
--- a/tests/m_rootdir/expect
+++ b/tests/m_rootdir/expect
@@ -11,7 +11,7 @@ Inode count: 1024
Block count: 16384
Reserved block count: 819
Free blocks: 14786
-Free inodes: 1005
+Free inodes: 952
First block: 1
Block size: 1024
Fragment size: 1024
@@ -26,7 +26,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
@@ -47,9 +47,9 @@ Group 0: (Blocks 1-8192)
Block bitmap at 130 (+129)
Inode bitmap at 132 (+131)
Inode table at 134-261 (+133)
- 7748 free blocks, 493 free inodes, 4 directories, 493 unused inodes
+ 7748 free blocks, 440 free inodes, 4 directories, 440 unused inodes
Free blocks: 445-8192
- Free inodes: 20-512
+ Free inodes: 73-512
Group 1: (Blocks 8193-16383) [INODE_UNINIT]
Backup superblock at 8193, Group descriptors at 8194-8194
Reserved GDT blocks at 8195-8321
@@ -114,4 +114,4 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test.img: 19/1024 files (0.0% non-contiguous), 1598/16384 blocks
+test.img: 72/1024 files (0.0% non-contiguous), 1598/16384 blocks
diff --git a/tests/m_std/expect.1 b/tests/m_std/expect.1
index b05031f8e315..8661e6978354 100644
--- a/tests/m_std/expect.1
+++ b/tests/m_std/expect.1
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 3364/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 3364/65536 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -27,7 +27,7 @@ Inode count: 16384
Block count: 65536
Reserved block count: 3276
Free blocks: 62172
-Free inodes: 16373
+Free inodes: 16320
First block: 1
Block size: 1024
Fragment size: 1024
@@ -40,7 +40,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -50,9 +50,9 @@ Group 0: (Blocks 1-8192)
Reserved GDT blocks at 3-257
Block bitmap at 258 (+257), Inode bitmap at 259 (+258)
Inode table at 260-515 (+259)
- 7663 free blocks, 2037 free inodes, 2 directories
+ 7663 free blocks, 1984 free inodes, 2 directories
Free blocks: 530-8192
- Free inodes: 12-2048
+ Free inodes: 65-2048
Group 1: (Blocks 8193-16384)
Backup superblock at 8193, Group descriptors at 8194-8194
Reserved GDT blocks at 8195-8449
diff --git a/tests/m_uninit/expect.1 b/tests/m_uninit/expect.1
index e886dfbf1373..3e2ead292009 100644
--- a/tests/m_uninit/expect.1
+++ b/tests/m_uninit/expect.1
@@ -12,7 +12,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/32768 files (0.0% non-contiguous), 5691/131072 blocks
+test_filesys: 64/32768 files (0.0% non-contiguous), 5691/131072 blocks
Exit status is 0
Filesystem volume name: <none>
Last mounted on: <not available>
@@ -27,7 +27,7 @@ Inode count: 32768
Block count: 131072
Reserved block count: 6553
Free blocks: 125381
-Free inodes: 32757
+Free inodes: 32704
First block: 1
Block size: 1024
Fragment size: 1024
@@ -40,7 +40,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -50,9 +50,9 @@ Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
Reserved GDT blocks at 3-258
Block bitmap at 259 (+258), Inode bitmap at 260 (+259)
Inode table at 261-516 (+260)
- 7662 free blocks, 2037 free inodes, 2 directories, 2037 unused inodes
+ 7662 free blocks, 1984 free inodes, 2 directories, 1984 unused inodes
Free blocks: 531-8192
- Free inodes: 12-2048
+ Free inodes: 65-2048
Group 1: (Blocks 8193-16384) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
Backup superblock at 8193, Group descriptors at 8194-8194
Reserved GDT blocks at 8195-8450
diff --git a/tests/r_fixup_lastbg/expect b/tests/r_fixup_lastbg/expect
index 96b154a94078..64e227c89d4d 100644
--- a/tests/r_fixup_lastbg/expect
+++ b/tests/r_fixup_lastbg/expect
@@ -36,4 +36,4 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test.img: 11/1248 files (0.0% non-contiguous), 1517/20004 blocks
+test.img: 64/1248 files (0.0% non-contiguous), 1517/20004 blocks
diff --git a/tests/r_fixup_lastbg_big/expect b/tests/r_fixup_lastbg_big/expect
index edaabaf00d91..43a21b2b9987 100644
--- a/tests/r_fixup_lastbg_big/expect
+++ b/tests/r_fixup_lastbg_big/expect
@@ -42,4 +42,4 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test.img: 11/2080 files (0.0% non-contiguous), 1809/40000 blocks
+test.img: 64/2080 files (0.0% non-contiguous), 1809/40000 blocks
diff --git a/tests/r_resize_inode/expect b/tests/r_resize_inode/expect
index ba1647ea72c2..4594bc190e55 100644
--- a/tests/r_resize_inode/expect
+++ b/tests/r_resize_inode/expect
@@ -8,7 +8,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/16384 files (0.0% non-contiguous), 4513/65536 blocks
+test_filesys: 64/16384 files (0.0% non-contiguous), 4513/65536 blocks
Exit status is 0
dumpe2fs test.img
Filesystem volume name: <none>
@@ -24,7 +24,7 @@ Inode count: 16384
Block count: 65536
Reserved block count: 3276
Free blocks: 61023
-Free inodes: 16373
+Free inodes: 16320
First block: 1
Block size: 1024
Fragment size: 1024
@@ -37,7 +37,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -47,9 +47,9 @@ Group 0: (Blocks 1-1024)
Reserved GDT blocks at 4-258
Block bitmap at 259 (+258), Inode bitmap at 260 (+259)
Inode table at 261-292 (+260)
- 718 free blocks, 245 free inodes, 2 directories
+ 718 free blocks, 192 free inodes, 2 directories
Free blocks: 307-1024
- Free inodes: 12-256
+ Free inodes: 65-256
Group 1: (Blocks 1025-2048)
Backup superblock at 1025, Group descriptors at 1026-1027
Reserved GDT blocks at 1028-1282
@@ -455,7 +455,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/4096 files (0.0% non-contiguous), 2107/16384 blocks
+test_filesys: 64/4096 files (0.0% non-contiguous), 2107/16384 blocks
Exit status is 0
dumpe2fs test.img
Filesystem volume name: <none>
@@ -471,7 +471,7 @@ Inode count: 4096
Block count: 16384
Reserved block count: 819
Free blocks: 14277
-Free inodes: 4085
+Free inodes: 4032
First block: 1
Block size: 1024
Fragment size: 1024
@@ -484,7 +484,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -494,9 +494,9 @@ Group 0: (Blocks 1-1024)
Reserved GDT blocks at 3-258
Block bitmap at 260 (+259), Inode bitmap at 261 (+260)
Inode table at 262-293 (+261)
- 718 free blocks, 245 free inodes, 2 directories
+ 718 free blocks, 192 free inodes, 2 directories
Free blocks: 259, 308-1024
- Free inodes: 12-256
+ Free inodes: 65-256
Group 1: (Blocks 1025-2048)
Backup superblock at 1025, Group descriptors at 1026-1026
Reserved GDT blocks at 1027-1282
@@ -609,7 +609,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/41472 files (0.0% non-contiguous), 8361/165536 blocks
+test_filesys: 64/41472 files (0.0% non-contiguous), 8361/165536 blocks
Exit status is 0
dumpe2fs test.img
Filesystem volume name: <none>
@@ -625,7 +625,7 @@ Inode count: 41472
Block count: 165536
Reserved block count: 8274
Free blocks: 157175
-Free inodes: 41461
+Free inodes: 41408
First block: 1
Block size: 1024
Fragment size: 1024
@@ -638,7 +638,7 @@ Mount count: 0
Check interval: 15552000 (6 months)
Reserved blocks uid: 0
Reserved blocks gid: 0
-First inode: 11
+First inode: 64
Inode size: 128
Default directory hash: half_md4

@@ -648,9 +648,9 @@ Group 0: (Blocks 1-1024)
Reserved GDT blocks at 8-258
Block bitmap at 260 (+259), Inode bitmap at 261 (+260)
Inode table at 262-293 (+261)
- 718 free blocks, 245 free inodes, 2 directories
+ 718 free blocks, 192 free inodes, 2 directories
Free blocks: 259, 308-1024
- Free inodes: 12-256
+ Free inodes: 65-256
Group 1: (Blocks 1025-2048)
Backup superblock at 1025, Group descriptors at 1026-1031
Reserved GDT blocks at 1032-1282
diff --git a/tests/t_32to64bit_meta/expect b/tests/t_32to64bit_meta/expect
index 28e328c524a8..eb5b79e1fe9a 100644
--- a/tests/t_32to64bit_meta/expect
+++ b/tests/t_32to64bit_meta/expect
@@ -34,7 +34,7 @@ Change in FS metadata:
Reserved block count: 26214
-Free blocks: 858
+Free blocks: 852
- Free inodes: 65046
+ Free inodes: 64993
First block: 1
Block size: 1024
Fragment size: 1024
diff --git a/tests/t_32to64bit_move_itable/expect b/tests/t_32to64bit_move_itable/expect
index e4fa55432bb3..4f9aa9ef7922 100644
--- a/tests/t_32to64bit_move_itable/expect
+++ b/tests/t_32to64bit_move_itable/expect
@@ -34,7 +34,7 @@ Change in FS metadata:
Reserved block count: 39321
-Free blocks: 764
+Free blocks: 734
- Free inodes: 97566
+ Free inodes: 97513
First block: 1
Block size: 1024
Fragment size: 1024
diff --git a/tests/t_64to32bit/expect b/tests/t_64to32bit/expect
index 6d8ff8011a7c..2af0227b891e 100644
--- a/tests/t_64to32bit/expect
+++ b/tests/t_64to32bit/expect
@@ -34,7 +34,7 @@ Change in FS metadata:
Reserved block count: 26214
-Free blocks: 571
+Free blocks: 589
- Free inodes: 65048
+ Free inodes: 64995
First block: 1
Block size: 1024
Fragment size: 1024
diff --git a/tests/t_64to32bit_meta/expect b/tests/t_64to32bit_meta/expect
index d6e2dccc894b..7e40a99ae8ec 100644
--- a/tests/t_64to32bit_meta/expect
+++ b/tests/t_64to32bit_meta/expect
@@ -37,7 +37,7 @@ Change in FS metadata:
Reserved block count: 26214
-Free blocks: 852
+Free blocks: 858
- Free inodes: 65046
+ Free inodes: 64993
First block: 1
Block size: 1024
Fragment size: 1024
diff --git a/tests/t_disable_mcsum_noinitbg/expect b/tests/t_disable_mcsum_noinitbg/expect
index a022631d1706..3c405e770767 100644
--- a/tests/t_disable_mcsum_noinitbg/expect
+++ b/tests/t_disable_mcsum_noinitbg/expect
@@ -40,10 +40,10 @@ Change in FS metadata:
Block bitmap at 262 (+261)
Inode bitmap at 278 (+277)
Inode table at 294-549 (+293)
-- 21 free blocks, 536 free inodes, 2 directories, 536 unused inodes
-+ 21 free blocks, 536 free inodes, 2 directories
+- 21 free blocks, 483 free inodes, 2 directories, 483 unused inodes
++ 21 free blocks, 483 free inodes, 2 directories
Free blocks: 4413-4433
- Free inodes: 489-1024
+ Free inodes: 542-1024
-Group 1: (Blocks 8193-16384) [INODE_UNINIT]
+Group 1: (Blocks 8193-16384)
Backup superblock at 8193, Group descriptors at 8194-8197
diff --git a/tests/t_enable_mcsum/expect b/tests/t_enable_mcsum/expect
index 2ee3c279c42b..6ed16ded0798 100644
--- a/tests/t_enable_mcsum/expect
+++ b/tests/t_enable_mcsum/expect
@@ -47,7 +47,7 @@ Change in FS metadata:
Reserved block count: 26214
-Free blocks: 571
+Free blocks: 568
- Free inodes: 65048
+ Free inodes: 64995
First block: 1
Block size: 1024
@@ -33,6 +33,7 @@
@@ -62,11 +62,11 @@ Change in FS metadata:
Block bitmap at 262 (+261)
Inode bitmap at 278 (+277)
Inode table at 294-549 (+293)
-- 21 free blocks, 536 free inodes, 2 directories, 536 unused inodes
+- 21 free blocks, 483 free inodes, 2 directories, 483 unused inodes
- Free blocks: 4413-4433
-+ 18 free blocks, 536 free inodes, 2 directories, 536 unused inodes
++ 18 free blocks, 483 free inodes, 2 directories, 483 unused inodes
+ Free blocks: 4413, 4417-4433
- Free inodes: 489-1024
+ Free inodes: 542-1024
Group 1: (Blocks 8193-16384) [INODE_UNINIT]
Backup superblock at 8193, Group descriptors at 8194-8197
Pass 1: Checking inodes, blocks, and sizes
diff --git a/tests/t_enable_mcsum_ext3/expect b/tests/t_enable_mcsum_ext3/expect
index 5460482a0d6d..fae36821fea9 100644
--- a/tests/t_enable_mcsum_ext3/expect
+++ b/tests/t_enable_mcsum_ext3/expect
@@ -49,9 +49,9 @@ Change in FS metadata:
Reserved GDT blocks at 4-259
Block bitmap at 260 (+259)
@@ -45,7 +46,7 @@
- 7789 free blocks, 1013 free inodes, 2 directories
+ 7789 free blocks, 960 free inodes, 2 directories
Free blocks: 404-8192
- Free inodes: 12-1024
+ Free inodes: 65-1024
-Group 1: (Blocks 8193-16384)
+Group 1: (Blocks 8193-16384) [ITABLE_ZEROED]
Backup superblock at 8193, Group descriptors at 8194-8195
diff --git a/tests/t_enable_mcsum_initbg/expect b/tests/t_enable_mcsum_initbg/expect
index d3b444436f84..c13c9785dffd 100644
--- a/tests/t_enable_mcsum_initbg/expect
+++ b/tests/t_enable_mcsum_initbg/expect
@@ -47,7 +47,7 @@ Change in FS metadata:
Reserved block count: 26214
-Free blocks: 571
+Free blocks: 568
- Free inodes: 65048
+ Free inodes: 64995
First block: 1
Block size: 1024
@@ -33,6 +33,7 @@
@@ -69,11 +69,11 @@ Change in FS metadata:
Block bitmap at 262 (+261)
Inode bitmap at 278 (+277)
Inode table at 294-549 (+293)
-- 21 free blocks, 536 free inodes, 2 directories
+- 21 free blocks, 483 free inodes, 2 directories
- Free blocks: 4413-4433
-+ 18 free blocks, 536 free inodes, 2 directories, 536 unused inodes
++ 18 free blocks, 483 free inodes, 2 directories, 483 unused inodes
+ Free blocks: 4413, 4417-4433
- Free inodes: 489-1024
+ Free inodes: 542-1024
-Group 1: (Blocks 8193-16384)
+Group 1: (Blocks 8193-16384) [INODE_UNINIT, ITABLE_ZEROED]
Backup superblock at 8193, Group descriptors at 8194-8197
diff --git a/tests/t_uninit_bg_rm/expect b/tests/t_uninit_bg_rm/expect
index 61e9eaa88219..ac8b68ee93bf 100644
--- a/tests/t_uninit_bg_rm/expect
+++ b/tests/t_uninit_bg_rm/expect
@@ -7,7 +7,7 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/65536 files (0.0% non-contiguous), 52294/1048576 blocks
+test_filesys: 64/65536 files (0.0% non-contiguous), 52294/1048576 blocks

mke2fs -q -t ext4 -O bigalloc -F -o Linux -b 1024 -C 8192 test.img 10G
tune2fs -f -O ^uninit_bg test.img
@@ -18,4 +18,4 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 11/655360 files (0.0% non-contiguous), 199864/10485760 blocks
+test_filesys: 64/655360 files (0.0% non-contiguous), 199864/10485760 blocks
--
2.1.4


2015-08-26 16:22:58

by Jan Kara

[permalink] [raw]
Subject: [PATCH 16/21] ext2fs: Remove old block mapping function

There is an old unused block mapping function in libext2fs. Just remove
it since the new one provides superior functionality.

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/bmove.c | 167 ----------------------------------------------------
lib/ext2fs/ext2fs.h | 16 -----
2 files changed, 183 deletions(-)
delete mode 100644 lib/ext2fs/bmove.c

diff --git a/lib/ext2fs/bmove.c b/lib/ext2fs/bmove.c
deleted file mode 100644
index e2ea405a5910..000000000000
--- a/lib/ext2fs/bmove.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * bmove.c --- Move blocks around to make way for a particular
- * filesystem structure.
- *
- * Copyright (C) 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Library
- * General Public License, version 2.
- * %End-Header%
- */
-
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#include "ext2_fs.h"
-#include "ext2fsP.h"
-
-struct process_block_struct {
- ext2_ino_t ino;
- struct ext2_inode * inode;
- ext2fs_block_bitmap reserve;
- ext2fs_block_bitmap alloc_map;
- errcode_t error;
- char *buf;
- int add_dir;
- int flags;
-};
-
-static int process_block(ext2_filsys fs, blk64_t *block_nr,
- e2_blkcnt_t blockcnt, blk64_t ref_block,
- int ref_offset, void *priv_data)
-{
- struct process_block_struct *pb;
- errcode_t retval;
- int ret;
- blk64_t block, orig;
-
- pb = (struct process_block_struct *) priv_data;
- block = orig = *block_nr;
- ret = 0;
-
- /*
- * Let's see if this is one which we need to relocate
- */
- if (ext2fs_test_block_bitmap2(pb->reserve, block)) {
- do {
- if (++block >= ext2fs_blocks_count(fs->super))
- block = fs->super->s_first_data_block;
- if (block == orig) {
- pb->error = EXT2_ET_BLOCK_ALLOC_FAIL;
- return BLOCK_ABORT;
- }
- } while (ext2fs_test_block_bitmap2(pb->reserve, block) ||
- ext2fs_test_block_bitmap2(pb->alloc_map, block));
-
- retval = io_channel_read_blk64(fs->io, orig, 1, pb->buf);
- if (retval) {
- pb->error = retval;
- return BLOCK_ABORT;
- }
- retval = io_channel_write_blk64(fs->io, block, 1, pb->buf);
- if (retval) {
- pb->error = retval;
- return BLOCK_ABORT;
- }
- *block_nr = block;
- ext2fs_mark_block_bitmap2(pb->alloc_map, block);
- ret = BLOCK_CHANGED;
- if (pb->flags & EXT2_BMOVE_DEBUG)
- printf("ino=%u, blockcnt=%lld, %llu->%llu\n",
- (unsigned) pb->ino, blockcnt,
- (unsigned long long) orig,
- (unsigned long long) block);
- }
- if (pb->add_dir) {
- retval = ext2fs_add_dir_block2(fs->dblist, pb->ino,
- block, blockcnt);
- if (retval) {
- pb->error = retval;
- ret |= BLOCK_ABORT;
- }
- }
- return ret;
-}
-
-errcode_t ext2fs_move_blocks(ext2_filsys fs,
- ext2fs_block_bitmap reserve,
- ext2fs_block_bitmap alloc_map,
- int flags)
-{
- ext2_ino_t ino;
- struct ext2_inode inode;
- errcode_t retval;
- struct process_block_struct pb;
- ext2_inode_scan scan;
- char *block_buf;
-
- retval = ext2fs_open_inode_scan(fs, 0, &scan);
- if (retval)
- return retval;
-
- pb.reserve = reserve;
- pb.error = 0;
- pb.alloc_map = alloc_map ? alloc_map : fs->block_map;
- pb.flags = flags;
-
- retval = ext2fs_get_array(4, fs->blocksize, &block_buf);
- if (retval)
- return retval;
- pb.buf = block_buf + fs->blocksize * 3;
-
- /*
- * If GET_DBLIST is set in the flags field, then we should
- * gather directory block information while we're doing the
- * block move.
- */
- if (flags & EXT2_BMOVE_GET_DBLIST) {
- if (fs->dblist) {
- ext2fs_free_dblist(fs->dblist);
- fs->dblist = NULL;
- }
- retval = ext2fs_init_dblist(fs, 0);
- if (retval)
- return retval;
- }
-
- retval = ext2fs_get_next_inode(scan, &ino, &inode);
- if (retval)
- return retval;
-
- while (ino) {
- if ((inode.i_links_count == 0) ||
- !ext2fs_inode_has_valid_blocks2(fs, &inode))
- goto next;
-
- pb.ino = ino;
- pb.inode = &inode;
-
- pb.add_dir = (LINUX_S_ISDIR(inode.i_mode) &&
- flags & EXT2_BMOVE_GET_DBLIST);
-
- retval = ext2fs_block_iterate3(fs, ino, 0, block_buf,
- process_block, &pb);
- if (retval)
- return retval;
- if (pb.error)
- return pb.error;
-
- next:
- retval = ext2fs_get_next_inode(scan, &ino, &inode);
- if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
- goto next;
- }
- return 0;
-}
-
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index e76ceaa699e6..de4b8c2f7013 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -344,14 +344,6 @@ struct struct_ext2_filsys {
#define BLOCK_COUNT_TIND (-3)
#define BLOCK_COUNT_TRANSLATOR (-4)

-#if 0
-/*
- * Flags for ext2fs_move_blocks
- */
-#define EXT2_BMOVE_GET_DBLIST 0x0001
-#define EXT2_BMOVE_DEBUG 0x0002
-#endif
-
/*
* Generic (non-filesystem layout specific) extents structure
*/
@@ -948,14 +940,6 @@ errcode_t ext2fs_map_cluster_block(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode, blk64_t lblk,
blk64_t *pblk);

-#if 0
-/* bmove.c */
-extern errcode_t ext2fs_move_blocks(ext2_filsys fs,
- ext2fs_block_bitmap reserve,
- ext2fs_block_bitmap alloc_map,
- int flags);
-#endif

2015-08-26 16:22:58

by Jan Kara

[permalink] [raw]
Subject: [PATCH 21/21] resize2fs: Use libextfs2 helpers for resizing

Change resize2fs to use ext2fs_move_blocks() and ext2fs_move_inodes() to
do resizing and thus avoid unnecessary code duplication. This results in
a quite big rewrite of the resize code but hopefully the result is
worth it.

Since location of some group metadata changes in some tests, update the
expected outputs.

Signed-off-by: Jan Kara <[email protected]>
---
resize/online.c | 14 +-
resize/resize2fs.c | 2323 ++++++++--------------------------
resize/resize2fs.h | 15 +-
tests/r_expand_full/expect | 20 +-
tests/t_32to64bit_expand_full/expect | 20 +-
5 files changed, 578 insertions(+), 1814 deletions(-)

diff --git a/resize/online.c b/resize/online.c
index 46d86b0f3c8d..d202c0e92e6e 100644
--- a/resize/online.c
+++ b/resize/online.c
@@ -197,6 +197,12 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
return retval;
}

+ retval = validate_fs_size(fs, new_size);
+ if (retval) {
+ close(fd);
+ return retval;
+ }
+
retval = ext2fs_dup_handle(fs, &new_fs);
if (retval) {
close(fd);
@@ -214,7 +220,13 @@ errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
* but at least it allows on-line resizing to function.
*/
new_fs->super->s_feature_incompat &= ~EXT4_FEATURE_INCOMPAT_FLEX_BG;
- retval = adjust_fs_info(new_fs, fs, 0, *new_size);
+ retval = adjust_fs_info(new_fs, fs, *new_size);
+ if (retval) {
+ close(fd);
+ return retval;
+ }
+
+ retval = alloc_new_groups(new_fs, fs->group_desc_count);
if (retval) {
close(fd);
return retval;
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 70c963783f3f..51f013e4be64 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -13,24 +13,36 @@
*/

/*
- * Resizing a filesystem consists of the following phases:
+ * Shrinking a filesystem consists of the following phases:
*
- * 1. Adjust superblock and write out new parts of the inode
- * table
- * 2. Determine blocks which need to be relocated, and copy the
- * contents of blocks from their old locations to the new ones.
- * 3. Scan the inode table, doing the following:
- * a. If blocks have been moved, update the block
- * pointers in the inodes and indirect blocks to
- * point at the new block locations.
- * b. If parts of the inode table need to be evacuated,
- * copy inodes from their old locations to their
- * new ones.
- * c. If (b) needs to be done, note which blocks contain
- * directory information, since we will need to
- * update the directory information.
- * 4. Update the directory blocks with the new inode locations.
- * 5. Move the inode tables, if necessary.
+ * 1. We validate whether filesystem size is sane
+ * 2. We identify blocks which need moving (beyond new end of the
+ * filesystem, under new sb backup if sparse_super2 is enabled) and
+ * move them. ext2fs_move_blocks() also takes care of updating all the
+ * block references.
+ * 3. We identify inodes which need moving (beyond end of the new
+ * filesystem) and move them. ext2fs_move_inodes() also takes care of
+ * updating all the inode references.
+ * 4. We create new fs structure with updated number of block groups.
+ * 5. We free metadata of groups that will be removed (with flex_bg
+ * feature they can be allocated inside area of the new filesystem).
+ * 6. We free backup group descriptor blocks which are not needed anymore.
+ * 7. We recompute group & global allocation counters.
+ * 8. We rewrite resize inode to contain now reserved blocks for backup
+ * group descriptors.
+ *
+ * Growing a filesystem consists of the following phases:
+ * 1. We validate whether filesystem size is sane
+ * 2. We create new fs structure with updated number of block groups.
+ * 3. We allocate and initialize bitmaps & inode tables for new groups.
+ * 4. We identify blocks that need moving to make space for new group
+ * descriptor backups and move them. ext2fs_move_blocks() also takes
+ * care of updating all the block references.
+ * 5. We free space of group descriptor backups that aren't needed anymore
+ * (happens with sparse_super2 feature).
+ * 6. We recompute group & global allocation counters.
+ * 7. We rewrite resize inode to contain now reserved blocks for backup
+ * group descriptors.
*/

#include "config.h"
@@ -41,21 +53,17 @@
#define RESIZE2FS_DEBUG
#endif

-static void fix_uninit_block_bitmaps(ext2_filsys fs);
-static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size);
-static errcode_t blocks_to_move(ext2_resize_t rfs);
-static errcode_t block_mover(ext2_resize_t rfs);
-static errcode_t inode_scan_and_fix(ext2_resize_t rfs);
-static errcode_t inode_ref_fix(ext2_resize_t rfs);
-static errcode_t move_itables(ext2_resize_t rfs);
+static void fix_uninit_block_bitmaps(ext2_filsys fs, dgrp_t start);
static errcode_t fix_resize_inode(ext2_filsys fs);
static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs);
-static errcode_t fix_sb_journal_backup(ext2_filsys fs);
static errcode_t mark_table_blocks(ext2_filsys fs,
ext2fs_block_bitmap bmap);
static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs);
-static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
- ext2fs_block_bitmap meta_bmap);
+static errcode_t free_group_metadata(ext2_resize_t rfs);
+static errcode_t prepare_shrink(ext2_filsys fs, blk64_t new_size);
+static errcode_t init_new_itables(ext2_resize_t rfs);
+static errcode_t free_gd_blocks(ext2_resize_t rfs);
+static errcode_t make_space_for_gd(ext2_resize_t rfs);

/*
* Some helper CPP macros
@@ -101,7 +109,6 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
fs->priv_data = rfs;
rfs->old_fs = fs;
rfs->flags = flags;
- rfs->itable_buf = 0;
rfs->progress = progress;

init_resource_track(&overall_track, "overall resize2fs", fs->io);
@@ -116,64 +123,76 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
ext2fs_flush(fs);

init_resource_track(&rtrack, "fix_uninit_block_bitmaps 1", fs->io);
- fix_uninit_block_bitmaps(fs);
+ fix_uninit_block_bitmaps(fs, 0);
print_resource_track(rfs, &rtrack, fs->io);
- retval = ext2fs_dup_handle(fs, &rfs->new_fs);
- if (retval)
- goto errout;

- init_resource_track(&rtrack, "adjust_superblock", fs->io);
- retval = adjust_superblock(rfs, *new_size);
+ retval = validate_fs_size(fs, new_size);
if (retval)
goto errout;
- print_resource_track(rfs, &rtrack, fs->io);
-
- init_resource_track(&rtrack, "fix_uninit_block_bitmaps 2", fs->io);
- fix_uninit_block_bitmaps(rfs->new_fs);
- print_resource_track(rfs, &rtrack, fs->io);
- /* Clear the block bitmap uninit flag for the last block group */
- ext2fs_bg_flags_clear(rfs->new_fs, rfs->new_fs->group_desc_count - 1,
- EXT2_BG_BLOCK_UNINIT);

- *new_size = ext2fs_blocks_count(rfs->new_fs->super);
+ if (*new_size < ext2fs_blocks_count(fs->super)) {
+ init_resource_track(&rtrack, "prepare_shrink", fs->io);
+ retval = prepare_shrink(fs, *new_size);
+ if (retval)
+ goto errout;
+ print_resource_track(rfs, &rtrack, fs->io);
+ }

- init_resource_track(&rtrack, "blocks_to_move", fs->io);
- retval = blocks_to_move(rfs);
+ retval = ext2fs_dup_handle(fs, &rfs->new_fs);
if (retval)
goto errout;
- print_resource_track(rfs, &rtrack, fs->io);
-
-#ifdef RESIZE2FS_DEBUG
- if (rfs->flags & RESIZE_DEBUG_BMOVE)
- printf("Number of free blocks: %llu/%llu, Needed: %llu\n",
- ext2fs_free_blocks_count(rfs->old_fs->super),
- ext2fs_free_blocks_count(rfs->new_fs->super),
- rfs->needed_blocks);
-#endif

- init_resource_track(&rtrack, "block_mover", fs->io);
- retval = block_mover(rfs);
+ init_resource_track(&rtrack, "adjust_fs_info", fs->io);
+ retval = adjust_fs_info(rfs->new_fs, fs, *new_size);
if (retval)
goto errout;
print_resource_track(rfs, &rtrack, fs->io);

- init_resource_track(&rtrack, "inode_scan_and_fix", fs->io);
- retval = inode_scan_and_fix(rfs);
- if (retval)
- goto errout;
- print_resource_track(rfs, &rtrack, fs->io);
+ if (*new_size > ext2fs_blocks_count(fs->super)) {
+ retval = alloc_new_groups(rfs->new_fs,
+ rfs->old_fs->group_desc_count);
+ if (retval)
+ goto errout;

- init_resource_track(&rtrack, "inode_ref_fix", fs->io);
- retval = inode_ref_fix(rfs);
- if (retval)
- goto errout;
- print_resource_track(rfs, &rtrack, fs->io);
+ retval = init_new_itables(rfs);
+ if (retval)
+ goto errout;

- init_resource_track(&rtrack, "move_itables", fs->io);
- retval = move_itables(rfs);
- if (retval)
- goto errout;
- print_resource_track(rfs, &rtrack, fs->io);
+ init_resource_track(&rtrack, "fix_uninit_block_bitmaps 2",
+ fs->io);
+ fix_uninit_block_bitmaps(rfs->new_fs, fs->group_desc_count);
+ print_resource_track(rfs, &rtrack, fs->io);
+ }
+
+ /* Clear the block bitmap uninit flag for the last block group */
+ ext2fs_bg_flags_clear(rfs->new_fs, rfs->new_fs->group_desc_count - 1,
+ EXT2_BG_BLOCK_UNINIT);
+
+ if (*new_size > ext2fs_blocks_count(fs->super)) {
+ init_resource_track(&rtrack, "make_space_for_gd", fs->io);
+ retval = make_space_for_gd(rfs);
+ if (retval)
+ goto errout;
+ print_resource_track(rfs, &rtrack, fs->io);
+
+ retval = clear_sparse_super2_last_group(rfs);
+ if (retval)
+ goto errout;
+ } else {
+ init_resource_track(&rtrack, "free_group_metadata", fs->io);
+ /* Now free metadata of groups we don't need anymore */
+ retval = free_group_metadata(rfs);
+ if (retval)
+ goto errout;
+ print_resource_track(rfs, &rtrack, fs->io);
+
+ init_resource_track(&rtrack, "free_gd_blocks", fs->io);
+ /* Free backup group descriptors we don't need */
+ retval = free_gd_blocks(rfs);
+ if (retval)
+ goto errout;
+ print_resource_track(rfs, &rtrack, fs->io);
+ }

init_resource_track(&rtrack, "calculate_summary_stats", fs->io);
retval = ext2fs_calculate_summary_stats(rfs->new_fs);
@@ -187,22 +206,15 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
goto errout;
print_resource_track(rfs, &rtrack, fs->io);

- init_resource_track(&rtrack, "fix_sb_journal_backup", fs->io);
- retval = fix_sb_journal_backup(rfs->new_fs);
- if (retval)
- goto errout;
- print_resource_track(rfs, &rtrack, fs->io);
-
- retval = clear_sparse_super2_last_group(rfs);
- if (retval)
- goto errout;
-
retval = ext2fs_set_gdt_csum(rfs->new_fs);
if (retval)
goto errout;

rfs->new_fs->super->s_state &= ~EXT2_ERROR_FS;
rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
+ ext2fs_mark_bb_dirty(rfs->new_fs);
+ ext2fs_mark_ib_dirty(rfs->new_fs);
+ ext2fs_mark_super_dirty(rfs->new_fs);

print_resource_track(rfs, &overall_track, fs->io);
retval = ext2fs_close_free(&rfs->new_fs);
@@ -213,12 +225,6 @@ errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,

ext2fs_free(rfs->old_fs);
rfs->old_fs = NULL;
- if (rfs->itable_buf)
- ext2fs_free_mem(&rfs->itable_buf);
- if (rfs->reserve_blocks)
- ext2fs_free_block_bitmap(rfs->reserve_blocks);
- if (rfs->move_blocks)
- ext2fs_free_block_bitmap(rfs->move_blocks);
ext2fs_free_mem(&rfs);

return 0;
@@ -228,8 +234,6 @@ errout:
ext2fs_free(rfs->new_fs);
rfs->new_fs = NULL;
}
- if (rfs->itable_buf)
- ext2fs_free_mem(&rfs->itable_buf);
ext2fs_free_mem(&rfs);
return retval;
}
@@ -255,16 +259,15 @@ static void adjust_reserved_gdt_blocks(ext2_filsys old_fs, ext2_filsys fs)
/*
* Clean up the bitmaps for unitialized bitmaps
*/
-static void fix_uninit_block_bitmaps(ext2_filsys fs)
+static void fix_uninit_block_bitmaps(ext2_filsys fs, dgrp_t start)
{
blk64_t blk, lblk;
dgrp_t g;
- int i;

if (!ext2fs_has_group_desc_csum(fs))
return;

- for (g=0; g < fs->group_desc_count; g++) {
+ for (g = start; g < fs->group_desc_count; g++) {
if (!(ext2fs_bg_flags_test(fs, g, EXT2_BG_BLOCK_UNINIT)))
continue;

@@ -278,10 +281,9 @@ static void fix_uninit_block_bitmaps(ext2_filsys fs)
ext2fs_block_bitmap_loc(fs, g));
ext2fs_mark_block_bitmap2(fs->block_map,
ext2fs_inode_bitmap_loc(fs, g));
- for (i = 0, blk = ext2fs_inode_table_loc(fs, g);
- i < (unsigned int) fs->inode_blocks_per_group;
- i++, blk++)
- ext2fs_mark_block_bitmap2(fs->block_map, blk);
+ ext2fs_mark_block_bitmap_range2(fs->block_map,
+ ext2fs_inode_table_loc(fs, g),
+ fs->inode_blocks_per_group);
}
}

@@ -297,21 +299,73 @@ static void fix_uninit_block_bitmaps(ext2_filsys fs)
*/

/*
- * If the group descriptor's bitmap and inode table blocks are valid,
- * release them in the new filesystem data structure, and mark them as
- * reserved so the old inode table blocks don't get overwritten.
+ * Check whether requested filesystem size is sane. Round it down in case the
+ * last group would be too small.
+ */
+errcode_t validate_fs_size(ext2_filsys fs, blk64_t *new_sizep)
+{
+ blk64_t new_size = *new_sizep;
+ dgrp_t groups;
+ blk64_t desc_blocks;
+ blk64_t overhead = 0, rem;
+ unsigned long long new_inodes; /* u64 to check for overflow */
+
+retry:
+ groups = ext2fs_div64_ceil(new_size - fs->super->s_first_data_block,
+ EXT2_BLOCKS_PER_GROUP(fs->super));
+ if (groups == 0)
+ return EXT2_ET_TOOSMALL;
+ desc_blocks = ext2fs_div_ceil(groups, EXT2_DESC_PER_BLOCK(fs->super));
+
+ /*
+ * Overhead is the number of bookkeeping blocks per group. It
+ * includes the superblock backup, the group descriptor
+ * backups, the inode bitmap, the block bitmap, and the inode
+ * table.
+ */
+ overhead = 2 + fs->inode_blocks_per_group;
+ if (ext2fs_bg_has_super(fs, groups - 1))
+ overhead += 1 + desc_blocks + fs->super->s_reserved_gdt_blocks;
+
+ /*
+ * See if the last group is big enough to support the
+ * necessary data structures. If not, we need to get rid of
+ * it.
+ */
+ rem = (new_size - fs->super->s_first_data_block) %
+ fs->super->s_blocks_per_group;
+ if (groups == 1 && rem && rem < overhead)
+ return EXT2_ET_TOOSMALL;
+ if (groups > 1 && rem && rem < overhead + 50) {
+ new_size -= rem;
+ goto retry;
+ }
+
+ new_inodes = ((unsigned long long)fs->super->s_inodes_per_group) *
+ groups;
+ if (new_inodes > ~0U) {
+ fprintf(stderr, _("inodes (%llu) must be less than %u"),
+ new_inodes, ~0U);
+ return EXT2_ET_TOO_MANY_INODES;
+ }
+
+ *new_sizep = new_size;
+ return 0;
+}
+
+/*
+ * If the group descriptor's bitmap and inode table blocks are valid, release
+ * them. With FLEX_BG this may actually free some space in the shrunk
+ * filesystem.
*/
-static errcode_t free_gdp_blocks(ext2_filsys fs,
- ext2fs_block_bitmap reserve_blocks,
- ext2_filsys old_fs,
- dgrp_t group)
+static errcode_t free_group_metadata(ext2_resize_t rfs)
{
+ ext2_filsys fs = rfs->new_fs, old_fs = rfs->old_fs;
blk64_t blk;
int j;
dgrp_t i;
ext2fs_block_bitmap bg_map = NULL;
errcode_t retval = 0;
- dgrp_t count = old_fs->group_desc_count - fs->group_desc_count;

/* If bigalloc, don't free metadata living in the same cluster */
if (EXT2FS_CLUSTER_RATIO(fs) > 1) {
@@ -324,22 +378,18 @@ static errcode_t free_gdp_blocks(ext2_filsys fs,
goto out;
}

- for (i = group; i < group + count; i++) {
+ for (i = fs->group_desc_count; i < old_fs->group_desc_count; i++) {
blk = ext2fs_block_bitmap_loc(old_fs, i);
if (blk &&
(blk < ext2fs_blocks_count(fs->super)) &&
- !(bg_map && ext2fs_test_block_bitmap2(bg_map, blk))) {
+ !(bg_map && ext2fs_test_block_bitmap2(bg_map, blk)))
ext2fs_block_alloc_stats2(fs, blk, -1);
- ext2fs_mark_block_bitmap2(reserve_blocks, blk);
- }

blk = ext2fs_inode_bitmap_loc(old_fs, i);
if (blk &&
(blk < ext2fs_blocks_count(fs->super)) &&
- !(bg_map && ext2fs_test_block_bitmap2(bg_map, blk))) {
+ !(bg_map && ext2fs_test_block_bitmap2(bg_map, blk)))
ext2fs_block_alloc_stats2(fs, blk, -1);
- ext2fs_mark_block_bitmap2(reserve_blocks, blk);
- }

blk = ext2fs_inode_table_loc(old_fs, i);
for (j = 0;
@@ -348,7 +398,6 @@ static errcode_t free_gdp_blocks(ext2_filsys fs,
(bg_map && ext2fs_test_block_bitmap2(bg_map, blk)))
continue;
ext2fs_block_alloc_stats2(fs, blk, -1);
- ext2fs_mark_block_bitmap2(reserve_blocks, blk);
}
}

@@ -359,250 +408,180 @@ out:
}

/*
- * This routine is shared by the online and offline resize routines.
- * All of the information which is adjusted in memory is done here.
+ * Prepare filesystem for shrinking - free up all space beyond new end of the
+ * filesystem and space needed for new group descriptor backups. Also move
+ * inodes that are in removed block groups into block groups that remain.
*/
-errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs,
- ext2fs_block_bitmap reserve_blocks, blk64_t new_size)
+static errcode_t prepare_shrink(ext2_filsys fs, blk64_t new_size)
{
+ dgrp_t groups, i;
+ blk64_t blk;
+ blk64_t blk_per_g = EXT2_BLOCKS_PER_GROUP(fs->super);
+ ext2fs_inode_bitmap move_inodes = NULL;
+ ext2fs_block_bitmap move_blocks = NULL;
+ ext2_ino_t old_inos, new_inos, ino;
errcode_t retval;
- blk64_t overhead = 0;
- blk64_t rem;
- blk64_t blk, group_block;
- blk64_t real_end;
- blk64_t old_numblocks, numblocks, adjblocks;
- unsigned long i, j, old_desc_blocks;
- unsigned int meta_bg, meta_bg_size;
- int has_super, csum_flag;
- unsigned long long new_inodes; /* u64 to check for overflow */
- double percent;
-
- ext2fs_blocks_count_set(fs->super, new_size);
-
-retry:
- fs->group_desc_count = ext2fs_div64_ceil(ext2fs_blocks_count(fs->super) -
- fs->super->s_first_data_block,
- EXT2_BLOCKS_PER_GROUP(fs->super));
- if (fs->group_desc_count == 0)
- return EXT2_ET_TOOSMALL;
- fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
- EXT2_DESC_PER_BLOCK(fs->super));
-
- /*
- * Overhead is the number of bookkeeping blocks per group. It
- * includes the superblock backup, the group descriptor
- * backups, the inode bitmap, the block bitmap, and the inode
- * table.
- */
- overhead = (int) (2 + fs->inode_blocks_per_group);

- if (ext2fs_bg_has_super(fs, fs->group_desc_count - 1))
- overhead += 1 + fs->desc_blocks +
- fs->super->s_reserved_gdt_blocks;
+ groups = ext2fs_div64_ceil(new_size - fs->super->s_first_data_block,
+ blk_per_g);

+ retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"),
+ &move_blocks);
+ if (retval)
+ goto errout;
/*
- * See if the last group is big enough to support the
- * necessary data structures. If not, we need to get rid of
- * it.
- */
- rem = (ext2fs_blocks_count(fs->super) - fs->super->s_first_data_block) %
- fs->super->s_blocks_per_group;
- if ((fs->group_desc_count == 1) && rem && (rem < overhead))
- return EXT2_ET_TOOSMALL;
- if ((fs->group_desc_count > 1) && rem && (rem < overhead+50)) {
- ext2fs_blocks_count_set(fs->super,
- ext2fs_blocks_count(fs->super) - rem);
- goto retry;
- }
- /*
- * Adjust the number of inodes
+ * Update the location of the backup superblocks if the sparse_super2
+ * feature is enabled. Mark new backup descriptor blocks in bitmap
+ * to move
*/
- new_inodes =(unsigned long long) fs->super->s_inodes_per_group * fs->group_desc_count;
- if (new_inodes > ~0U) {
- fprintf(stderr, _("inodes (%llu) must be less than %u"),
- new_inodes, ~0U);
- return EXT2_ET_TOO_MANY_INODES;
+ if (fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2 &&
+ groups < fs->group_desc_count) {
+ dgrp_t last_bg = groups - 1;
+ dgrp_t old_last_bg = fs->group_desc_count - 1;
+
+ if (last_bg > 1 && fs->super->s_backup_bgs[1] == old_last_bg) {
+ blk64_t desc_blocks = 0;
+ dgrp_t meta_bg, meta_bg_size;
+
+ meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
+ meta_bg = last_bg / meta_bg_size;
+
+ if (!(fs->super->s_feature_incompat &
+ EXT2_FEATURE_INCOMPAT_META_BG) ||
+ (meta_bg < fs->super->s_first_meta_bg)) {
+ desc_blocks = ext2fs_div_ceil(groups,
+ EXT2_DESC_PER_BLOCK(fs->super));
+ } else {
+ if (((last_bg % meta_bg_size) == 0) ||
+ ((last_bg % meta_bg_size) == 1) ||
+ ((last_bg % meta_bg_size) == (meta_bg_size-1)))
+ desc_blocks = 1;
+ }
+ fs->super->s_backup_bgs[1] = last_bg;
+ ext2fs_mark_block_bitmap_range2(move_blocks,
+ last_bg * blk_per_g + fs->super->s_first_data_block,
+ 1 + desc_blocks);
+ }
+ if (fs->super->s_backup_bgs[0] > last_bg)
+ fs->super->s_backup_bgs[0] = 0;
+ if (fs->super->s_backup_bgs[1] > last_bg)
+ fs->super->s_backup_bgs[1] = 0;
}
- fs->super->s_inodes_count = fs->super->s_inodes_per_group *
- fs->group_desc_count;
-
- /*
- * Adjust the number of free blocks
- */
- blk = ext2fs_blocks_count(old_fs->super);
- if (blk > ext2fs_blocks_count(fs->super))
- ext2fs_free_blocks_count_set(fs->super,
- ext2fs_free_blocks_count(fs->super) -
- (blk - ext2fs_blocks_count(fs->super)));
- else
- ext2fs_free_blocks_count_set(fs->super,
- ext2fs_free_blocks_count(fs->super) +
- (ext2fs_blocks_count(fs->super) - blk));
-
- /*
- * Adjust the number of reserved blocks
- */
- percent = (ext2fs_r_blocks_count(old_fs->super) * 100.0) /
- ext2fs_blocks_count(old_fs->super);
- ext2fs_r_blocks_count_set(fs->super,
- (percent * ext2fs_blocks_count(fs->super) /
- 100.0));

+ /* Mark all blocks beyond new end of fs in bitmap to move */
+ ext2fs_mark_block_bitmap_range2(move_blocks, new_size,
+ ext2fs_blocks_count(fs->super) - new_size);
/*
- * Adjust the bitmaps for size
+ * Now have to we unmark metadata of groups which are going away since
+ * ext2fs_move_blocks() would allocate blocks for them
*/
- retval = ext2fs_resize_inode_bitmap2(fs->super->s_inodes_count,
- fs->super->s_inodes_count,
- fs->inode_map);
- if (retval) goto errout;
-
- real_end = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count) - 1 +
- fs->super->s_first_data_block;
- retval = ext2fs_resize_block_bitmap2(new_size - 1,
- real_end, fs->block_map);
- if (retval) goto errout;
+ for (i = groups; i < fs->group_desc_count; i++) {
+ blk_t num_blocks;
+ blk64_t old_desc_blk, new_desc_blk;
+
+ ext2fs_super_and_bgd_loc2(fs, i, &blk, &old_desc_blk,
+ &new_desc_blk, &num_blocks);
+ if (blk) {
+ ext2fs_unmark_block_bitmap2(move_blocks, blk);
+ num_blocks--;
+ }
+ if (old_desc_blk)
+ blk = old_desc_blk;
+ else
+ blk = new_desc_blk;

- /*
- * If we are growing the file system, also grow the size of
- * the reserve_blocks bitmap
- */
- if (reserve_blocks && new_size > ext2fs_blocks_count(old_fs->super)) {
- retval = ext2fs_resize_block_bitmap2(new_size - 1,
- real_end, reserve_blocks);
- if (retval) goto errout;
- }
+ if (blk)
+ ext2fs_unmark_block_bitmap_range2(move_blocks, blk,
+ num_blocks);

- /*
- * Reallocate the group descriptors as necessary.
- */
- if (old_fs->desc_blocks != fs->desc_blocks) {
- retval = ext2fs_resize_mem(old_fs->desc_blocks *
- fs->blocksize,
- fs->desc_blocks * fs->blocksize,
- &fs->group_desc);
- if (retval)
- goto errout;
- if (fs->desc_blocks > old_fs->desc_blocks)
- memset((char *) fs->group_desc +
- (old_fs->desc_blocks * fs->blocksize), 0,
- (fs->desc_blocks - old_fs->desc_blocks) *
- fs->blocksize);
- }
+ /*
+ * Mark the blocks used for the inode table
+ */
+ blk = ext2fs_inode_table_loc(fs, i);
+ if (blk)
+ ext2fs_unmark_block_bitmap_range2(move_blocks, blk,
+ fs->inode_blocks_per_group);

- /*
- * If the resize_inode feature is set, and we are changing the
- * number of descriptor blocks, then adjust
- * s_reserved_gdt_blocks if possible to avoid needing to move
- * the inode table either now or in the future.
- */
- adjust_reserved_gdt_blocks(old_fs, fs);
+ /*
+ * Mark block used for the block bitmap
+ */
+ blk = ext2fs_block_bitmap_loc(fs, i);
+ if (blk)
+ ext2fs_unmark_block_bitmap2(move_blocks, blk);

- if ((fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) &&
- (fs->super->s_first_meta_bg > fs->desc_blocks)) {
- fs->super->s_feature_incompat &=
- ~EXT2_FEATURE_INCOMPAT_META_BG;
- fs->super->s_first_meta_bg = 0;
+ /*
+ * Mark block used for the inode bitmap
+ */
+ blk = ext2fs_inode_bitmap_loc(fs, i);
+ if (blk)
+ ext2fs_unmark_block_bitmap2(move_blocks, blk);
}

- /*
- * Update the location of the backup superblocks if the
- * sparse_super2 feature is enabled.
- */
- if (fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2) {
- dgrp_t last_bg = fs->group_desc_count - 1;
- dgrp_t old_last_bg = old_fs->group_desc_count - 1;
+ /* Map of blocks to move is done - let's move them */
+ retval = ext2fs_move_blocks(fs, move_blocks, NULL);
+ if (retval)
+ goto errout;

- if (last_bg > old_last_bg) {
- if (old_fs->group_desc_count == 1)
- fs->super->s_backup_bgs[0] = 1;
- if (old_fs->group_desc_count == 1 &&
- fs->super->s_backup_bgs[0])
- fs->super->s_backup_bgs[0] = last_bg;
- else if (fs->super->s_backup_bgs[1])
- fs->super->s_backup_bgs[1] = last_bg;
- } else if (last_bg < old_last_bg) {
- if (fs->super->s_backup_bgs[0] > last_bg)
- fs->super->s_backup_bgs[0] = 0;
- if (fs->super->s_backup_bgs[1] > last_bg)
- fs->super->s_backup_bgs[1] = 0;
- if (last_bg > 1 &&
- old_fs->super->s_backup_bgs[1] == old_last_bg)
- fs->super->s_backup_bgs[1] = last_bg;
- }
- }
+ /* Didn't remove any group? No need to move any inodes so we are done */
+ if (groups == fs->group_desc_count)
+ goto errout;

- /*
- * If we are shrinking the number of block groups, we're done
- * and can exit now.
- */
- if (old_fs->group_desc_count > fs->group_desc_count) {
- /*
- * Check the block groups that we are chopping off
- * and free any blocks associated with their metadata
- */
- retval = free_gdp_blocks(fs, reserve_blocks, old_fs,
- fs->group_desc_count);
+ /* Move inodes from groups that will be removed */
+ retval = ext2fs_allocate_inode_bitmap(fs, _("inodes to be moved"),
+ &move_inodes);
+ if (retval)
goto errout;
- }

- /*
- * Fix the count of the last (old) block group
- */
- old_numblocks = (ext2fs_blocks_count(old_fs->super) -
- old_fs->super->s_first_data_block) %
- old_fs->super->s_blocks_per_group;
- if (!old_numblocks)
- old_numblocks = old_fs->super->s_blocks_per_group;
- if (old_fs->group_desc_count == fs->group_desc_count) {
- numblocks = (ext2fs_blocks_count(fs->super) -
- fs->super->s_first_data_block) %
- fs->super->s_blocks_per_group;
- if (!numblocks)
- numblocks = fs->super->s_blocks_per_group;
- } else
- numblocks = fs->super->s_blocks_per_group;
- i = old_fs->group_desc_count - 1;
- ext2fs_bg_free_blocks_count_set(fs, i, ext2fs_bg_free_blocks_count(fs, i) + (numblocks - old_numblocks));
- ext2fs_group_desc_csum_set(fs, i);
+ old_inos = fs->group_desc_count * fs->super->s_inodes_per_group;
+ new_inos = groups * fs->super->s_inodes_per_group;
+ for (ino = new_inos; ino < old_inos; ino++)
+ ext2fs_mark_inode_bitmap2(move_inodes, ino);

- /*
- * If the number of block groups is staying the same, we're
- * done and can exit now. (If the number block groups is
- * shrinking, we had exited earlier.)
- */
- if (old_fs->group_desc_count >= fs->group_desc_count) {
- retval = 0;
- goto errout;
- }
+ retval = ext2fs_move_inodes(fs, move_inodes);
+errout:
+ if (move_inodes)
+ ext2fs_free_inode_bitmap(move_inodes);
+ if (move_blocks)
+ ext2fs_free_block_bitmap(move_blocks);
+ return retval;
+}
+
+/*
+ * Allocate space for group metadata (sb & descriptor backups, bitmaps,
+ * inode table)
+ */
+errcode_t alloc_new_groups(ext2_filsys fs, dgrp_t from)
+{
+ errcode_t retval;
+ unsigned long i;
+ int csum_flag;
+ ext2fs_block_bitmap merged_map = NULL;

/*
* Initialize the new block group descriptors
*/
- group_block = ext2fs_group_first_block2(fs,
- old_fs->group_desc_count);
csum_flag = ext2fs_has_group_desc_csum(fs);
if (!getenv("RESIZE2FS_FORCE_ITABLE_INIT") &&
access("/sys/fs/ext4/features/lazy_itable_init", F_OK) == 0)
lazy_itable_init = 1;
- if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
- old_desc_blocks = fs->super->s_first_meta_bg;
- else
- old_desc_blocks = fs->desc_blocks +
- fs->super->s_reserved_gdt_blocks;
+
+ retval = ext2fs_copy_bitmap(fs->block_map, &merged_map);
+ if (retval)
+ return retval;

/*
* If we changed the number of block_group descriptor blocks,
- * we need to make sure they are all marked as reserved in the
- * file systems's block allocation map.
+ * we need to make sure they are all marked as reserved so that
+ * ext2fs_allocate_group_table2() called a bit later doesn't use
+ * these blocks for new group's metadata. We mark the blocks as
+ * used in the block bitmap once we free them up.
*/
- for (i = 0; i < old_fs->group_desc_count; i++)
- ext2fs_reserve_super_and_bgd(fs, i, fs->block_map);
+ for (i = 0; i < from; i++)
+ ext2fs_reserve_super_and_bgd(fs, i, merged_map);

- for (i = old_fs->group_desc_count;
- i < fs->group_desc_count; i++) {
+ for (i = from; i < fs->group_desc_count; i++) {
memset(ext2fs_group_desc(fs, fs->group_desc, i), 0,
sizeof(struct ext2_group_desc));
- adjblocks = 0;

ext2fs_bg_flags_zap(fs, i);
if (csum_flag) {
@@ -614,115 +593,34 @@ retry:
fs->super->s_inodes_per_group);
}

- numblocks = ext2fs_group_blocks_count(fs, i);
- if ((i < fs->group_desc_count - 1) && csum_flag)
+ if ((i < fs->group_desc_count - 1) && csum_flag &&
+ !ext2fs_bg_has_super(fs, i))
ext2fs_bg_flags_set(fs, i, EXT2_BG_BLOCK_UNINIT);

- has_super = ext2fs_bg_has_super(fs, i);
- if (has_super) {
- ext2fs_block_alloc_stats2(fs, group_block, +1);
- adjblocks++;
- }
- meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
- meta_bg = i / meta_bg_size;
- if (!(fs->super->s_feature_incompat &
- EXT2_FEATURE_INCOMPAT_META_BG) ||
- (meta_bg < fs->super->s_first_meta_bg)) {
- if (has_super) {
- for (j=0; j < old_desc_blocks; j++)
- ext2fs_block_alloc_stats2(fs,
- group_block + 1 + j, +1);
- adjblocks += old_desc_blocks;
- }
- } else {
- if (has_super)
- has_super = 1;
- if (((i % meta_bg_size) == 0) ||
- ((i % meta_bg_size) == 1) ||
- ((i % meta_bg_size) == (meta_bg_size-1)))
- ext2fs_block_alloc_stats2(fs,
- group_block + has_super, +1);
- }
-
- adjblocks += 2 + fs->inode_blocks_per_group;
-
- numblocks -= adjblocks;
- ext2fs_free_blocks_count_set(fs->super,
- ext2fs_free_blocks_count(fs->super) - adjblocks);
- fs->super->s_free_inodes_count +=
- fs->super->s_inodes_per_group;
- ext2fs_bg_free_blocks_count_set(fs, i, numblocks);
- ext2fs_bg_free_inodes_count_set(fs, i,
- fs->super->s_inodes_per_group);
ext2fs_bg_used_dirs_count_set(fs, i, 0);
- ext2fs_group_desc_csum_set(fs, i);

- retval = ext2fs_allocate_group_table(fs, i, 0);
- if (retval) goto errout;
+ ext2fs_reserve_super_and_bgd(fs, i, fs->block_map);
+ ext2fs_reserve_super_and_bgd(fs, i, merged_map);

- group_block += fs->super->s_blocks_per_group;
+ retval = ext2fs_allocate_group_table2(fs, i, merged_map,
+ EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP);
+ if (retval)
+ goto errout;
}
- retval = 0;
-
- /*
- * Mark all of the metadata blocks as reserved so they won't
- * get allocated by the call to ext2fs_allocate_group_table()
- * in blocks_to_move(), where we allocate new blocks to
- * replace those allocation bitmap and inode table blocks
- * which have to get relocated to make space for an increased
- * number of the block group descriptors.
- */
- if (reserve_blocks)
- mark_table_blocks(fs, reserve_blocks);

errout:
- return (retval);
+ if (merged_map)
+ ext2fs_free_block_bitmap(merged_map);
+ return retval;
}

-/*
- * This routine adjusts the superblock and other data structures, both
- * in disk as well as in memory...
- */
-static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
+/* Initialize inode tables in new block groups. */
+static errcode_t init_new_itables(ext2_resize_t rfs)
{
- ext2_filsys fs = rfs->new_fs;
- int adj = 0;
errcode_t retval;
- blk64_t group_block;
+ ext2_filsys old_fs = rfs->old_fs, fs = rfs->new_fs;
+ dgrp_t max_group, adj;
unsigned long i;
- unsigned long max_group;
-
- ext2fs_mark_super_dirty(fs);
- ext2fs_mark_bb_dirty(fs);
- ext2fs_mark_ib_dirty(fs);
-
- retval = ext2fs_allocate_block_bitmap(fs, _("reserved blocks"),
- &rfs->reserve_blocks);
- if (retval)
- return retval;
-
- retval = adjust_fs_info(fs, rfs->old_fs, rfs->reserve_blocks, new_size);
- if (retval)
- goto errout;
-
- /*
- * Check to make sure there are enough inodes
- */
- if ((rfs->old_fs->super->s_inodes_count -
- rfs->old_fs->super->s_free_inodes_count) >
- rfs->new_fs->super->s_inodes_count) {
- retval = ENOSPC;
- goto errout;
- }
-
- /*
- * If we are not increasing the number block groups, we're done and
- * can exit now.
- */
- if (rfs->old_fs->group_desc_count >= fs->group_desc_count) {
- retval = 0;
- goto errout;
- }

/*
* If we are using uninit_bg (aka GDT_CSUM) and the kernel
@@ -734,18 +632,7 @@ static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
goto errout;
}

- /*
- * Initialize the inode table
- */
- retval = ext2fs_get_array(fs->blocksize, fs->inode_blocks_per_group,
- &rfs->itable_buf);
- if (retval)
- goto errout;
-
- memset(rfs->itable_buf, 0, fs->blocksize * fs->inode_blocks_per_group);
- group_block = ext2fs_group_first_block2(fs,
- rfs->old_fs->group_desc_count);
- adj = rfs->old_fs->group_desc_count;
+ adj = old_fs->group_desc_count;
max_group = fs->group_desc_count - adj;
if (rfs->progress) {
retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS,
@@ -753,8 +640,7 @@ static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
if (retval)
goto errout;
}
- for (i = rfs->old_fs->group_desc_count;
- i < fs->group_desc_count; i++) {
+ for (i = old_fs->group_desc_count; i < fs->group_desc_count; i++) {
/*
* Write out the new inode table
*/
@@ -771,1320 +657,320 @@ static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
if (retval)
goto errout;
}
- group_block += fs->super->s_blocks_per_group;
}
io_channel_flush(fs->io);
retval = 0;
-
errout:
- return retval;
-}
-
-/* --------------------------------------------------------------------
- *
- * Resize processing, phase 2.
- *
- * In this phase we adjust determine which blocks need to be moved, in
- * blocks_to_move(). We then copy the blocks to their ultimate new
- * destinations using block_mover(). Since we are copying blocks to
- * their new locations, again during this pass we can abort without
- * any problems.
- * --------------------------------------------------------------------
- */
-
-/*
- * This helper function creates a block bitmap with all of the
- * filesystem meta-data blocks.
- */
-static errcode_t mark_table_blocks(ext2_filsys fs,
- ext2fs_block_bitmap bmap)
-{
- dgrp_t i;
- blk64_t blk;
-
- for (i = 0; i < fs->group_desc_count; i++) {
- ext2fs_reserve_super_and_bgd(fs, i, bmap);
-
- /*
- * Mark the blocks used for the inode table
- */
- blk = ext2fs_inode_table_loc(fs, i);
- if (blk)
- ext2fs_mark_block_bitmap_range2(bmap, blk,
- fs->inode_blocks_per_group);
-
- /*
- * Mark block used for the block bitmap
- */
- blk = ext2fs_block_bitmap_loc(fs, i);
- if (blk)
- ext2fs_mark_block_bitmap2(bmap, blk);
-
- /*
- * Mark block used for the inode bitmap
- */
- blk = ext2fs_inode_bitmap_loc(fs, i);
- if (blk)
- ext2fs_mark_block_bitmap2(bmap, blk);
- }
- return 0;
-}
-
-/*
- * This function checks to see if a particular block (either a
- * superblock or a block group descriptor) overlaps with an inode or
- * block bitmap block, or with the inode table.
- */
-static void mark_fs_metablock(ext2_resize_t rfs,
- ext2fs_block_bitmap meta_bmap,
- int group, blk64_t blk)
-{
- ext2_filsys fs = rfs->new_fs;

- ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
- ext2fs_block_alloc_stats2(fs, blk, +1);
-
- /*
- * Check to see if we overlap with the inode or block bitmap,
- * or the inode tables. If not, and the block is in use, then
- * mark it as a block to be moved.
- */
- if (IS_BLOCK_BM(fs, group, blk)) {
- ext2fs_block_bitmap_loc_set(fs, group, 0);
- rfs->needed_blocks++;
- return;
- }
- if (IS_INODE_BM(fs, group, blk)) {
- ext2fs_inode_bitmap_loc_set(fs, group, 0);
- rfs->needed_blocks++;
- return;
- }
- if (IS_INODE_TB(fs, group, blk)) {
- ext2fs_inode_table_loc_set(fs, group, 0);
- rfs->needed_blocks++;
- return;
- }
- if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) {
- dgrp_t i;
-
- for (i=0; i < rfs->old_fs->group_desc_count; i++) {
- if (IS_BLOCK_BM(fs, i, blk)) {
- ext2fs_block_bitmap_loc_set(fs, i, 0);
- rfs->needed_blocks++;
- return;
- }
- if (IS_INODE_BM(fs, i, blk)) {
- ext2fs_inode_bitmap_loc_set(fs, i, 0);
- rfs->needed_blocks++;
- return;
- }
- if (IS_INODE_TB(fs, i, blk)) {
- ext2fs_inode_table_loc_set(fs, i, 0);
- rfs->needed_blocks++;
- return;
- }
- }
- }
-
- if (ext2fs_has_group_desc_csum(fs) &&
- (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT))) {
- /*
- * If the block bitmap is uninitialized, which means
- * nothing other than standard metadata in use.
- */
- return;
- } else if (ext2fs_test_block_bitmap2(rfs->old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap2(meta_bmap, blk)) {
- ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
- rfs->needed_blocks++;
- }
+ return retval;
}

-
/*
- * This routine marks and unmarks reserved blocks in the new block
- * bitmap. It also determines which blocks need to be moved and
- * places this information into the move_blocks bitmap.
+ * This routine is shared by the online and offline resize routines.
+ * All of the information which is adjusted in memory is done here.
*/
-static errcode_t blocks_to_move(ext2_resize_t rfs)
+errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs, blk64_t new_size)
{
- int j, has_super;
- dgrp_t i, max_groups, g;
- blk64_t blk, group_blk;
- blk64_t old_blocks, new_blocks, group_end, cluster_freed;
- blk64_t new_size;
- unsigned int meta_bg, meta_bg_size;
errcode_t retval;
- ext2_filsys fs, old_fs;
- ext2fs_block_bitmap meta_bmap, new_meta_bmap = NULL;
- int flex_bg;
-
- fs = rfs->new_fs;
- old_fs = rfs->old_fs;
- if (ext2fs_blocks_count(old_fs->super) > ext2fs_blocks_count(fs->super))
- fs = rfs->old_fs;
-
- retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"),
- &rfs->move_blocks);
- if (retval)
- return retval;
-
- retval = ext2fs_allocate_block_bitmap(fs, _("meta-data blocks"),
- &meta_bmap);
- if (retval)
- return retval;
-
- retval = mark_table_blocks(old_fs, meta_bmap);
- if (retval)
- return retval;
-
- fs = rfs->new_fs;
-
- /*
- * If we're shrinking the filesystem, we need to move any
- * group's metadata blocks (either allocation bitmaps or the
- * inode table) which are beyond the end of the new
- * filesystem.
- */
- new_size = ext2fs_blocks_count(fs->super);
- if (new_size < ext2fs_blocks_count(old_fs->super)) {
- for (g = 0; g < fs->group_desc_count; g++) {
- int realloc = 0;
- /*
- * ext2fs_allocate_group_table will re-allocate any
- * metadata blocks whose location is set to zero.
- */
- if (ext2fs_block_bitmap_loc(fs, g) >= new_size) {
- ext2fs_block_bitmap_loc_set(fs, g, 0);
- realloc = 1;
- }
- if (ext2fs_inode_bitmap_loc(fs, g) >= new_size) {
- ext2fs_inode_bitmap_loc_set(fs, g, 0);
- realloc = 1;
- }
- if ((ext2fs_inode_table_loc(fs, g) +
- fs->inode_blocks_per_group) > new_size) {
- ext2fs_inode_table_loc_set(fs, g, 0);
- realloc = 1;
- }
-
- if (realloc) {
- retval = ext2fs_allocate_group_table(fs, g, 0);
- if (retval)
- return retval;
- }
- }
- }
-
- /*
- * If we're shrinking the filesystem, we need to move all of
- * the blocks that don't fit any more
- */
- for (blk = ext2fs_blocks_count(fs->super);
- blk < ext2fs_blocks_count(old_fs->super); blk++) {
- g = ext2fs_group_of_blk2(fs, blk);
- if (ext2fs_has_group_desc_csum(fs) &&
- ext2fs_bg_flags_test(old_fs, g, EXT2_BG_BLOCK_UNINIT)) {
- /*
- * The block bitmap is uninitialized, so skip
- * to the next block group.
- */
- blk = ext2fs_group_first_block2(fs, g+1) - 1;
- continue;
- }
- if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap2(meta_bmap, blk)) {
- ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
- rfs->needed_blocks++;
- }
- ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
- }
-
- if (old_fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
- old_blocks = old_fs->super->s_first_meta_bg;
- else
- old_blocks = old_fs->desc_blocks +
- old_fs->super->s_reserved_gdt_blocks;
- if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
- new_blocks = fs->super->s_first_meta_bg;
- else
- new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
-
- retval = reserve_sparse_super2_last_group(rfs, meta_bmap);
- if (retval)
- goto errout;
+ blk64_t blk, group_block;
+ blk64_t real_end;
+ unsigned long i;
+ double percent;

- if (old_blocks == new_blocks) {
- retval = 0;
- goto errout;
- }
+ ext2fs_blocks_count_set(fs->super, new_size);
+ fs->group_desc_count = ext2fs_div64_ceil(new_size -
+ fs->super->s_first_data_block,
+ EXT2_BLOCKS_PER_GROUP(fs->super));
+ fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
+ EXT2_DESC_PER_BLOCK(fs->super));
+ fs->super->s_inodes_count = fs->super->s_inodes_per_group *
+ fs->group_desc_count;

- max_groups = fs->group_desc_count;
- if (max_groups > old_fs->group_desc_count)
- max_groups = old_fs->group_desc_count;
- group_blk = old_fs->super->s_first_data_block;
/*
- * If we're reducing the number of descriptor blocks, this
- * makes life easy. :-) We just have to mark some extra
- * blocks as free.
+ * Don't update free blocks count. That gets recalculated when we are
+ * done.
*/
- if (old_blocks > new_blocks) {
- if (EXT2FS_CLUSTER_RATIO(fs) > 1) {
- retval = ext2fs_allocate_block_bitmap(fs,
- _("new meta blocks"),
- &new_meta_bmap);
- if (retval)
- goto errout;
-
- retval = mark_table_blocks(fs, new_meta_bmap);
- if (retval)
- goto errout;
- }
-
- for (i = 0; i < max_groups; i++) {
- if (!ext2fs_bg_has_super(old_fs, i)) {
- group_blk += fs->super->s_blocks_per_group;
- continue;
- }
- group_end = group_blk + 1 + old_blocks;
- for (blk = group_blk + 1 + new_blocks;
- blk < group_end;) {
- if (new_meta_bmap == NULL ||
- !ext2fs_test_block_bitmap2(new_meta_bmap,
- blk)) {
- cluster_freed =
- EXT2FS_CLUSTER_RATIO(fs) -
- (blk &
- EXT2FS_CLUSTER_MASK(fs));
- if (cluster_freed > group_end - blk)
- cluster_freed = group_end - blk;
- ext2fs_block_alloc_stats2(fs, blk, -1);
- blk += EXT2FS_CLUSTER_RATIO(fs);
- rfs->needed_blocks -= cluster_freed;
- continue;
- }
- rfs->needed_blocks--;
- blk++;
- }
- group_blk += fs->super->s_blocks_per_group;
- }
- retval = 0;
- goto errout;
- }
- /*
- * If we're increasing the number of descriptor blocks, life
- * gets interesting....
- */
- meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
- flex_bg = fs->super->s_feature_incompat &
- EXT4_FEATURE_INCOMPAT_FLEX_BG;
- /* first reserve all of the existing fs meta blocks */
- for (i = 0; i < max_groups; i++) {
- has_super = ext2fs_bg_has_super(fs, i);
- if (has_super)
- mark_fs_metablock(rfs, meta_bmap, i, group_blk);
-
- meta_bg = i / meta_bg_size;
- if (!(fs->super->s_feature_incompat &
- EXT2_FEATURE_INCOMPAT_META_BG) ||
- (meta_bg < fs->super->s_first_meta_bg)) {
- if (has_super) {
- for (blk = group_blk+1;
- blk < group_blk + 1 + new_blocks; blk++)
- mark_fs_metablock(rfs, meta_bmap,
- i, blk);
- }
- } else {
- if (has_super)
- has_super = 1;
- if (((i % meta_bg_size) == 0) ||
- ((i % meta_bg_size) == 1) ||
- ((i % meta_bg_size) == (meta_bg_size-1)))
- mark_fs_metablock(rfs, meta_bmap, i,
- group_blk + has_super);
- }
-
- /*
- * Reserve the existing meta blocks that we know
- * aren't to be moved.
- *
- * For flex_bg file systems, in order to avoid
- * overwriting fs metadata (especially inode table
- * blocks) belonging to a different block group when
- * we are relocating the inode tables, we need to
- * reserve all existing fs metadata blocks.
- */
- if (ext2fs_block_bitmap_loc(fs, i))
- ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
- ext2fs_block_bitmap_loc(fs, i));
- else if (flex_bg && i < old_fs->group_desc_count)
- ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
- ext2fs_block_bitmap_loc(old_fs, i));
-
- if (ext2fs_inode_bitmap_loc(fs, i))
- ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
- ext2fs_inode_bitmap_loc(fs, i));
- else if (flex_bg && i < old_fs->group_desc_count)
- ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
- ext2fs_inode_bitmap_loc(old_fs, i));
-
- if (ext2fs_inode_table_loc(fs, i))
- ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks,
- ext2fs_inode_table_loc(fs, i),
- fs->inode_blocks_per_group);
- else if (flex_bg && i < old_fs->group_desc_count)
- ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks,
- ext2fs_inode_table_loc(old_fs, i),
- old_fs->inode_blocks_per_group);
-
- group_blk += rfs->new_fs->super->s_blocks_per_group;
- }
-
- /* Allocate the missing data structures */
- for (i = 0; i < max_groups; i++) {
- if (ext2fs_inode_table_loc(fs, i) &&
- ext2fs_inode_bitmap_loc(fs, i) &&
- ext2fs_block_bitmap_loc(fs, i))
- continue;
-
- retval = ext2fs_allocate_group_table2(fs, i,
- rfs->reserve_blocks,
- EXT2FS_ALLOC_TABLE_UPDATE_STATS |
- EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP);
- if (retval)
- goto errout;
-
- /*
- * For those structures that have changed, we need to
- * do bookkeepping.
- */
- if (ext2fs_block_bitmap_loc(old_fs, i) !=
- (blk = ext2fs_block_bitmap_loc(fs, i))) {
- if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap2(meta_bmap, blk))
- ext2fs_mark_block_bitmap2(rfs->move_blocks,
- blk);
- }
- if (ext2fs_inode_bitmap_loc(old_fs, i) !=
- (blk = ext2fs_inode_bitmap_loc(fs, i))) {
- if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap2(meta_bmap, blk))
- ext2fs_mark_block_bitmap2(rfs->move_blocks,
- blk);
- }
-
- /*
- * The inode table, if we need to relocate it, is
- * handled specially. We have to reserve the blocks
- * for both the old and the new inode table, since we
- * can't have the inode table be destroyed during the
- * block relocation phase.
- */
- if (ext2fs_inode_table_loc(fs, i) == ext2fs_inode_table_loc(old_fs, i))
- continue; /* inode table not moved */
-
- rfs->needed_blocks += fs->inode_blocks_per_group;
-
- /*
- * Mark the new inode table as in use in the new block
- * allocation bitmap, and move any blocks that might
- * be necessary.
- */
- for (blk = ext2fs_inode_table_loc(fs, i), j=0;
- j < fs->inode_blocks_per_group ; j++, blk++) {
- if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap2(meta_bmap, blk))
- ext2fs_mark_block_bitmap2(rfs->move_blocks,
- blk);
- }
-
- /*
- * Make sure the old inode table is reserved in the
- * block reservation bitmap.
- */
- for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0;
- j < fs->inode_blocks_per_group ; j++, blk++)
- ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
- }
- retval = 0;
-
-errout:
- if (new_meta_bmap)
- ext2fs_free_block_bitmap(new_meta_bmap);
- if (meta_bmap)
- ext2fs_free_block_bitmap(meta_bmap);
-
- return retval;
-}
-
-/*
- * This helper function tries to allocate a new block. We try to
- * avoid hitting the original group descriptor blocks at least at
- * first, since we want to make it possible to recover from a badly
- * aborted resize operation as much as possible.
- *
- * In the future, I may further modify this routine to balance out
- * where we get the new blocks across the various block groups.
- * Ideally we would allocate blocks that corresponded with the block
- * group of the containing inode, and keep contiguous blocks
- * together. However, this very difficult to do efficiently, since we
- * don't have the necessary information up front.
- */
-
-#define AVOID_OLD 1
-#define DESPERATION 2
-
-static void init_block_alloc(ext2_resize_t rfs)
-{
- rfs->alloc_state = AVOID_OLD;
- rfs->new_blk = rfs->new_fs->super->s_first_data_block;
-#if 0
- /* HACK for testing */
- if (ext2fs_blocks_count(rfs->new_fs->super) >
- ext2fs_blocks_count(rfs->old_fs->super))
- rfs->new_blk = ext2fs_blocks_count(rfs->old_fs->super);
-#endif
-}
-
-static blk64_t get_new_block(ext2_resize_t rfs)
-{
- ext2_filsys fs = rfs->new_fs;
-
- while (1) {
- if (rfs->new_blk >= ext2fs_blocks_count(fs->super)) {
- if (rfs->alloc_state == DESPERATION)
- return 0;
-
-#ifdef RESIZE2FS_DEBUG
- if (rfs->flags & RESIZE_DEBUG_BMOVE)
- printf("Going into desperation mode "
- "for block allocations\n");
-#endif
- rfs->alloc_state = DESPERATION;
- rfs->new_blk = fs->super->s_first_data_block;
- continue;
- }
- if (ext2fs_test_block_bitmap2(fs->block_map, rfs->new_blk) ||
- ext2fs_test_block_bitmap2(rfs->reserve_blocks,
- rfs->new_blk) ||
- ((rfs->alloc_state == AVOID_OLD) &&
- (rfs->new_blk < ext2fs_blocks_count(rfs->old_fs->super)) &&
- ext2fs_test_block_bitmap2(rfs->old_fs->block_map,
- rfs->new_blk))) {
- rfs->new_blk++;
- continue;
- }
- return rfs->new_blk;
- }
-}
-
-static errcode_t resize2fs_get_alloc_block(ext2_filsys fs, blk64_t goal,
- blk64_t *ret)
-{
- ext2_resize_t rfs = (ext2_resize_t) fs->priv_data;
- blk64_t blk;
-
- blk = get_new_block(rfs);
- if (!blk)
- return ENOSPC;
-
-#ifdef RESIZE2FS_DEBUG
- if (rfs->flags & 0xF)
- printf("get_alloc_block allocating %llu\n", blk);
-#endif
-
- ext2fs_mark_block_bitmap2(rfs->old_fs->block_map, blk);
- ext2fs_mark_block_bitmap2(rfs->new_fs->block_map, blk);
- *ret = (blk64_t) blk;
- return 0;
-}
-
-static errcode_t block_mover(ext2_resize_t rfs)
-{
- blk64_t blk, old_blk, new_blk;
- ext2_filsys fs = rfs->new_fs;
- ext2_filsys old_fs = rfs->old_fs;
- errcode_t retval;
- __u64 size;
- int c;
- int to_move, moved;
- ext2_badblocks_list badblock_list = 0;
- int bb_modified = 0;
-
- fs->get_alloc_block = resize2fs_get_alloc_block;
- old_fs->get_alloc_block = resize2fs_get_alloc_block;
-
- retval = ext2fs_read_bb_inode(old_fs, &badblock_list);
- if (retval)
- return retval;
-
- new_blk = fs->super->s_first_data_block;
- if (!rfs->itable_buf) {
- retval = ext2fs_get_array(fs->blocksize,
- fs->inode_blocks_per_group,
- &rfs->itable_buf);
- if (retval)
- return retval;
- }
- retval = ext2fs_create_extent_table(&rfs->bmap, 0);
- if (retval)
- return retval;

/*
- * The first step is to figure out where all of the blocks
- * will go.
+ * Adjust the number of reserved blocks
*/
- to_move = moved = 0;
- init_block_alloc(rfs);
- for (blk = B2C(old_fs->super->s_first_data_block);
- blk < ext2fs_blocks_count(old_fs->super);
- blk += EXT2FS_CLUSTER_RATIO(fs)) {
- if (!ext2fs_test_block_bitmap2(old_fs->block_map, blk))
- continue;
- if (!ext2fs_test_block_bitmap2(rfs->move_blocks, blk))
- continue;
- if (ext2fs_badblocks_list_test(badblock_list, blk)) {
- ext2fs_badblocks_list_del(badblock_list, blk);
- bb_modified++;
- continue;
- }
-
- new_blk = get_new_block(rfs);
- if (!new_blk) {
- retval = ENOSPC;
- goto errout;
- }
- ext2fs_block_alloc_stats2(fs, new_blk, +1);
- ext2fs_add_extent_entry(rfs->bmap, B2C(blk), B2C(new_blk));
- to_move++;
- }
-
- if (to_move == 0) {
- if (rfs->bmap) {
- ext2fs_free_extent_table(rfs->bmap);
- rfs->bmap = 0;
- }
- retval = 0;
- goto errout;
- }
+ percent = (ext2fs_r_blocks_count(old_fs->super) * 100.0) /
+ ext2fs_blocks_count(old_fs->super);
+ ext2fs_r_blocks_count_set(fs->super,
+ (percent * ext2fs_blocks_count(fs->super) /
+ 100.0));

/*
- * Step two is to actually move the blocks
+ * Adjust the bitmaps for size
*/
- retval = ext2fs_iterate_extent(rfs->bmap, 0, 0, 0);
+ retval = ext2fs_resize_inode_bitmap2(fs->super->s_inodes_count,
+ fs->super->s_inodes_count,
+ fs->inode_map);
if (retval) goto errout;

- if (rfs->progress) {
- retval = (rfs->progress)(rfs, E2_RSZ_BLOCK_RELOC_PASS,
- 0, to_move);
- if (retval)
- goto errout;
- }
- while (1) {
- retval = ext2fs_iterate_extent(rfs->bmap, &old_blk, &new_blk, &size);
- if (retval) goto errout;
- if (!size)
- break;
- old_blk = C2B(old_blk);
- new_blk = C2B(new_blk);
- size = C2B(size);
-#ifdef RESIZE2FS_DEBUG
- if (rfs->flags & RESIZE_DEBUG_BMOVE)
- printf("Moving %llu blocks %llu->%llu\n",
- size, old_blk, new_blk);
-#endif
- do {
- c = size;
- if (c > fs->inode_blocks_per_group)
- c = fs->inode_blocks_per_group;
- retval = io_channel_read_blk64(fs->io, old_blk, c,
- rfs->itable_buf);
- if (retval) goto errout;
- retval = io_channel_write_blk64(fs->io, new_blk, c,
- rfs->itable_buf);
- if (retval) goto errout;
- size -= c;
- new_blk += c;
- old_blk += c;
- moved += c;
- if (rfs->progress) {
- io_channel_flush(fs->io);
- retval = (rfs->progress)(rfs,
- E2_RSZ_BLOCK_RELOC_PASS,
- moved, to_move);
- if (retval)
- goto errout;
- }
- } while (size > 0);
- io_channel_flush(fs->io);
- }
-
-errout:
- if (badblock_list) {
- if (!retval && bb_modified)
- retval = ext2fs_update_bb_inode(old_fs,
- badblock_list);
- ext2fs_badblocks_list_free(badblock_list);
- }
- return retval;
-}
-
-
-/* --------------------------------------------------------------------
- *
- * Resize processing, phase 3
- *
- * --------------------------------------------------------------------
- */
-
-
-/*
- * The extent translation table is stored in clusters so we need to
- * take special care when mapping a source block number to its
- * destination block number.
- */
-static __u64 extent_translate(ext2_filsys fs, ext2_extent extent, __u64 old_loc)
-{
- __u64 new_block = C2B(ext2fs_extent_translate(extent, B2C(old_loc)));
-
- if (new_block != 0)
- new_block += old_loc & (EXT2FS_CLUSTER_RATIO(fs) - 1);
- return new_block;
-}
-
-struct process_block_struct {
- ext2_resize_t rfs;
- ext2_ino_t ino;
- ext2_ino_t old_ino;
- struct ext2_inode * inode;
- errcode_t error;
- int is_dir;
- int changed;
- int has_extents;
-};
-
-static int process_block(ext2_filsys fs, blk64_t *block_nr,
- e2_blkcnt_t blockcnt,
- blk64_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)), void *priv_data)
-{
- struct process_block_struct *pb;
- errcode_t retval;
- blk64_t block, new_block;
- int ret = 0;
-
- pb = (struct process_block_struct *) priv_data;
- block = *block_nr;
- if (pb->rfs->bmap) {
- new_block = extent_translate(fs, pb->rfs->bmap, block);
- if (new_block) {
- *block_nr = new_block;
- ret |= BLOCK_CHANGED;
- pb->changed = 1;
-#ifdef RESIZE2FS_DEBUG
- if (pb->rfs->flags & RESIZE_DEBUG_BMOVE)
- printf("ino=%u, blockcnt=%lld, %llu->%llu\n",
- pb->old_ino, blockcnt, block,
- new_block);
-#endif
- block = new_block;
- }
- }
-
- if (pb->is_dir) {
- retval = ext2fs_add_dir_block2(fs->dblist, pb->ino,
- block, (int) blockcnt);
- if (retval) {
- pb->error = retval;
- ret |= BLOCK_ABORT;
- }
- }
- return ret;
-}
-
-/*
- * Progress callback
- */
-static errcode_t progress_callback(ext2_filsys fs,
- ext2_inode_scan scan EXT2FS_ATTR((unused)),
- dgrp_t group, void * priv_data)
-{
- ext2_resize_t rfs = (ext2_resize_t) priv_data;
- errcode_t retval;
+ real_end = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count) - 1 +
+ fs->super->s_first_data_block;
+ retval = ext2fs_resize_block_bitmap2(new_size - 1,
+ real_end, fs->block_map);
+ if (retval) goto errout;

/*
- * This check is to protect against old ext2 libraries. It
- * shouldn't be needed against new libraries.
+ * Reallocate the group descriptors as necessary.
*/
- if ((group+1) == 0)
- return 0;
-
- if (rfs->progress) {
- io_channel_flush(fs->io);
- retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS,
- group+1, fs->group_desc_count);
- if (retval)
- return retval;
- }
-
- return 0;
-}
-
-static errcode_t migrate_ea_block(ext2_resize_t rfs, ext2_ino_t ino,
- struct ext2_inode *inode, int *changed)
-{
- char *buf = NULL;
- blk64_t new_block;
- errcode_t err = 0;
-
- /* No EA block or no remapping? Quit early. */
- if (ext2fs_file_acl_block(rfs->old_fs, inode) == 0 && !rfs->bmap)
- return 0;
- new_block = extent_translate(rfs->old_fs, rfs->bmap,
- ext2fs_file_acl_block(rfs->old_fs, inode));
- if (new_block == 0)
- return 0;
-
- /* Set the new ACL block */
- ext2fs_file_acl_block_set(rfs->old_fs, inode, new_block);
-
- /* Update checksum */
- if (EXT2_HAS_RO_COMPAT_FEATURE(rfs->new_fs->super,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
- err = ext2fs_get_mem(rfs->old_fs->blocksize, &buf);
- if (err)
- return err;
- rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
- err = ext2fs_read_ext_attr3(rfs->old_fs, new_block, buf, ino);
- rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
- if (err)
- goto out;
- err = ext2fs_write_ext_attr3(rfs->old_fs, new_block, buf, ino);
- if (err)
- goto out;
- }
- *changed = 1;
-
-out:
- ext2fs_free_mem(&buf);
- return err;
-}
-
-/* Rewrite extents */
-static errcode_t rewrite_extents(ext2_filsys fs, ext2_ino_t ino)
-{
- ext2_extent_handle_t handle;
- struct ext2fs_extent extent;
- errcode_t errcode;
- struct ext2_extent_info info;
-
- errcode = ext2fs_extent_open(fs, ino, &handle);
- if (errcode)
- return errcode;
-
- errcode = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent);
- if (errcode)
- goto out;
-
- do {
- errcode = ext2fs_extent_get_info(handle, &info);
- if (errcode)
- break;
-
- /*
- * If this is the first extent in an extent block that we
- * haven't visited, rewrite the extent to force the ETB
- * checksum to be rewritten.
- */
- if (info.curr_entry == 1 && info.curr_level != 0 &&
- !(extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)) {
- errcode = ext2fs_extent_replace(handle, 0, &extent);
- if (errcode)
- break;
- }
-
- /* Skip to the end of a block of leaf nodes */
- if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) {
- errcode = ext2fs_extent_get(handle,
- EXT2_EXTENT_LAST_SIB,
- &extent);
- if (errcode)
- break;
- }
-
- errcode = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT, &extent);
- } while (errcode == 0);
-
-out:
- /* Ok if we run off the end */
- if (errcode == EXT2_ET_EXTENT_NO_NEXT)
- errcode = 0;
- ext2fs_extent_free(handle);
- return errcode;
-}
-
-static void quiet_com_err_proc(const char *whoami, errcode_t code,
- const char *fmt, va_list args)
-{
-}
-
-static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
-{
- struct process_block_struct pb;
- ext2_ino_t ino, new_inode;
- struct ext2_inode *inode = NULL;
- ext2_inode_scan scan = NULL;
- errcode_t retval;
- char *block_buf = 0;
- ext2_ino_t start_to_move;
- int inode_size;
-
- if ((rfs->old_fs->group_desc_count <=
- rfs->new_fs->group_desc_count) &&
- !rfs->bmap)
- return 0;
-
- set_com_err_hook(quiet_com_err_proc);
-
- retval = ext2fs_open_inode_scan(rfs->old_fs, 0, &scan);
- if (retval) goto errout;
-
- retval = ext2fs_init_dblist(rfs->old_fs, 0);
- if (retval) goto errout;
- retval = ext2fs_get_array(rfs->old_fs->blocksize, 3, &block_buf);
- if (retval) goto errout;
-
- start_to_move = (rfs->new_fs->group_desc_count *
- rfs->new_fs->super->s_inodes_per_group);
-
- if (rfs->progress) {
- retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS,
- 0, rfs->old_fs->group_desc_count);
+ if (old_fs->desc_blocks != fs->desc_blocks) {
+ retval = ext2fs_resize_mem(old_fs->desc_blocks *
+ fs->blocksize,
+ fs->desc_blocks * fs->blocksize,
+ &fs->group_desc);
if (retval)
goto errout;
+ if (fs->desc_blocks > old_fs->desc_blocks)
+ memset((char *) fs->group_desc +
+ (old_fs->desc_blocks * fs->blocksize), 0,
+ (fs->desc_blocks - old_fs->desc_blocks) *
+ fs->blocksize);
}
- ext2fs_set_inode_callback(scan, progress_callback, (void *) rfs);
- pb.rfs = rfs;
- pb.inode = inode;
- pb.error = 0;
- new_inode = EXT2_FIRST_INODE(rfs->new_fs->super);
- inode_size = EXT2_INODE_SIZE(rfs->new_fs->super);
- inode = malloc(inode_size);
- if (!inode) {
- retval = ENOMEM;
- goto errout;
- }
+
/*
- * First, copy all of the inodes that need to be moved
- * elsewhere in the inode table
+ * If the resize_inode feature is set, and we are changing the
+ * number of descriptor blocks, then adjust
+ * s_reserved_gdt_blocks if possible to avoid needing to move
+ * the inode table either now or in the future.
*/
- while (1) {
- retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size);
- if (retval) goto errout;
- if (!ino)
- break;
-
- if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO)
- continue; /* inode not in use */
-
- pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
- pb.changed = 0;
-
- /* Remap EA block */
- retval = migrate_ea_block(rfs, ino, inode, &pb.changed);
- if (retval)
- goto errout;
-
- new_inode = ino;
- if (ino <= start_to_move)
- goto remap_blocks; /* Don't need to move inode. */
-
- /*
- * Find a new inode. Now that extents and directory blocks
- * are tied to the inode number through the checksum, we must
- * set up the new inode before we start rewriting blocks.
- */
- retval = ext2fs_new_inode(rfs->new_fs, 0, 0, 0, &new_inode);
- if (retval)
- goto errout;
-
- ext2fs_inode_alloc_stats2(rfs->new_fs, new_inode, +1,
- pb.is_dir);
- inode->i_ctime = time(0);
- retval = ext2fs_write_inode_full(rfs->old_fs, new_inode,
- inode, inode_size);
- if (retval)
- goto errout;
- pb.changed = 0;
-
-#ifdef RESIZE2FS_DEBUG
- if (rfs->flags & RESIZE_DEBUG_INODEMAP)
- printf("Inode moved %u->%u\n", ino, new_inode);
-#endif
- if (!rfs->imap) {
- retval = ext2fs_create_extent_table(&rfs->imap, 0);
- if (retval)
- goto errout;
- }
- ext2fs_add_extent_entry(rfs->imap, ino, new_inode);
+ adjust_reserved_gdt_blocks(old_fs, fs);

-remap_blocks:
- if (pb.changed)
- retval = ext2fs_write_inode_full(rfs->old_fs,
- new_inode,
- inode, inode_size);
- if (retval)
- goto errout;
+ if ((fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) &&
+ (fs->super->s_first_meta_bg > fs->desc_blocks)) {
+ fs->super->s_feature_incompat &=
+ ~EXT2_FEATURE_INCOMPAT_META_BG;
+ fs->super->s_first_meta_bg = 0;
+ }

- /* Rewrite extent block checksums with new inode number */
- if (EXT2_HAS_RO_COMPAT_FEATURE(rfs->old_fs->super,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
- (inode->i_flags & EXT4_EXTENTS_FL)) {
- rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
- retval = rewrite_extents(rfs->old_fs, new_inode);
- rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
- if (retval)
- goto errout;
- }
+ /*
+ * Update the location of the backup superblocks if the
+ * sparse_super2 feature is enabled.
+ */
+ if (fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2) {
+ dgrp_t last_bg = fs->group_desc_count - 1;
+ dgrp_t old_last_bg = old_fs->group_desc_count - 1;

- /*
- * Update inodes to point to new blocks; schedule directory
- * blocks for inode remapping. Need to write out dir blocks
- * with new inode numbers if we have metadata_csum enabled.
- */
- if (ext2fs_inode_has_valid_blocks2(rfs->old_fs, inode) &&
- (rfs->bmap || pb.is_dir)) {
- pb.ino = new_inode;
- pb.old_ino = ino;
- pb.has_extents = inode->i_flags & EXT4_EXTENTS_FL;
- rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
- retval = ext2fs_block_iterate3(rfs->old_fs,
- new_inode, 0, block_buf,
- process_block, &pb);
- rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
- if (retval)
- goto errout;
- if (pb.error) {
- retval = pb.error;
- goto errout;
- }
- } else if ((inode->i_flags & EXT4_INLINE_DATA_FL) &&
- (rfs->bmap || pb.is_dir)) {
- /* inline data dir; update it too */
- retval = ext2fs_add_dir_block2(rfs->old_fs->dblist,
- new_inode, 0, 0);
- if (retval)
- goto errout;
+ /* For shrinking we already did this in prepare_shrink() */
+ if (last_bg > old_last_bg) {
+ if (old_fs->group_desc_count == 1)
+ fs->super->s_backup_bgs[0] = 1;
+ if (old_fs->group_desc_count == 1 &&
+ fs->super->s_backup_bgs[0])
+ fs->super->s_backup_bgs[0] = last_bg;
+ else if (fs->super->s_backup_bgs[1])
+ fs->super->s_backup_bgs[1] = last_bg;
}
}
- io_channel_flush(rfs->old_fs->io);

errout:
- reset_com_err_hook();
- if (rfs->bmap) {
- ext2fs_free_extent_table(rfs->bmap);
- rfs->bmap = 0;
- }
- if (scan)
- ext2fs_close_inode_scan(scan);
- if (block_buf)
- ext2fs_free_mem(&block_buf);
- free(inode);
return retval;
}

-/* --------------------------------------------------------------------
- *
- * Resize processing, phase 4.
- *
- * --------------------------------------------------------------------
+/*
+ * This helper function creates a block bitmap with all of the
+ * filesystem meta-data blocks.
*/
-
-struct istruct {
- ext2_resize_t rfs;
- errcode_t err;
- unsigned int max_dirs;
- unsigned int num;
-};
-
-static int check_and_change_inodes(ext2_ino_t dir,
- int entry EXT2FS_ATTR((unused)),
- struct ext2_dir_entry *dirent, int offset,
- int blocksize EXT2FS_ATTR((unused)),
- char *buf EXT2FS_ATTR((unused)),
- void *priv_data)
+static errcode_t mark_table_blocks(ext2_filsys fs,
+ ext2fs_block_bitmap bmap)
{
- struct istruct *is = (struct istruct *) priv_data;
- struct ext2_inode inode;
- ext2_ino_t new_inode;
- errcode_t retval;
- int ret = 0;
-
- if (is->rfs->progress && offset == 0) {
- io_channel_flush(is->rfs->old_fs->io);
- is->err = (is->rfs->progress)(is->rfs,
- E2_RSZ_INODE_REF_UPD_PASS,
- ++is->num, is->max_dirs);
- if (is->err)
- return DIRENT_ABORT;
- }
-
- /*
- * If we have checksums enabled and the inode wasn't present in the
- * old fs, then we must rewrite all dir blocks with new checksums.
- */
- if (EXT2_HAS_RO_COMPAT_FEATURE(is->rfs->old_fs->super,
- EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
- !ext2fs_test_inode_bitmap2(is->rfs->old_fs->inode_map, dir))
- ret |= DIRENT_CHANGED;
-
- if (!dirent->inode)
- return ret;
+ dgrp_t i;
+ blk64_t blk;

- new_inode = ext2fs_extent_translate(is->rfs->imap, dirent->inode);
+ for (i = 0; i < fs->group_desc_count; i++) {
+ ext2fs_reserve_super_and_bgd(fs, i, bmap);

- if (!new_inode)
- return ret;
-#ifdef RESIZE2FS_DEBUG
- if (is->rfs->flags & RESIZE_DEBUG_INODEMAP)
- printf("Inode translate (dir=%u, name=%.*s, %u->%u)\n",
- dir, ext2fs_dirent_name_len(dirent), dirent->name,
- dirent->inode, new_inode);
-#endif
+ /*
+ * Mark the blocks used for the inode table
+ */
+ blk = ext2fs_inode_table_loc(fs, i);
+ if (blk)
+ ext2fs_mark_block_bitmap_range2(bmap, blk,
+ fs->inode_blocks_per_group);

- dirent->inode = new_inode;
+ /*
+ * Mark block used for the block bitmap
+ */
+ blk = ext2fs_block_bitmap_loc(fs, i);
+ if (blk)
+ ext2fs_mark_block_bitmap2(bmap, blk);

- /* Update the directory mtime and ctime */
- retval = ext2fs_read_inode(is->rfs->old_fs, dir, &inode);
- if (retval == 0) {
- inode.i_mtime = inode.i_ctime = time(0);
- is->err = ext2fs_write_inode(is->rfs->old_fs, dir, &inode);
- if (is->err)
- return ret | DIRENT_ABORT;
+ /*
+ * Mark block used for the inode bitmap
+ */
+ blk = ext2fs_inode_bitmap_loc(fs, i);
+ if (blk)
+ ext2fs_mark_block_bitmap2(bmap, blk);
}
-
- return ret | DIRENT_CHANGED;
+ return 0;
}

-static errcode_t inode_ref_fix(ext2_resize_t rfs)
+/*
+ * Free group descriptor blocks that aren't needed anymore when fs is shrunk
+ */
+static errcode_t free_gd_blocks(ext2_resize_t rfs)
{
- errcode_t retval;
- struct istruct is;
+ errcode_t retval = 0;
+ ext2_filsys fs = rfs->new_fs, old_fs = rfs->old_fs;
+ blk64_t old_blocks, new_blocks, group_end, cluster_freed;
+ ext2fs_block_bitmap new_meta_bmap = NULL;
+ blk64_t blk, group_blk;
+ dgrp_t i;
+
+ if (old_fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
+ old_blocks = old_fs->super->s_first_meta_bg;
+ else
+ old_blocks = old_fs->desc_blocks +
+ old_fs->super->s_reserved_gdt_blocks;
+ if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
+ new_blocks = fs->super->s_first_meta_bg;
+ else
+ new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks;

- if (!rfs->imap)
+ if (old_blocks == new_blocks)
return 0;

- /*
- * Now, we iterate over all of the directories to update the
- * inode references
- */
- is.num = 0;
- is.max_dirs = ext2fs_dblist_count2(rfs->old_fs->dblist);
- is.rfs = rfs;
- is.err = 0;
+ if (new_blocks > old_blocks) {
+ fprintf(stderr, "%s: Called when growing filesystem (%llu > "
+ "%llu)!\n", __func__, (unsigned long long)new_blocks,
+ (unsigned long long)old_blocks);
+ exit(1);
+ }

- if (rfs->progress) {
- retval = (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS,
- 0, is.max_dirs);
+ if (EXT2FS_CLUSTER_RATIO(fs) > 1) {
+ retval = ext2fs_allocate_block_bitmap(fs,
+ _("new meta blocks"),
+ &new_meta_bmap);
if (retval)
goto errout;
- }

- rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
- retval = ext2fs_dblist_dir_iterate(rfs->old_fs->dblist,
- DIRENT_FLAG_INCLUDE_EMPTY, 0,
- check_and_change_inodes, &is);
- rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
- if (retval)
- goto errout;
- if (is.err) {
- retval = is.err;
- goto errout;
+ retval = mark_table_blocks(fs, new_meta_bmap);
+ if (retval)
+ goto errout;
}

- if (rfs->progress && (is.num < is.max_dirs))
- (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS,
- is.max_dirs, is.max_dirs);
-
+ group_blk = fs->super->s_first_data_block;
+ for (i = 0; i < fs->group_desc_count; i++) {
+ if (!ext2fs_bg_has_super(fs, i)) {
+ group_blk += fs->super->s_blocks_per_group;
+ continue;
+ }
+ group_end = group_blk + 1 + old_blocks;
+ for (blk = group_blk + 1 + new_blocks; blk < group_end;) {
+ if (new_meta_bmap == NULL ||
+ !ext2fs_test_block_bitmap2(new_meta_bmap,
+ blk)) {
+ cluster_freed =
+ EXT2FS_CLUSTER_RATIO(fs) -
+ (blk &
+ EXT2FS_CLUSTER_MASK(fs));
+ if (cluster_freed > group_end - blk)
+ cluster_freed = group_end - blk;
+ ext2fs_block_alloc_stats2(fs, blk, -1);
+ blk += EXT2FS_CLUSTER_RATIO(fs);
+ continue;
+ }
+ blk++;
+ }
+ group_blk += fs->super->s_blocks_per_group;
+ }
errout:
- ext2fs_free_extent_table(rfs->imap);
- rfs->imap = 0;
return retval;
}

-
-/* --------------------------------------------------------------------
- *
- * Resize processing, phase 5.
- *
- * In this phase we actually move the inode table around, and then
- * update the summary statistics. This is scary, since aborting here
- * will potentially scramble the filesystem. (We are moving the
- * inode tables around in place, and so the potential for lost data,
- * or at the very least scrambling the mapping between filenames and
- * inode numbers is very high in case of a power failure here.)
- * --------------------------------------------------------------------
- */
-
-
/*
- * A very scary routine --- this one moves the inode table around!!!
- *
- * After this you have to use the rfs->new_fs file handle to read and
- * write inodes.
+ * Identify blocks that need moving to make space for new group descriptors,
+ * move them, and mark them as used.
*/
-static errcode_t move_itables(ext2_resize_t rfs)
+static errcode_t make_space_for_gd(ext2_resize_t rfs)
{
- int n, num, size;
- long long diff;
- dgrp_t i, max_groups;
- ext2_filsys fs = rfs->new_fs;
- char *cp;
- blk64_t old_blk, new_blk, blk, cluster_freed;
+ int j, has_super;
+ dgrp_t i;
+ blk64_t blk, group_blk;
+ blk64_t old_blocks, new_blocks;
+ unsigned int meta_bg, meta_bg_size;
errcode_t retval;
- int j, to_move, moved;
- ext2fs_block_bitmap new_bmap = NULL;
+ ext2_filsys fs = rfs->new_fs, old_fs = rfs->old_fs;
+ ext2fs_block_bitmap move_blocks;
+
+ retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"),
+ &move_blocks);
+ if (retval)
+ return retval;

- max_groups = fs->group_desc_count;
- if (max_groups > rfs->old_fs->group_desc_count)
- max_groups = rfs->old_fs->group_desc_count;
+ if (old_fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
+ old_blocks = old_fs->super->s_first_meta_bg;
+ else
+ old_blocks = old_fs->desc_blocks +
+ old_fs->super->s_reserved_gdt_blocks;
+ if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
+ new_blocks = fs->super->s_first_meta_bg;
+ else
+ new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks;

- size = fs->blocksize * fs->inode_blocks_per_group;
- if (!rfs->itable_buf) {
- retval = ext2fs_get_mem(size, &rfs->itable_buf);
- if (retval)
- return retval;
+ if (old_blocks == new_blocks) {
+ retval = 0;
+ goto errout;
}

- if (EXT2FS_CLUSTER_RATIO(fs) > 1) {
- retval = ext2fs_allocate_block_bitmap(fs, _("new meta blocks"),
- &new_bmap);
- if (retval)
- return retval;
-
- retval = mark_table_blocks(fs, new_bmap);
- if (retval)
- goto errout;
+ if (new_blocks < old_blocks) {
+ fprintf(stderr, "%s: Called when shrinking filesystem (%llu < "
+ "%llu)!\n", __func__, (unsigned long long)new_blocks,
+ (unsigned long long)old_blocks);
+ exit(1);
}

+ meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
/*
- * Figure out how many inode tables we need to move
+ * Mark space for new descriptor blocks as needing moving. We need to
+ * handle only groups with old style group descriptor blocks - for
+ * groups using META_BG the number of group descriptor blocks doesn't
+ * change.
*/
- to_move = moved = 0;
- for (i=0; i < max_groups; i++)
- if (ext2fs_inode_table_loc(rfs->old_fs, i) !=
- ext2fs_inode_table_loc(fs, i))
- to_move++;
+ group_blk = old_fs->super->s_first_data_block;
+ for (i = 0; i < old_fs->group_desc_count;
+ i++, group_blk += fs->super->s_blocks_per_group) {
+ if (!ext2fs_bg_has_super(fs, i))
+ continue;

- if (to_move == 0) {
- retval = 0;
- goto errout;
- }
+ meta_bg = i / meta_bg_size;
+ if (fs->super->s_feature_incompat &
+ EXT2_FEATURE_INCOMPAT_META_BG &&
+ meta_bg >= fs->super->s_first_meta_bg)
+ break;

- if (rfs->progress) {
- retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS,
- 0, to_move);
- if (retval)
- goto errout;
+ ext2fs_mark_block_bitmap_range2(move_blocks,
+ group_blk + old_blocks + 1,
+ new_blocks - old_blocks);
}

- rfs->old_fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
-
- for (i=0; i < max_groups; i++) {
- old_blk = ext2fs_inode_table_loc(rfs->old_fs, i);
- new_blk = ext2fs_inode_table_loc(fs, i);
- diff = new_blk - old_blk;
-
-#ifdef RESIZE2FS_DEBUG
- if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
- printf("Itable move group %d block %llu->%llu (diff %lld)\n",
- i, old_blk, new_blk, diff);
-#endif
+ retval = ext2fs_move_blocks(fs, move_blocks, NULL);
+ if (retval)
+ goto errout;

- if (!diff)
+ /* Blocks for group descriptors are unused now, mark them as used */
+ group_blk = old_fs->super->s_first_data_block;
+ for (i = 0; i < old_fs->group_desc_count;
+ i++, group_blk += fs->super->s_blocks_per_group) {
+ if (!ext2fs_bg_has_super(fs, i))
continue;
- if (diff < 0)
- diff = 0;
-
- retval = io_channel_read_blk64(fs->io, old_blk,
- fs->inode_blocks_per_group,
- rfs->itable_buf);
- if (retval)
- goto errout;
- /*
- * The end of the inode table segment often contains
- * all zeros, and we're often only moving the inode
- * table down a block or two. If so, we can optimize
- * things by not rewriting blocks that we know to be zero
- * already.
- */
- for (cp = rfs->itable_buf+size-1, n=0; n < size; n++, cp--)
- if (*cp)
- break;
- n = n >> EXT2_BLOCK_SIZE_BITS(fs->super);
-#ifdef RESIZE2FS_DEBUG
- if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
- printf("%d blocks of zeros...\n", n);
-#endif
- num = fs->inode_blocks_per_group;
- if (n > diff)
- num -= n;
-
- retval = io_channel_write_blk64(fs->io, new_blk,
- num, rfs->itable_buf);
- if (retval) {
- io_channel_write_blk64(fs->io, old_blk,
- num, rfs->itable_buf);
- goto errout;
- }
- if (n > diff) {
- retval = io_channel_write_blk64(fs->io,
- old_blk + fs->inode_blocks_per_group,
- diff, (rfs->itable_buf +
- (fs->inode_blocks_per_group - diff) *
- fs->blocksize));
- if (retval)
- goto errout;
- }
-
- for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0;
- j < fs->inode_blocks_per_group;) {
- if (new_bmap == NULL ||
- !ext2fs_test_block_bitmap2(new_bmap, blk)) {
- ext2fs_block_alloc_stats2(fs, blk, -1);
- cluster_freed = EXT2FS_CLUSTER_RATIO(fs) -
- (blk & EXT2FS_CLUSTER_MASK(fs));
- blk += cluster_freed;
- j += cluster_freed;
- continue;
- }
- blk++;
- j++;
- }

- ext2fs_inode_table_loc_set(rfs->old_fs, i, new_blk);
- ext2fs_group_desc_csum_set(rfs->old_fs, i);
- ext2fs_mark_super_dirty(rfs->old_fs);
- ext2fs_flush(rfs->old_fs);
+ meta_bg = i / meta_bg_size;
+ if (fs->super->s_feature_incompat &
+ EXT2_FEATURE_INCOMPAT_META_BG &&
+ meta_bg >= fs->super->s_first_meta_bg)
+ break;

- if (rfs->progress) {
- retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS,
- ++moved, to_move);
- if (retval)
- goto errout;
- }
+ ext2fs_mark_block_bitmap_range2(fs->block_map,
+ group_blk + old_blocks + 1,
+ new_blocks - old_blocks);
}
- mark_table_blocks(fs, fs->block_map);
- ext2fs_flush(fs);
-#ifdef RESIZE2FS_DEBUG
- if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
- printf("Inode table move finished.\n");
-#endif
- retval = 0;
-
errout:
- if (new_bmap)
- ext2fs_free_block_bitmap(new_bmap);
+ if (move_blocks)
+ ext2fs_free_block_bitmap(move_blocks);
return retval;
}

@@ -2134,102 +1020,6 @@ static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs)
}

/*
- * This function is used when shrinking a file system. We need to
- * utilize blocks from what will be the new last block group for the
- * backup superblock and block group descriptor blocks.
- * Unfortunately, those blocks may be used by other files or fs
- * metadata blocks. We need to mark them as being in use.
- */
-static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
- ext2fs_block_bitmap meta_bmap)
-{
- ext2_filsys fs = rfs->new_fs;
- ext2_filsys old_fs = rfs->old_fs;
- errcode_t retval;
- dgrp_t old_last_bg = rfs->old_fs->group_desc_count - 1;
- dgrp_t last_bg = fs->group_desc_count - 1;
- dgrp_t g;
- blk64_t blk, sb, old_desc;
- blk_t i, num;
- int realloc = 0;
-
- if (!(fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2))
- return 0;
-
- if (last_bg >= old_last_bg)
- return 0;
-
- if (fs->super->s_backup_bgs[0] == old_fs->super->s_backup_bgs[0] &&
- fs->super->s_backup_bgs[1] == old_fs->super->s_backup_bgs[1])
- return 0;
-
- if (fs->super->s_backup_bgs[0] != last_bg &&
- fs->super->s_backup_bgs[1] != last_bg)
- return 0;
-
- if (old_fs->super->s_backup_bgs[0] == last_bg ||
- old_fs->super->s_backup_bgs[1] == last_bg)
- return 0;
-
- retval = ext2fs_super_and_bgd_loc2(rfs->new_fs, last_bg,
- &sb, &old_desc, NULL, &num);
- if (retval)
- return retval;
-
- if (last_bg && !sb) {
- fputs(_("Should never happen! No sb in last super_sparse bg?\n"),
- stderr);
- exit(1);
- }
- if (old_desc && old_desc != sb+1) {
- fputs(_("Should never happen! Unexpected old_desc in "
- "super_sparse bg?\n"),
- stderr);
- exit(1);
- }
- num = (old_desc) ? num : 1;
-
- /* Reserve the backup blocks */
- ext2fs_mark_block_bitmap_range2(fs->block_map, sb, num);
-
- for (g = 0; g < fs->group_desc_count; g++) {
- blk64_t mb;
-
- mb = ext2fs_block_bitmap_loc(fs, g);
- if ((mb >= sb) && (mb < sb + num)) {
- ext2fs_block_bitmap_loc_set(fs, g, 0);
- realloc = 1;
- }
- mb = ext2fs_inode_bitmap_loc(fs, g);
- if ((mb >= sb) && (mb < sb + num)) {
- ext2fs_inode_bitmap_loc_set(fs, g, 0);
- realloc = 1;
- }
- mb = ext2fs_inode_table_loc(fs, g);
- if ((mb < sb + num) &&
- (sb < mb + fs->inode_blocks_per_group)) {
- ext2fs_inode_table_loc_set(fs, g, 0);
- realloc = 1;
- }
- if (realloc) {
- retval = ext2fs_allocate_group_table(fs, g, 0);
- if (retval)
- return retval;
- }
- }
-
- for (blk = sb, i = 0; i < num; blk++, i++) {
- if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap2(meta_bmap, blk)) {
- ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
- rfs->needed_blocks++;
- }
- ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
- }
- return 0;
-}
-
-/*
* Fix the resize inode
*/
static errcode_t fix_resize_inode(ext2_filsys fs)
@@ -2354,33 +1144,6 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs)
return 0;
}

-/*
- * Journal may have been relocated; update the backup journal blocks
- * in the superblock.
- */
-static errcode_t fix_sb_journal_backup(ext2_filsys fs)
-{
- errcode_t retval;
- struct ext2_inode inode;
-
- if (!(fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
- return 0;
-
- /* External journal? Nothing to do. */
- if (fs->super->s_journal_dev && !fs->super->s_journal_inum)
- return 0;
-
- retval = ext2fs_read_inode(fs, fs->super->s_journal_inum, &inode);
- if (retval)
- return retval;
- memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
- fs->super->s_jnl_blocks[15] = inode.i_size_high;
- fs->super->s_jnl_blocks[16] = inode.i_size;
- fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
- ext2fs_mark_super_dirty(fs);
- return 0;
-}
-
static int calc_group_overhead(ext2_filsys fs, blk64_t grp,
int old_desc_blocks)
{
diff --git a/resize/resize2fs.h b/resize/resize2fs.h
index c53b3bee8c8d..c5d9c92c58ca 100644
--- a/resize/resize2fs.h
+++ b/resize/resize2fs.h
@@ -107,19 +107,7 @@ typedef struct ext2_resize_struct *ext2_resize_t;
struct ext2_resize_struct {
ext2_filsys old_fs;
ext2_filsys new_fs;
- ext2fs_block_bitmap reserve_blocks;
- ext2fs_block_bitmap move_blocks;
- ext2_extent bmap;
- ext2_extent imap;
- blk64_t needed_blocks;
int flags;
- char *itable_buf;
-
- /*
- * For the block allocator
- */
- blk64_t new_blk;
- int alloc_state;

/*
* For the progress meter
@@ -146,9 +134,10 @@ extern errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
int pass, unsigned long cur,
unsigned long max));

+extern errcode_t validate_fs_size(ext2_filsys fs, blk64_t *new_sizep);
extern errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs,
- ext2fs_block_bitmap reserve_blocks,
blk64_t new_size);
+extern errcode_t alloc_new_groups(ext2_filsys fs, dgrp_t from);
extern blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags);


diff --git a/tests/r_expand_full/expect b/tests/r_expand_full/expect
index c80baa265e76..bfb8456eebee 100644
--- a/tests/r_expand_full/expect
+++ b/tests/r_expand_full/expect
@@ -27,20 +27,20 @@ Change in FS metadata:
group:block:super:gdt:bbitmap:ibitmap:itable
-0:1:1:2-4:5:6:7
-1:8193:8193:8194-8196:8197:8198:8199
-+0:1:1:2-13:263:264:265
-+1:8193:8193:8194-8205:8455:8456:8457
++0:1:1:2-13:14:15:16
++1:8193:8193:8194-8205:8206:8207:8208
2:16385:-1:-1:16385:16386:16387
-3:24577:24577:24578-24580:24581:24582:24583
-+3:24577:24577:24578-24589:24839:24840:24841
++3:24577:24577:24578-24589:24590:24591:24592
4:32769:-1:-1:32769:32770:32771
-5:40961:40961:40962-40964:40965:40966:40967
-+5:40961:40961:40962-40973:41223:41224:41225
++5:40961:40961:40962-40973:40974:40975:40976
6:49153:-1:-1:49153:49154:49155
-7:57345:57345:57346-57348:57349:57350:57351
-+7:57345:57345:57346-57357:57607:57608:57609
++7:57345:57345:57346-57357:57358:57359:57360
8:65537:-1:-1:65537:65538:65539
-9:73729:73729:73730-73732:73733:73734:73735
-+9:73729:73729:73730-73741:73991:73992:73993
++9:73729:73729:73730-73741:73742:73743:73744
10:81921:-1:-1:81921:81922:81923
11:90113:-1:-1:90113:90114:90115
12:98305:-1:-1:98305:98306:98307
@@ -49,10 +49,10 @@ Change in FS metadata:
23:188417:-1:-1:188417:188418:188419
24:196609:-1:-1:196609:196610:196611
-25:204801:204801:204802-204804:204805:204806:204807
-+25:204801:204801:204802-204813:205063:205064:205065
++25:204801:204801:204802-204813:204814:204815:204816
26:212993:-1:-1:212993:212994:212995
-27:221185:221185:221186-221188:221189:221190:221191
-+27:221185:221185:221186-221197:221447:221448:221449
++27:221185:221185:221186-221197:221198:221199:221200
28:229377:-1:-1:229377:229378:229379
29:237569:-1:-1:237569:237570:237571
30:245761:-1:-1:245761:245762:245763
@@ -61,7 +61,7 @@ Change in FS metadata:
47:385025:-1:-1:385025:385026:385027
48:393217:-1:-1:393217:393218:393219
-49:401409:401409:401410-401412:401413:401414:401415
-+49:401409:401409:401410-401421:401671:401672:401673
++49:401409:401409:401410-401421:401422:401423:401424
50:409601:-1:-1:409601:409602:409603
51:417793:-1:-1:417793:417794:417795
52:425985:-1:-1:425985:425986:425987
@@ -70,7 +70,7 @@ Change in FS metadata:
79:647169:-1:-1:647169:647170:647171
80:655361:-1:-1:655361:655362:655363
-81:663553:663553:663554-663556:663557:663558:663559
-+81:663553:663553:663554-663565:663815:663816:663817
++81:663553:663553:663554-663565:663566:663567:663568
82:671745:-1:-1:671745:671746:671747
83:679937:-1:-1:679937:679938:679939
84:688129:-1:-1:688129:688130:688131
diff --git a/tests/t_32to64bit_expand_full/expect b/tests/t_32to64bit_expand_full/expect
index 2093c1df2e46..a0991696c872 100644
--- a/tests/t_32to64bit_expand_full/expect
+++ b/tests/t_32to64bit_expand_full/expect
@@ -28,20 +28,20 @@ Change in FS metadata:
group:block:super:gdt:bbitmap:ibitmap:itable
-0:1:1:2-7:8:9:10
-1:8193:8193:8194-8199:8200:8201:8202
-+0:1:1:2-10:266:267:268
-+1:8193:8193:8194-8202:8458:8459:8460
++0:1:1:2-10:11:12:13
++1:8193:8193:8194-8202:8203:8204:8205
2:16385:-1:-1:16385:16386:16387
-3:24577:24577:24578-24583:24584:24585:24586
-+3:24577:24577:24578-24586:24842:24843:24844
++3:24577:24577:24578-24586:24587:24588:24589
4:32769:-1:-1:32769:32770:32771
-5:40961:40961:40962-40967:40968:40969:40970
-+5:40961:40961:40962-40970:41226:41227:41228
++5:40961:40961:40962-40970:40971:40972:40973
6:49153:-1:-1:49153:49154:49155
-7:57345:57345:57346-57351:57352:57353:57354
-+7:57345:57345:57346-57354:57610:57611:57612
++7:57345:57345:57346-57354:57355:57356:57357
8:65537:-1:-1:65537:65538:65539
-9:73729:73729:73730-73735:73736:73737:73738
-+9:73729:73729:73730-73738:73994:73995:73996
++9:73729:73729:73730-73738:73739:73740:73741
10:81921:-1:-1:81921:81922:81923
11:90113:-1:-1:90113:90114:90115
12:98305:-1:-1:98305:98306:98307
@@ -50,10 +50,10 @@ Change in FS metadata:
23:188417:-1:-1:188417:188418:188419
24:196609:-1:-1:196609:196610:196611
-25:204801:204801:204802-204807:204808:204809:204810
-+25:204801:204801:204802-204810:205066:205067:205068
++25:204801:204801:204802-204810:204811:204812:204813
26:212993:-1:-1:212993:212994:212995
-27:221185:221185:221186-221191:221192:221193:221194
-+27:221185:221185:221186-221194:221450:221451:221452
++27:221185:221185:221186-221194:221195:221196:221197
28:229377:-1:-1:229377:229378:229379
29:237569:-1:-1:237569:237570:237571
30:245761:-1:-1:245761:245762:245763
@@ -62,7 +62,7 @@ Change in FS metadata:
47:385025:-1:-1:385025:385026:385027
48:393217:-1:-1:393217:393218:393219
-49:401409:401409:401410-401415:401416:401417:401418
-+49:401409:401409:401410-401418:401674:401675:401676
++49:401409:401409:401410-401418:401419:401420:401421
50:409601:-1:-1:409601:409602:409603
51:417793:-1:-1:417793:417794:417795
52:425985:-1:-1:425985:425986:425987
@@ -71,7 +71,7 @@ Change in FS metadata:
79:647169:-1:-1:647169:647170:647171
80:655361:-1:-1:655361:655362:655363
-81:663553:663553:663554-663559:663560:663561:663562
-+81:663553:663553:663554-663562:663818:663819:663820
++81:663553:663553:663554-663562:663563:663564:663565
82:671745:-1:-1:671745:671746:671747
83:679937:-1:-1:679937:679938:679939
84:688129:-1:-1:688129:688130:688131
--
2.1.4


2015-08-26 16:22:59

by Jan Kara

[permalink] [raw]
Subject: [PATCH 17/21] resize2fs: Remove duplicate condition

Signed-off-by: Jan Kara <[email protected]>
---
resize/resize2fs.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 3cff977b1d53..70c963783f3f 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -716,19 +716,9 @@ static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
}

/*
- * If we are shrinking the number block groups, we're done and
+ * If we are not increasing the number block groups, we're done and
* can exit now.
*/
- if (rfs->old_fs->group_desc_count > fs->group_desc_count) {
- retval = 0;
- goto errout;
- }

2015-08-26 16:22:59

by Jan Kara

[permalink] [raw]
Subject: [PATCH 19/21] resize2fs: Remove extent mapping code

Extent mapping code is now in libext2fs. Remove a special version from
resize2fs.

Signed-off-by: Jan Kara <[email protected]>
---
resize/Makefile.in | 8 +-
resize/extent.c | 241 -----------------------------------------------------
resize/resize2fs.h | 11 ---
3 files changed, 3 insertions(+), 257 deletions(-)
delete mode 100644 resize/extent.c

diff --git a/resize/Makefile.in b/resize/Makefile.in
index ecd8619e55a5..82ae57adc4c5 100644
--- a/resize/Makefile.in
+++ b/resize/Makefile.in
@@ -16,13 +16,11 @@ PROGS= resize2fs
TEST_PROGS= test_extent
MANPAGES= resize2fs.8

-RESIZE_OBJS= extent.o resize2fs.o main.o online.o resource_track.o \
- sim_progress.o
+RESIZE_OBJS= resize2fs.o main.o online.o resource_track.o sim_progress.o

-TEST_EXTENT_OBJS= extent.o test_extent.o
+TEST_EXTENT_OBJS= test_extent.o

-SRCS= $(srcdir)/extent.c \
- $(srcdir)/resize2fs.c \
+SRCS= $(srcdir)/resize2fs.c \
$(srcdir)/main.c \
$(srcdir)/online.c \
$(srcdir)/resource_track.c \
diff --git a/resize/extent.c b/resize/extent.c
deleted file mode 100644
index ec81b944e94a..000000000000
--- a/resize/extent.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * extent.c --- ext2 extent abstraction
- *
- * This abstraction is used to provide a compact way of representing a
- * translation table, for moving multiple contiguous ranges (extents)
- * of blocks or inodes.
- *
- * Copyright (C) 1997, 1998 by Theodore Ts'o and
- * PowerQuest, Inc.
- *
- * Copyright (C) 1999, 2000 by Theosore Ts'o
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
- * %End-Header%
- */
-
-#include "config.h"
-#include "resize2fs.h"
-
-struct ext2_extent_entry {
- __u64 old_loc, new_loc;
- __u64 size;
-};
-
-struct _ext2_extent {
- struct ext2_extent_entry *list;
- __u64 cursor;
- __u64 size;
- __u64 num;
- __u64 sorted;
-};
-
-/*
- * Create an extent table
- */
-errcode_t ext2fs_create_extent_table(ext2_extent *ret_extent, __u64 size)
-{
- ext2_extent extent;
- errcode_t retval;
-
- retval = ext2fs_get_mem(sizeof(struct _ext2_extent), &extent);
- if (retval)
- return retval;
- memset(extent, 0, sizeof(struct _ext2_extent));
-
- extent->size = size ? size : 50;
- extent->cursor = 0;
- extent->num = 0;
- extent->sorted = 1;
-
- retval = ext2fs_get_array(sizeof(struct ext2_extent_entry),
- extent->size, &extent->list);
- if (retval) {
- ext2fs_free_mem(&extent);
- return retval;
- }
- memset(extent->list, 0,
- sizeof(struct ext2_extent_entry) * extent->size);
- *ret_extent = extent;
- return 0;
-}
-
-/*
- * Free an extent table
- */
-void ext2fs_free_extent_table(ext2_extent extent)
-{
- if (extent->list)
- ext2fs_free_mem(&extent->list);
- extent->list = 0;
- extent->size = 0;
- extent->num = 0;
- ext2fs_free_mem(&extent);
-}
-
-/*
- * Add an entry to the extent table
- */
-errcode_t ext2fs_add_extent_entry(ext2_extent extent, __u64 old_loc, __u64 new_loc)
-{
- struct ext2_extent_entry *ent;
- errcode_t retval;
- __u64 newsize;
- __u64 curr;
-
- if (extent->num >= extent->size) {
- newsize = extent->size + 100;
- retval = ext2fs_resize_mem(sizeof(struct ext2_extent_entry) *
- extent->size,
- sizeof(struct ext2_extent_entry) *
- newsize, &extent->list);
- if (retval)
- return retval;
- extent->size = newsize;
- }
- curr = extent->num;
- ent = extent->list + curr;
- if (curr) {
- /*
- * Check to see if this can be coalesced with the last
- * extent
- */
- ent--;
- if ((ent->old_loc + ent->size == old_loc) &&
- (ent->new_loc + ent->size == new_loc)) {
- ent->size++;
- return 0;
- }
- /*
- * Now see if we're going to ruin the sorting
- */
- if (ent->old_loc + ent->size > old_loc)
- extent->sorted = 0;
- ent++;
- }
- ent->old_loc = old_loc;
- ent->new_loc = new_loc;
- ent->size = 1;
- extent->num++;
- return 0;
-}
-
-/*
- * Helper function for qsort
- */
-static EXT2_QSORT_TYPE extent_cmp(const void *a, const void *b)
-{
- const struct ext2_extent_entry *db_a;
- const struct ext2_extent_entry *db_b;
-
- db_a = (const struct ext2_extent_entry *) a;
- db_b = (const struct ext2_extent_entry *) b;
-
- return (db_a->old_loc - db_b->old_loc);
-}
-
-/*
- * Given an inode map and inode number, look up the old inode number
- * and return the new inode number.
- */
-__u64 ext2fs_extent_translate(ext2_extent extent, __u64 old_loc)
-{
- __s64 low, high, mid;
- __u64 lowval, highval;
- float range;
-
- if (!extent->sorted) {
- qsort(extent->list, extent->num,
- sizeof(struct ext2_extent_entry), extent_cmp);
- extent->sorted = 1;
- }
- low = 0;
- high = extent->num-1;
- while (low <= high) {
-#if 0
- mid = (low+high)/2;
-#else
- if (low == high)
- mid = low;
- else {
- /* Interpolate for efficiency */
- lowval = extent->list[low].old_loc;
- highval = extent->list[high].old_loc;
-
- if (old_loc < lowval)
- range = 0;
- else if (old_loc > highval)
- range = 1;
- else {
- range = ((float) (old_loc - lowval)) /
- (highval - lowval);
- if (range > 0.9)
- range = 0.9;
- if (range < 0.1)
- range = 0.1;
- }
- mid = low + ((__u64) (range * (high-low)));
- }
-#endif
- if ((old_loc >= extent->list[mid].old_loc) &&
- (old_loc < extent->list[mid].old_loc + extent->list[mid].size))
- return (extent->list[mid].new_loc +
- (old_loc - extent->list[mid].old_loc));
- if (old_loc < extent->list[mid].old_loc)
- high = mid-1;
- else
- low = mid+1;
- }
- return 0;
-}
-
-/*
- * For debugging only
- */
-void ext2fs_extent_dump(ext2_extent extent, FILE *out)
-{
- __u64 i;
- struct ext2_extent_entry *ent;
-
- fputs(_("# Extent dump:\n"), out);
- fprintf(out, _("#\tNum=%llu, Size=%llu, Cursor=%llu, Sorted=%llu\n"),
- extent->num, extent->size, extent->cursor, extent->sorted);
- for (i=0, ent=extent->list; i < extent->num; i++, ent++) {
- fprintf(out, "#\t\t %llu -> %llu (%llu)\n", ent->old_loc,
- ent->new_loc, ent->size);
- }
-}
-
-/*
- * Iterate over the contents of the extent table
- */
-errcode_t ext2fs_iterate_extent(ext2_extent extent, __u64 *old_loc,
- __u64 *new_loc, __u64 *size)
-{
- struct ext2_extent_entry *ent;
-
- if (!old_loc) {
- extent->cursor = 0;
- return 0;
- }
-
- if (extent->cursor >= extent->num) {
- *old_loc = 0;
- *new_loc = 0;
- *size = 0;
- return 0;
- }
-
- ent = extent->list + extent->cursor++;
-
- *old_loc = ent->old_loc;
- *new_loc = ent->new_loc;
- *size = ent->size;
- return 0;
-}
-
-
-
-
diff --git a/resize/resize2fs.h b/resize/resize2fs.h
index 829fcd8ea8e1..c53b3bee8c8d 100644
--- a/resize/resize2fs.h
+++ b/resize/resize2fs.h
@@ -152,17 +152,6 @@ extern errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs,
extern blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags);


-/* extent.c */
-extern errcode_t ext2fs_create_extent_table(ext2_extent *ret_extent,
- __u64 size);
-extern void ext2fs_free_extent_table(ext2_extent extent);
-extern errcode_t ext2fs_add_extent_entry(ext2_extent extent,
- __u64 old_loc, __u64 new_loc);
-extern __u64 ext2fs_extent_translate(ext2_extent extent, __u64 old_loc);
-extern void ext2fs_extent_dump(ext2_extent extent, FILE *out);
-extern errcode_t ext2fs_iterate_extent(ext2_extent extent, __u64 *old_loc,
- __u64 *new_loc, __u64 *size);

2015-08-26 16:22:59

by Jan Kara

[permalink] [raw]
Subject: [PATCH 18/21] ext2fs: Add extent dumping function to extent mapping code

For testing extent mapping code, we will need the extent dumping
function. So copy that function over from the resize2fs version of the
code.

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/extent_map.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/lib/ext2fs/extent_map.c b/lib/ext2fs/extent_map.c
index a4e1df404dca..0f1acc78b67f 100644
--- a/lib/ext2fs/extent_map.c
+++ b/lib/ext2fs/extent_map.c
@@ -231,3 +231,20 @@ errcode_t ext2fs_iterate_extent(ext2_map_extent extent, __u64 *old_loc,
*size = ent->size;
return 0;
}
+
+/*
+ * For debugging only
+ */
+void ext2fs_extent_dump(ext2_map_extent extent, FILE *out)
+{
+ __u64 i;
+ struct ext2_map_extent_entry *ent;
+
+ fputs("# Extent dump:\n", out);
+ fprintf(out, "#\tNum=%llu, Size=%llu, Cursor=%llu, Sorted=%llu\n",
+ extent->num, extent->size, extent->cursor, extent->sorted);
+ for (i=0, ent=extent->list; i < extent->num; i++, ent++) {
+ fprintf(out, "#\t\t %llu -> %llu (%llu)\n", ent->old_loc,
+ ent->new_loc, ent->size);
+ }
+}
--
2.1.4


2015-08-26 16:22:59

by Jan Kara

[permalink] [raw]
Subject: [PATCH 20/21] ext2fs: Move extent mapping test

Move test program for excercising extent mapping code from resize2fs
into libext2fs since the code is now generic.

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/Makefile.in | 12 +++-
lib/ext2fs/tst_extent_map.c | 127 +++++++++++++++++++++++++++++++++++++++++++
lib/ext2fs/tst_extent_map_in | 64 ++++++++++++++++++++++
resize/Makefile.in | 21 +------
resize/test_extent.c | 126 ------------------------------------------
resize/test_extent.in | 64 ----------------------
6 files changed, 203 insertions(+), 211 deletions(-)
create mode 100644 lib/ext2fs/tst_extent_map.c
create mode 100644 lib/ext2fs/tst_extent_map_in
delete mode 100644 resize/test_extent.c
delete mode 100644 resize/test_extent.in

diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 02ede7bbf856..98d8d3764e05 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -488,6 +488,14 @@ tst_extents: $(srcdir)/extent.c $(DEBUG_OBJS) $(DEPSTATIC_LIBSS) libext2fs.a \
$(STATIC_LIBEXT2FS) $(LIBBLKID) $(LIBUUID) \
$(STATIC_LIBCOM_ERR) $(SYSLIBS) -I $(top_srcdir)/debugfs

+tst_extent_map: $(srcdir)/extent_map.c $(DEPSTATIC_LIBSS) \
+ $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+ $(E) " LD $@"
+ $(Q) $(CC) -o tst_extent_map $(srcdir)/tst_extent_map.c \
+ $(ALL_CFLAGS) $(ALL_LDFLAGS) -DDEBUG \
+ $(STATIC_LIBSS) $(STATIC_LIBEXT2FS) \
+ $(STATIC_LIBCOM_ERR) $(SYSLIBS)
+
tst_libext2fs: $(DEBUG_OBJS) \
$(DEPSTATIC_LIBSS) $(STATIC_LIBE2P) $(DEPLIBUUID) libext2fs.a \
$(DEPLIBBLKID) $(DEPSTATIC_LIBCOM_ERR) $(DEPLIBQUOTA)
@@ -528,7 +536,7 @@ mkjournal: mkjournal.c $(STATIC_LIBEXT2FS) $(DEPLIBCOM_ERR)
check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount \
tst_super_size tst_types tst_inode_size tst_csum tst_crc32c tst_bitmaps \
tst_inline tst_inline_data tst_libext2fs tst_sha256 tst_sha512 \
- tst_digest_encode
+ tst_digest_encode tst_extent_map
$(TESTENV) ./tst_bitops
$(TESTENV) ./tst_badblocks
$(TESTENV) ./tst_iscan
@@ -537,6 +545,8 @@ check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount \
$(TESTENV) ./tst_super_size
$(TESTENV) ./tst_inode_size
$(TESTENV) ./tst_csum
+ $(TESTENV) ./tst_extent_map <tst_extent_map_in >tst_extent_map_out
+ diff $(srcdir)/tst_extent_map_in tst_extent_map_out
$(TESTENV) ./tst_inline
$(TESTENV) ./tst_inline_data
$(TESTENV) ./tst_crc32c
diff --git a/lib/ext2fs/tst_extent_map.c b/lib/ext2fs/tst_extent_map.c
new file mode 100644
index 000000000000..a00dedb2932b
--- /dev/null
+++ b/lib/ext2fs/tst_extent_map.c
@@ -0,0 +1,127 @@
+/*
+ * test_extent.c --- tester for the extent abstraction
+ *
+ * Copyright (C) 1997, 1998 by Theodore Ts'o and
+ * PowerQuest, Inc.
+ *
+ * Copyright (C) 1999, 2000 by Theosore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+
+#include "move.h"
+
+void do_test(FILE *in, FILE *out);
+
+void do_test(FILE *in, FILE *out)
+{
+ char buf[128];
+ char *cp, *cmd, *arg1, *arg2;
+ __u64 num1, num2;
+ __u64 size;
+ errcode_t retval;
+ ext2_map_extent extent = 0;
+ const char *no_table = "# No extent table\n";
+
+ while (!feof(in)) {
+ if (!fgets(buf, sizeof(buf), in))
+ break;
+ /*
+ * Ignore comments
+ */
+ if (buf[0] =='#')
+ continue;
+
+ /*
+ * Echo command
+ */
+ fputs(buf, out);
+
+ cp = strchr(buf, '\n');
+ if (cp)
+ *cp = '\0';
+
+ /*
+ * Parse command line; simple, at most two arguments
+ */
+ cmd = buf;
+ num1 = num2 = 0;
+ arg1 = arg2 = 0;
+ cp = strchr(buf, ' ');
+ if (cp) {
+ *cp++ = '\0';
+ arg1 = cp;
+ num1 = strtoul(arg1, 0, 0);
+
+ cp = strchr(cp, ' ');
+ }
+ if (cp) {
+ *cp++ = '\0';
+ arg2 = cp;
+ num2 = strtoul(arg2, 0, 0);
+ }
+
+ if (!strcmp(cmd, "create")) {
+ retval = ext2fs_create_extent_table(&extent, num1);
+ if (retval) {
+ handle_error:
+ fprintf(out, "# Error: %s\n",
+ error_message(retval));
+ continue;
+ }
+ continue;
+ }
+ if (!extent) {
+ fputs(no_table, out);
+ continue;
+ }
+ if (!strcmp(cmd, "free")) {
+ ext2fs_free_extent_table(extent);
+ extent = 0;
+ } else if (!strcmp(cmd, "add")) {
+ retval = ext2fs_add_extent_entry(extent, num1, num2);
+ if (retval)
+ goto handle_error;
+ } else if (!strcmp(cmd, "lookup")) {
+ num2 = ext2fs_extent_translate(extent, num1);
+ fprintf(out, "# Answer: %llu%s\n", num2,
+ num2 ? "" : " (not found)");
+ } else if (!strcmp(cmd, "dump")) {
+ ext2fs_extent_dump(extent, out);
+ } else if (!strcmp(cmd, "iter_test")) {
+ retval = ext2fs_iterate_extent(extent, 0, 0, 0);
+ if (retval)
+ goto handle_error;
+ while (1) {
+ retval = ext2fs_iterate_extent(extent,
+ &num1, &num2, &size);
+ if (retval)
+ goto handle_error;
+ if (!size)
+ break;
+ fprintf(out, "# %llu -> %llu (%llu)\n",
+ num1, num2, size);
+ }
+ } else
+ fputs("# Syntax error\n", out);
+ }
+ if (extent)
+ ext2fs_free_extent_table(extent);
+}
+
+#ifdef __GNUC__
+#define ATTR(x) __attribute__(x)
+#else
+#define ATTR(x)
+#endif
+
+int main(int argc ATTR((unused)), char **argv ATTR((unused)))
+{
+ do_test(stdin, stdout);
+ exit(0);
+}
diff --git a/lib/ext2fs/tst_extent_map_in b/lib/ext2fs/tst_extent_map_in
new file mode 100644
index 000000000000..7edcc41898a6
--- /dev/null
+++ b/lib/ext2fs/tst_extent_map_in
@@ -0,0 +1,64 @@
+create 10
+add 10 20
+add 11 21
+add 12 22
+add 14 45
+add 16 50
+add 17 51
+dump
+# Extent dump:
+# Num=3, Size=10, Cursor=0, Sorted=1
+# 10 -> 20 (3)
+# 14 -> 45 (1)
+# 16 -> 50 (2)
+add 18 52
+dump
+# Extent dump:
+# Num=3, Size=10, Cursor=0, Sorted=1
+# 10 -> 20 (3)
+# 14 -> 45 (1)
+# 16 -> 50 (3)
+lookup 10
+# Answer: 20
+lookup 11
+# Answer: 21
+lookup 12
+# Answer: 22
+lookup 13
+# Answer: 0 (not found)
+lookup 14
+# Answer: 45
+lookup 15
+# Answer: 0 (not found)
+lookup 16
+# Answer: 50
+lookup 1
+# Answer: 0 (not found)
+lookup 50
+# Answer: 0 (not found)
+add 19 100
+add 13 5
+lookup 18
+# Answer: 52
+lookup 19
+# Answer: 100
+lookup 20
+# Answer: 0 (not found)
+lookup 12
+# Answer: 22
+lookup 13
+# Answer: 5
+dump
+# Extent dump:
+# Num=5, Size=10, Cursor=0, Sorted=1
+# 10 -> 20 (3)
+# 13 -> 5 (1)
+# 14 -> 45 (1)
+# 16 -> 50 (3)
+# 19 -> 100 (1)
+iter_test
+# 10 -> 20 (3)
+# 13 -> 5 (1)
+# 14 -> 45 (1)
+# 16 -> 50 (3)
+# 19 -> 100 (1)
diff --git a/resize/Makefile.in b/resize/Makefile.in
index 82ae57adc4c5..f67188dcfd42 100644
--- a/resize/Makefile.in
+++ b/resize/Makefile.in
@@ -13,13 +13,10 @@ LDFLAG_STATIC = @LDFLAG_STATIC@
@MCONFIG@

PROGS= resize2fs
-TEST_PROGS= test_extent
MANPAGES= resize2fs.8

RESIZE_OBJS= resize2fs.o main.o online.o resource_track.o sim_progress.o

-TEST_EXTENT_OBJS= test_extent.o
-
SRCS= $(srcdir)/resize2fs.c \
$(srcdir)/main.c \
$(srcdir)/online.c \
@@ -54,10 +51,6 @@ resize2fs.8: $(DEP_SUBSTITUTE) $(srcdir)/resize2fs.8.in
$(E) " SUBST $@"
$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/resize2fs.8.in resize2fs.8

-test_extent: $(TEST_EXTENT_OBJS)
- $(E) " LD $@"
- $(Q) $(CC) $(ALL_LDFLAGS) -o test_extent $(TEST_EXTENT_OBJS) $(LIBS)
-
installdirs:
$(E) " MKINSTALLDIRS $(root_sbindir) $(man8dir)"
$(Q) $(MKINSTALLDIRS) $(DESTDIR)$(root_sbindir) \
@@ -90,21 +83,9 @@ uninstall:
$(RM) -f $(DESTDIR)$(man8dir)/$$i; \
done

-test_extent.out: test_extent $(srcdir)/test_extent.in
- $(TESTENV) ./test_extent < $(srcdir)/test_extent.in > test_extent.out
-
-check:: test_extent.out
- $(Q) if cmp -s test_extent.out $(srcdir)/test_extent.in ; then \
- echo "Test succeeded." ; \
- else \
- echo "Test failed!" ; \
- diff test_extent.out $(srcdir)/test_extent.in ; \
- exit 1 ; \
- fi
-
clean::
$(RM) -f $(PROGS) $(TEST_PROGS) $(MANPAGES) \#* *.s *.o *.a *~ core \
- resize2fs.static test_extent.out
+ resize2fs.static

mostlyclean: clean

diff --git a/resize/test_extent.c b/resize/test_extent.c
deleted file mode 100644
index 60aa08f3577e..000000000000
--- a/resize/test_extent.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * test_extent.c --- tester for the extent abstraction
- *
- * Copyright (C) 1997, 1998 by Theodore Ts'o and
- * PowerQuest, Inc.
- *
- * Copyright (C) 1999, 2000 by Theosore Ts'o
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
- * %End-Header%
- */
-
-#include "config.h"
-#include "resize2fs.h"
-
-void do_test(FILE *in, FILE *out);
-
-void do_test(FILE *in, FILE *out)
-{
- char buf[128];
- char *cp, *cmd, *arg1, *arg2;
- __u64 num1, num2;
- __u64 size;
- errcode_t retval;
- ext2_extent extent = 0;
- const char *no_table = "# No extent table\n";
-
- while (!feof(in)) {
- if (!fgets(buf, sizeof(buf), in))
- break;
- /*
- * Ignore comments
- */
- if (buf[0] =='#')
- continue;
-
- /*
- * Echo command
- */
- fputs(buf, out);
-
- cp = strchr(buf, '\n');
- if (cp)
- *cp = '\0';
-
- /*
- * Parse command line; simple, at most two arguments
- */
- cmd = buf;
- num1 = num2 = 0;
- arg1 = arg2 = 0;
- cp = strchr(buf, ' ');
- if (cp) {
- *cp++ = '\0';
- arg1 = cp;
- num1 = strtoul(arg1, 0, 0);
-
- cp = strchr(cp, ' ');
- }
- if (cp) {
- *cp++ = '\0';
- arg2 = cp;
- num2 = strtoul(arg2, 0, 0);
- }
-
- if (!strcmp(cmd, "create")) {
- retval = ext2fs_create_extent_table(&extent, num1);
- if (retval) {
- handle_error:
- fprintf(out, "# Error: %s\n",
- error_message(retval));
- continue;
- }
- continue;
- }
- if (!extent) {
- fputs(no_table, out);
- continue;
- }
- if (!strcmp(cmd, "free")) {
- ext2fs_free_extent_table(extent);
- extent = 0;
- } else if (!strcmp(cmd, "add")) {
- retval = ext2fs_add_extent_entry(extent, num1, num2);
- if (retval)
- goto handle_error;
- } else if (!strcmp(cmd, "lookup")) {
- num2 = ext2fs_extent_translate(extent, num1);
- fprintf(out, "# Answer: %llu%s\n", num2,
- num2 ? "" : " (not found)");
- } else if (!strcmp(cmd, "dump")) {
- ext2fs_extent_dump(extent, out);
- } else if (!strcmp(cmd, "iter_test")) {
- retval = ext2fs_iterate_extent(extent, 0, 0, 0);
- if (retval)
- goto handle_error;
- while (1) {
- retval = ext2fs_iterate_extent(extent,
- &num1, &num2, &size);
- if (retval)
- goto handle_error;
- if (!size)
- break;
- fprintf(out, "# %llu -> %llu (%llu)\n",
- num1, num2, size);
- }
- } else
- fputs("# Syntax error\n", out);
- }
- if (extent)
- ext2fs_free_extent_table(extent);
-}
-
-#ifdef __GNUC__
-#define ATTR(x) __attribute__(x)
-#else
-#define ATTR(x)
-#endif
-
-int main(int argc ATTR((unused)), char **argv ATTR((unused)))
-{
- do_test(stdin, stdout);
- exit(0);
-}
diff --git a/resize/test_extent.in b/resize/test_extent.in
deleted file mode 100644
index 7edcc41898a6..000000000000
--- a/resize/test_extent.in
+++ /dev/null
@@ -1,64 +0,0 @@
-create 10
-add 10 20
-add 11 21
-add 12 22
-add 14 45
-add 16 50
-add 17 51
-dump
-# Extent dump:
-# Num=3, Size=10, Cursor=0, Sorted=1
-# 10 -> 20 (3)
-# 14 -> 45 (1)
-# 16 -> 50 (2)
-add 18 52
-dump
-# Extent dump:
-# Num=3, Size=10, Cursor=0, Sorted=1
-# 10 -> 20 (3)
-# 14 -> 45 (1)
-# 16 -> 50 (3)
-lookup 10
-# Answer: 20
-lookup 11
-# Answer: 21
-lookup 12
-# Answer: 22
-lookup 13
-# Answer: 0 (not found)
-lookup 14
-# Answer: 45
-lookup 15
-# Answer: 0 (not found)
-lookup 16
-# Answer: 50
-lookup 1
-# Answer: 0 (not found)
-lookup 50
-# Answer: 0 (not found)
-add 19 100
-add 13 5
-lookup 18
-# Answer: 52
-lookup 19
-# Answer: 100
-lookup 20
-# Answer: 0 (not found)
-lookup 12
-# Answer: 22
-lookup 13
-# Answer: 5
-dump
-# Extent dump:
-# Num=5, Size=10, Cursor=0, Sorted=1
-# 10 -> 20 (3)
-# 13 -> 5 (1)
-# 14 -> 45 (1)
-# 16 -> 50 (3)
-# 19 -> 100 (1)
-iter_test
-# 10 -> 20 (3)
-# 13 -> 5 (1)
-# 14 -> 45 (1)
-# 16 -> 50 (3)
-# 19 -> 100 (1)
--
2.1.4


2015-08-26 16:22:55

by Jan Kara

[permalink] [raw]
Subject: [PATCH 05/21] ext2fs: Implement block moving in libext2fs

From: Jan Kara <[email protected]>

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/Makefile.in | 6 +-
lib/ext2fs/ext2fs.h | 4 +
lib/ext2fs/extent_map.c | 233 ++++++++++++
lib/ext2fs/move.c | 950 ++++++++++++++++++++++++++++++++++++++++++++++++
lib/ext2fs/move.h | 19 +
5 files changed, 1211 insertions(+), 1 deletion(-)
create mode 100644 lib/ext2fs/extent_map.c
create mode 100644 lib/ext2fs/move.c
create mode 100644 lib/ext2fs/move.h

diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 26aaf6fb1a15..02ede7bbf856 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -125,7 +125,9 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
unlink.o \
valid_blk.o \
version.o \
- rbtree.o
+ rbtree.o \
+ extent_map.o \
+ move.o

SRCS= ext2_err.c \
$(srcdir)/alloc.c \
@@ -215,6 +217,8 @@ SRCS= ext2_err.c \
$(srcdir)/write_bb_file.c \
$(srcdir)/rbtree.c \
$(srcdir)/tst_libext2fs.c \
+ $(srcdir)/extent_map.c \
+ $(srcdir)/move.c \
$(DEBUG_SRCS)

HFILES= bitops.h ext2fs.h ext2_io.h ext2_fs.h ext2_ext_attr.h ext3_extents.h \
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 0b8d1f6f22b1..2e07bddf6e39 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1523,6 +1523,10 @@ extern errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
extern int ext2fs_default_journal_size(__u64 num_blocks);
extern int ext2fs_journal_sb_start(int blocksize);

+/* move.c */
+errcode_t ext2fs_move_blocks(ext2_filsys fs, ext2fs_block_bitmap move_map,
+ ext2fs_block_bitmap reuse_map);
+
/* openfs.c */
extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
unsigned int block_size, io_manager manager,
diff --git a/lib/ext2fs/extent_map.c b/lib/ext2fs/extent_map.c
new file mode 100644
index 000000000000..a4e1df404dca
--- /dev/null
+++ b/lib/ext2fs/extent_map.c
@@ -0,0 +1,233 @@
+/*
+ * extent.c --- ext2 extent mapping abstraction
+ *
+ * This abstraction is used to provide a compact way of representing a
+ * translation table, for moving multiple contiguous ranges (extents)
+ * of blocks or inodes.
+ *
+ * Copyright (C) 1997, 1998 by Theodore Ts'o and
+ * PowerQuest, Inc.
+ *
+ * Copyright (C) 1999, 2000 by Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include "ext2_fs.h"
+#include "com_err.h"
+#include "move.h"
+
+struct ext2_map_extent_entry {
+ __u64 old_loc, new_loc;
+ __u64 size;
+};
+
+struct _ext2_map_extent {
+ struct ext2_map_extent_entry *list;
+ __u64 cursor;
+ __u64 size;
+ __u64 num;
+ __u64 sorted;
+};
+
+int ext2fs_extent_table_empty(ext2_map_extent extent)
+{
+ return !extent->num;
+}
+
+/*
+ * Create an extent table
+ */
+errcode_t ext2fs_create_extent_table(ext2_map_extent *ret_extent, __u64 size)
+{
+ ext2_map_extent extent;
+ errcode_t retval;
+
+ retval = ext2fs_get_mem(sizeof(struct _ext2_map_extent), &extent);
+ if (retval)
+ return retval;
+ memset(extent, 0, sizeof(struct _ext2_map_extent));
+
+ extent->size = size ? size : 50;
+ extent->cursor = 0;
+ extent->num = 0;
+ extent->sorted = 1;
+
+ retval = ext2fs_get_array(sizeof(struct ext2_map_extent_entry),
+ extent->size, &extent->list);
+ if (retval) {
+ ext2fs_free_mem(&extent);
+ return retval;
+ }
+ memset(extent->list, 0,
+ sizeof(struct ext2_map_extent_entry) * extent->size);
+ *ret_extent = extent;
+ return 0;
+}
+
+/*
+ * Free an extent table
+ */
+void ext2fs_free_extent_table(ext2_map_extent extent)
+{
+ if (extent->list)
+ ext2fs_free_mem(&extent->list);
+ extent->list = 0;
+ extent->size = 0;
+ extent->num = 0;
+ ext2fs_free_mem(&extent);
+}
+
+/*
+ * Add an entry to the extent table
+ */
+errcode_t ext2fs_add_extent_entry(ext2_map_extent extent, __u64 old_loc,
+ __u64 new_loc)
+{
+ struct ext2_map_extent_entry *ent;
+ errcode_t retval;
+ __u64 newsize;
+ __u64 curr;
+
+ if (extent->num >= extent->size) {
+ newsize = extent->size + 100;
+ retval = ext2fs_resize_mem(
+ sizeof(struct ext2_map_extent_entry) * extent->size,
+ sizeof(struct ext2_map_extent_entry) * newsize,
+ &extent->list);
+ if (retval)
+ return retval;
+ extent->size = newsize;
+ }
+ curr = extent->num;
+ ent = extent->list + curr;
+ if (curr) {
+ /*
+ * Check to see if this can be coalesced with the last
+ * extent
+ */
+ ent--;
+ if ((ent->old_loc + ent->size == old_loc) &&
+ (ent->new_loc + ent->size == new_loc)) {
+ ent->size++;
+ return 0;
+ }
+ /*
+ * Now see if we're going to ruin the sorting
+ */
+ if (ent->old_loc + ent->size > old_loc)
+ extent->sorted = 0;
+ ent++;
+ }
+ ent->old_loc = old_loc;
+ ent->new_loc = new_loc;
+ ent->size = 1;
+ extent->num++;
+ return 0;
+}
+
+/*
+ * Helper function for qsort
+ */
+static EXT2_QSORT_TYPE extent_cmp(const void *a, const void *b)
+{
+ const struct ext2_map_extent_entry *db_a;
+ const struct ext2_map_extent_entry *db_b;
+
+ db_a = (const struct ext2_map_extent_entry *) a;
+ db_b = (const struct ext2_map_extent_entry *) b;
+
+ return (db_a->old_loc - db_b->old_loc);
+}
+
+/*
+ * Given an inode map and inode number, look up the old inode number
+ * and return the new inode number.
+ */
+__u64 ext2fs_extent_translate(ext2_map_extent extent, __u64 old_loc)
+{
+ __s64 low, high, mid;
+ __u64 lowval, highval;
+ float range;
+
+ if (!extent->sorted) {
+ qsort(extent->list, extent->num,
+ sizeof(struct ext2_map_extent_entry), extent_cmp);
+ extent->sorted = 1;
+ }
+ low = 0;
+ high = extent->num-1;
+ while (low <= high) {
+#if 0
+ mid = (low+high)/2;
+#else
+ if (low == high)
+ mid = low;
+ else {
+ /* Interpolate for efficiency */
+ lowval = extent->list[low].old_loc;
+ highval = extent->list[high].old_loc;
+
+ if (old_loc < lowval)
+ range = 0;
+ else if (old_loc > highval)
+ range = 1;
+ else {
+ range = ((float) (old_loc - lowval)) /
+ (highval - lowval);
+ if (range > 0.9)
+ range = 0.9;
+ if (range < 0.1)
+ range = 0.1;
+ }
+ mid = low + ((__u64) (range * (high-low)));
+ }
+#endif
+ if ((old_loc >= extent->list[mid].old_loc) &&
+ (old_loc < extent->list[mid].old_loc + extent->list[mid].size))
+ return (extent->list[mid].new_loc +
+ (old_loc - extent->list[mid].old_loc));
+ if (old_loc < extent->list[mid].old_loc)
+ high = mid-1;
+ else
+ low = mid+1;
+ }
+ return 0;
+}
+
+/*
+ * Iterate over the contents of the extent table
+ */
+errcode_t ext2fs_iterate_extent(ext2_map_extent extent, __u64 *old_loc,
+ __u64 *new_loc, __u64 *size)
+{
+ struct ext2_map_extent_entry *ent;
+
+ if (!old_loc) {
+ extent->cursor = 0;
+ return 0;
+ }
+
+ if (extent->cursor >= extent->num) {
+ *old_loc = 0;
+ *new_loc = 0;
+ *size = 0;
+ return 0;
+ }
+
+ ent = extent->list + extent->cursor++;
+
+ *old_loc = ent->old_loc;
+ *new_loc = ent->new_loc;
+ *size = ent->size;
+ return 0;
+}
diff --git a/lib/ext2fs/move.c b/lib/ext2fs/move.c
new file mode 100644
index 000000000000..691b6d78acca
--- /dev/null
+++ b/lib/ext2fs/move.c
@@ -0,0 +1,950 @@
+#include "ext2fs.h"
+#include "ext2fsP.h"
+#include "move.h"
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+
+/*
+ * Functions to move blocks around
+ */
+enum mover_alloc_state {
+ AVOID_REUSE,
+ DESPERATION,
+};
+
+struct mover_alloc_data {
+ ext2_filsys fs;
+ enum mover_alloc_state alloc_state;
+ blk64_t new_blk;
+ ext2fs_block_bitmap reuse_map;
+ ext2fs_block_bitmap move_map;
+};
+
+static blk64_t get_new_block(struct mover_alloc_data *data)
+{
+ ext2_filsys fs = data->fs;
+
+ while (1) {
+ if (data->new_blk >= ext2fs_blocks_count(fs->super)) {
+ if (data->alloc_state == DESPERATION)
+ return 0;
+ data->alloc_state = DESPERATION;
+ data->new_blk = fs->super->s_first_data_block;
+ continue;
+ }
+ if (ext2fs_test_block_bitmap2(fs->block_map, data->new_blk) ||
+ ext2fs_test_block_bitmap2(data->move_map, data->new_blk) ||
+ (data->alloc_state == AVOID_REUSE &&
+ ext2fs_test_block_bitmap2(data->reuse_map,
+ data->new_blk))) {
+ data->new_blk++;
+ continue;
+ }
+ return data->new_blk;
+ }
+}
+
+static errcode_t move_get_new_block(ext2_filsys fs, blk64_t goal,
+ blk64_t *ret)
+{
+ struct mover_alloc_data *data =
+ (struct mover_alloc_data *)fs->alloc_data;
+ blk64_t blk;
+
+ blk = get_new_block(data);
+ if (!blk)
+ return ENOSPC;
+ *ret = blk;
+ return 0;
+}
+
+static errcode_t block_mover(ext2_filsys fs, ext2fs_block_bitmap move_map,
+ ext2fs_block_bitmap reuse_map,
+ ext2_map_extent bmap)
+{
+ blk64_t blk, old_blk, new_blk;
+ errcode_t retval;
+ __u64 size;
+ int c;
+ int to_move, moved;
+ ext2_badblocks_list badblock_list = 0;
+ int bb_modified = 0;
+ char *buf;
+ int buf_blocks = fs->inode_blocks_per_group;
+ struct mover_alloc_data data;
+ struct ext2fs_numeric_progress_struct progress;
+
+ retval = ext2fs_read_bb_inode(fs, &badblock_list);
+ if (retval)
+ return retval;
+
+ new_blk = fs->super->s_first_data_block;
+ retval = ext2fs_get_array(fs->blocksize, buf_blocks, &buf);
+ if (retval)
+ return retval;
+
+ data.fs = fs;
+ data.new_blk = fs->super->s_first_data_block;
+ data.alloc_state = AVOID_REUSE;
+ data.reuse_map = reuse_map;
+ data.move_map = move_map;
+ fs->alloc_data = &data;
+ ext2fs_set_alloc_block_callback(fs, move_get_new_block, NULL);
+
+ /*
+ * The first step is to figure out where all of the blocks
+ * will go.
+ */
+ to_move = moved = 0;
+ for (blk = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+ blk < ext2fs_blocks_count(fs->super);
+ blk += EXT2FS_CLUSTER_RATIO(fs)) {
+ if (!ext2fs_test_block_bitmap2(fs->block_map, blk))
+ continue;
+ if (!ext2fs_test_block_bitmap2(move_map, blk))
+ continue;
+ if (ext2fs_badblocks_list_test(badblock_list, blk)) {
+ ext2fs_badblocks_list_del(badblock_list, blk);
+ bb_modified++;
+ continue;
+ }
+
+ new_blk = get_new_block(&data);
+ if (!new_blk) {
+ retval = ENOSPC;
+ goto errout;
+ }
+ ext2fs_block_alloc_stats2(fs, new_blk, +1);
+ ext2fs_block_alloc_stats2(fs, blk, -1);
+ ext2fs_add_extent_entry(bmap, EXT2FS_B2C(fs, blk),
+ EXT2FS_B2C(fs, new_blk));
+ to_move++;
+ }
+
+ if (to_move == 0) {
+ retval = -1;
+ goto errout;
+ }
+
+ /*
+ * Step two is to actually move the blocks
+ */
+ retval = ext2fs_iterate_extent(bmap, 0, 0, 0);
+ if (retval)
+ goto errout;
+
+ if (fs->progress_ops && fs->progress_ops->init) {
+ (fs->progress_ops->init)(fs, &progress, "Relocating blocks",
+ to_move);
+ }
+ while (1) {
+ retval = ext2fs_iterate_extent(bmap, &old_blk, &new_blk, &size);
+ if (retval)
+ goto errout_progress;
+ if (!size)
+ break;
+ old_blk = EXT2FS_C2B(fs, old_blk);
+ new_blk = EXT2FS_C2B(fs, new_blk);
+ size = EXT2FS_C2B(fs, size);
+ do {
+ c = min(size, buf_blocks);
+ retval = io_channel_read_blk64(fs->io, old_blk, c, buf);
+ if (retval)
+ goto errout_progress;
+ retval = io_channel_write_blk64(fs->io, new_blk, c,
+ buf);
+ if (retval)
+ goto errout_progress;
+ size -= c;
+ new_blk += c;
+ old_blk += c;
+ moved += c;
+ if (fs->progress_ops && fs->progress_ops->update) {
+ io_channel_flush(fs->io);
+ fs->progress_ops->update(fs, &progress, moved);
+ }
+ } while (size > 0);
+ io_channel_flush(fs->io);
+ }
+errout_progress:
+ if (fs->progress_ops && fs->progress_ops->close) {
+ fs->progress_ops->close(fs, &progress, NULL);
+ }
+errout:
+ ext2fs_set_alloc_block_callback(fs, NULL, NULL);
+ fs->alloc_data = NULL;
+
+ if (badblock_list) {
+ if (!retval && bb_modified)
+ retval = ext2fs_update_bb_inode(fs, badblock_list);
+ ext2fs_badblocks_list_free(badblock_list);
+ }
+ ext2fs_free_mem(&buf);
+
+ return retval;
+}
+
+/*
+ * Functions to update block references from inode
+ */
+
+/*
+ * The extent translation table is stored in clusters so we need to
+ * take special care when mapping a source block number to its
+ * destination block number.
+ */
+static __u64 extent_translate(ext2_filsys fs, ext2_map_extent extent,
+ __u64 old_loc)
+{
+ __u64 new_block = EXT2FS_C2B(fs,
+ ext2fs_extent_translate(extent, EXT2FS_B2C(fs, old_loc)));
+
+ if (new_block != 0)
+ new_block += old_loc & (EXT2FS_CLUSTER_RATIO(fs) - 1);
+ return new_block;
+}
+
+static errcode_t migrate_ea_block(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode,
+ ext2_map_extent bmap)
+{
+ char *buf = NULL;
+ blk64_t new_block;
+ errcode_t err = 0;
+
+ /* No EA block? Quit early. */
+ if (ext2fs_file_acl_block(fs, inode) == 0)
+ return 0;
+ new_block = extent_translate(fs, bmap,
+ ext2fs_file_acl_block(fs, inode));
+ if (new_block == 0)
+ return 0;
+
+ /* Set the new ACL block */
+ ext2fs_file_acl_block_set(fs, inode, new_block);
+
+ /* Update checksum */
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+ err = ext2fs_get_mem(fs->blocksize, &buf);
+ if (err)
+ return err;
+ fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+ err = ext2fs_read_ext_attr3(fs, new_block, buf, ino);
+ fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
+ if (err)
+ goto out;
+ err = ext2fs_write_ext_attr3(fs, new_block, buf, ino);
+ if (err)
+ goto out;
+ }
+ err = ext2fs_write_inode_full(fs, ino, inode,
+ EXT2_INODE_SIZE(fs->super));
+out:
+ ext2fs_free_mem(&buf);
+ return err;
+}
+
+struct update_ref_process_block_struct {
+ ext2_ino_t ino;
+ struct ext2_inode * inode;
+ ext2_map_extent bmap;
+ errcode_t error;
+};
+
+static int update_ref_process_block(ext2_filsys fs, blk64_t *block_nr,
+ e2_blkcnt_t blockcnt,
+ blk64_t ref_block EXT2FS_ATTR((unused)),
+ int ref_offset EXT2FS_ATTR((unused)),
+ void *priv_data)
+{
+ struct update_ref_process_block_struct *pb;
+ blk64_t block, new_block;
+ int ret = 0;
+
+ pb = (struct update_ref_process_block_struct *) priv_data;
+ block = *block_nr;
+ new_block = extent_translate(fs, pb->bmap, block);
+ if (new_block) {
+ *block_nr = new_block;
+ ret |= BLOCK_CHANGED;
+ } else
+ new_block = block;
+
+ /* Add dir block to dblist */
+ if (LINUX_S_ISDIR(pb->inode->i_mode)) {
+ errcode_t retval;
+
+ retval = ext2fs_add_dir_block2(fs->dblist, pb->ino, new_block,
+ blockcnt);
+ if (retval) {
+ pb->error = retval;
+ ret |= BLOCK_ABORT;
+ }
+ }
+ return ret;
+}
+
+static errcode_t progress_callback(ext2_filsys fs,
+ ext2_inode_scan scan EXT2FS_ATTR((unused)),
+ dgrp_t group, void * priv_data)
+{
+ struct ext2fs_numeric_progress_struct *progress = priv_data;
+
+ io_channel_flush(fs->io);
+ if (fs->progress_ops->update)
+ (fs->progress_ops->update)(fs, progress, group + 1);
+
+ return 0;
+}
+
+/*
+ * Scan all inodes and update block references to new blocks. Also build new
+ * fs->dblist.
+ */
+static errcode_t fix_block_refs(ext2_filsys fs, ext2_map_extent bmap)
+{
+ struct update_ref_process_block_struct pb;
+ ext2_ino_t ino;
+ struct ext2_inode *inode = NULL;
+ ext2_inode_scan scan = NULL;
+ errcode_t retval;
+ char *block_buf = 0;
+ int inode_size;
+ struct ext2fs_numeric_progress_struct progress;
+
+ retval = ext2fs_open_inode_scan(fs, 0, &scan);
+ if (retval)
+ goto errout;
+
+ retval = ext2fs_get_array(fs->blocksize, 3, &block_buf);
+ if (retval)
+ goto errout;
+
+ /* Free old dblist, it needn't be valid after we moved blocks anyway */
+ if (fs->dblist) {
+ ext2fs_free_dblist(fs->dblist);
+ fs->dblist = NULL;
+ }
+ retval = ext2fs_init_dblist(fs, NULL);
+ if (retval)
+ goto errout;
+
+ if (fs->progress_ops) {
+ if (fs->progress_ops->init)
+ fs->progress_ops->init(fs, &progress,
+ "Updating block references",
+ fs->group_desc_count);
+ ext2fs_set_inode_callback(scan, progress_callback, &progress);
+ }
+
+ inode_size = EXT2_INODE_SIZE(fs->super);
+ inode = malloc(inode_size);
+ if (!inode) {
+ retval = ENOMEM;
+ goto errout_progress;
+ }
+
+ pb.inode = inode;
+ pb.error = 0;
+ pb.bmap = bmap;
+
+ while (1) {
+ retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size);
+ if (retval)
+ goto errout_progress;
+ if (!ino)
+ break;
+
+ if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO)
+ continue; /* inode not in use */
+
+ /* Remap EA block */
+ retval = migrate_ea_block(fs, ino, inode, bmap);
+ if (retval)
+ goto errout_progress;
+
+ /*
+ * Update inodes to point to new blocks; schedule directory
+ * blocks for inode remapping. Need to write out dir blocks
+ * with new inode numbers if we have metadata_csum enabled.
+ */
+ if (ext2fs_inode_has_valid_blocks2(fs, inode)) {
+ pb.ino = ino;
+ fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+ retval = ext2fs_block_iterate3(fs, ino, 0, block_buf,
+ update_ref_process_block,
+ &pb);
+ fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
+ if (retval)
+ goto errout_progress;
+ if (pb.error) {
+ retval = pb.error;
+ goto errout_progress;
+ }
+ } else if (inode->i_flags & EXT4_INLINE_DATA_FL &&
+ LINUX_S_ISDIR(inode->i_mode)) {
+ /* Add inline directory inodes to the list */
+ retval = ext2fs_add_dir_block2(fs->dblist, ino, 0, 0);
+ if (retval)
+ goto errout_progress;
+ }
+ }
+ io_channel_flush(fs->io);
+errout_progress:
+ if (fs->progress_ops && fs->progress_ops->close)
+ fs->progress_ops->close(fs, &progress, NULL);
+errout:
+ if (scan)
+ ext2fs_close_inode_scan(scan);
+ if (block_buf)
+ ext2fs_free_mem(&block_buf);
+ free(inode);
+
+ return retval;
+}
+
+/*
+ * Move block group metadata (bitmaps, inode table)
+ */
+static errcode_t move_inode_table(ext2_filsys fs, dgrp_t group,
+ blk64_t orig_loc, char *buf)
+{
+ blk64_t new_loc, n;
+ errcode_t retval;
+ long *c;
+ size_t size;
+ unsigned long long diff;
+
+ new_loc = ext2fs_inode_table_loc(fs, group);
+ retval = io_channel_read_blk64(fs->io, orig_loc,
+ fs->inode_blocks_per_group, buf);
+ if (retval)
+ return retval;
+
+ diff = llabs(new_loc - orig_loc);
+ if (diff >= fs->inode_blocks_per_group) {
+ n = fs->inode_blocks_per_group;
+ goto skip_zero;
+ }
+ /*
+ * The end of the inode table segment often contains
+ * all zeros, and we're often only moving the inode
+ * table down a block or two. If so, we can optimize
+ * things by not rewriting blocks that we know to be zero
+ * already.
+ */
+ size = fs->inode_blocks_per_group * fs->blocksize;
+ for (c = (long *)(buf + size - sizeof(long)), n = 0; n < size;
+ n += sizeof(long), c--)
+ if (*c)
+ break;
+ n = fs->inode_blocks_per_group - (n >> EXT2_BLOCK_SIZE_BITS(fs->super));
+ /* If we don't save anything with skipping zeros, don't do it... */
+ if (n + diff >= fs->inode_blocks_per_group)
+ n = fs->inode_blocks_per_group;
+skip_zero:
+ retval = io_channel_write_blk64(fs->io, new_loc, n, buf);
+ if (retval) {
+ io_channel_write_blk64(fs->io, orig_loc, n, buf);
+ return retval;
+ }
+ if (n == fs->inode_blocks_per_group)
+ return 0;
+ /*
+ * Write zeros to overwrite non-zero values in original table. We
+ * distinguish two cases:
+ * new_loc < orig_loc orig_loc + n orig_loc + itb
+ * | |XXXXXXXXXX|00000000000000|
+ *
+ * orig_loc new_loc orig_loc + n orig_loc + itb
+ * |XXXXXXXXX|XXXXXXXXXX|00000000000000|
+ */
+ if (new_loc < orig_loc) {
+ ext2fs_zero_blocks2(fs, new_loc + n, diff, NULL, NULL);
+ } else {
+ ext2fs_zero_blocks2(fs,
+ new_loc + fs->inode_blocks_per_group - diff,
+ diff, NULL, NULL);
+ }
+ return 0;
+}
+
+/*
+ * This helper function creates a block bitmap with all of the
+ * filesystem meta-data blocks.
+ */
+static errcode_t mark_table_blocks(ext2_filsys fs,
+ ext2fs_block_bitmap bmap)
+{
+ dgrp_t i;
+ blk64_t blk;
+
+ for (i = 0; i < fs->group_desc_count; i++) {
+ ext2fs_reserve_super_and_bgd(fs, i, bmap);
+
+ /*
+ * Mark the blocks used for the inode table
+ */
+ blk = ext2fs_inode_table_loc(fs, i);
+ if (blk)
+ ext2fs_mark_block_bitmap_range2(bmap, blk,
+ fs->inode_blocks_per_group);
+
+ /*
+ * Mark block used for the block bitmap
+ */
+ blk = ext2fs_block_bitmap_loc(fs, i);
+ if (blk)
+ ext2fs_mark_block_bitmap2(bmap, blk);
+
+ /*
+ * Mark block used for the inode bitmap
+ */
+ blk = ext2fs_inode_bitmap_loc(fs, i);
+ if (blk)
+ ext2fs_mark_block_bitmap2(bmap, blk);
+ }
+ return 0;
+}
+
+static errcode_t relocate_inode_table(ext2_filsys fs, dgrp_t grp,
+ blk64_t old_itable_loc,
+ blk64_t new_itable_loc, char *buf)
+{
+ errcode_t retval;
+
+ ext2fs_inode_table_loc_set(fs, grp, new_itable_loc);
+ retval = move_inode_table(fs, grp, old_itable_loc, buf);
+ if (retval) {
+ /*
+ * Back out setting of inode table location to avoid loosing
+ * inodes
+ */
+ ext2fs_inode_table_loc_set(fs, grp, old_itable_loc);
+ return retval;
+ }
+ if (EXT2FS_CLUSTER_RATIO(fs) <= 1) {
+ /* Now mark blocks under old table as free */
+ ext2fs_block_alloc_stats_range(fs, old_itable_loc,
+ fs->inode_blocks_per_group, -1);
+ /* Mark blocks under new table as used */
+ ext2fs_block_alloc_stats_range(fs, new_itable_loc,
+ fs->inode_blocks_per_group, +1);
+ }
+ return 0;
+}
+
+static void relocate_bitmap(ext2_filsys fs, dgrp_t grp, blk64_t old_loc,
+ blk64_t new_loc, int block)
+{
+ if (block) {
+ ext2fs_block_bitmap_loc_set(fs, grp, new_loc);
+ ext2fs_mark_bb_dirty(fs);
+ } else {
+ ext2fs_inode_bitmap_loc_set(fs, grp, new_loc);
+ ext2fs_mark_ib_dirty(fs);
+ }
+ if (EXT2FS_CLUSTER_RATIO(fs) <= 1)
+ ext2fs_block_alloc_stats2(fs, old_loc, -1);
+ ext2fs_block_alloc_stats2(fs, new_loc, +1);
+}
+
+/* Structure for tracking new locations of group metadata */
+struct group_metadata_loc {
+ blk64_t bb;
+ blk64_t ib;
+ blk64_t itable;
+};
+
+/*
+ * Moves group metadata whose blocks are marked in move_map. We also mark bits
+ * in move_map for data or directory blocks that need moving to make space for
+ * relocated group metadata (bitmaps, inode tables).
+ */
+static errcode_t ext2fs_move_group_metadata(ext2_filsys fs,
+ ext2fs_block_bitmap move_map,
+ struct group_metadata_loc *new_loc)
+{
+ dgrp_t i;
+ blk64_t b, table_loc, new_table_loc, bb_blk, ib_blk;
+ int relocate, move_itable;
+ char *buf;
+ errcode_t retval;
+ struct ext2fs_numeric_progress_struct progress;
+ ext2fs_block_bitmap g_meta_map = NULL;
+
+ retval = ext2fs_get_array(fs->blocksize, fs->inode_blocks_per_group,
+ &buf);
+ if (retval)
+ return retval;
+
+ /*
+ * We create a bitmap with blocks to move and group metadata. These are
+ * the blocks we cannot use as a new location of group metadata.
+ */
+ retval = ext2fs_copy_bitmap(move_map, &g_meta_map);
+ if (retval)
+ goto out;
+
+ retval = mark_table_blocks(fs, g_meta_map);
+ if (retval)
+ goto out;
+
+ if (fs->progress_ops && fs->progress_ops->init)
+ fs->progress_ops->init(fs, &progress, "Moving group metadata",
+ fs->group_desc_count);
+
+ for (i = 0; i < fs->group_desc_count; i++) {
+ relocate = 0;
+ move_itable = 0;
+
+ bb_blk = ext2fs_block_bitmap_loc(fs, i);
+ if (ext2fs_test_block_bitmap2(move_map, bb_blk)) {
+ ext2fs_block_bitmap_loc_set(fs, i, 0);
+ relocate = 1;
+ }
+
+ ib_blk = ext2fs_inode_bitmap_loc(fs, i);
+ if (ext2fs_test_block_bitmap2(move_map, ib_blk)) {
+ ext2fs_inode_bitmap_loc_set(fs, i, 0);
+ relocate = 1;
+ }
+
+ table_loc = ext2fs_inode_table_loc(fs, i);
+ for (b = 0; b < fs->inode_blocks_per_group; b++) {
+ if (ext2fs_test_block_bitmap2(move_map,
+ table_loc + b)) {
+ ext2fs_inode_table_loc_set(fs, i, 0);
+ move_itable = 1;
+ relocate = 1;
+ break;
+ }
+ }
+
+ if (relocate) {
+ if (EXT2FS_CLUSTER_RATIO(fs) <= 1 && move_itable) {
+ /*
+ * Mark blocks under old table as
+ * available for allocation of group
+ * metadata (unless they are marked in
+ * move_map) since we'd like to reuse
+ * them as much as possible.
+ */
+ for (b = 0; b < fs->inode_blocks_per_group;
+ b++) {
+ if (!ext2fs_test_block_bitmap2(move_map,
+ table_loc + b)) {
+ ext2fs_unmark_block_bitmap2(
+ g_meta_map,
+ table_loc + b);
+ }
+ }
+ }
+
+ retval = ext2fs_allocate_group_table2(fs, i, g_meta_map,
+ 0);
+ if (retval)
+ goto out_progress;
+ /*
+ * If blocks under bitmaps are used for something else,
+ * mark the blocks to be moved away and undo changes
+ * for now. We also clear corresponding bit in move_map
+ * so that it doesn't confuse block_mover().
+ */
+ b = ext2fs_block_bitmap_loc(fs, i);
+ if (b != bb_blk) {
+ ext2fs_mark_block_bitmap2(move_map, b);
+ ext2fs_block_bitmap_loc_set(fs, i, bb_blk);
+ new_loc[i].bb = b;
+ ext2fs_unmark_block_bitmap2(move_map, bb_blk);
+ }
+
+ b = ext2fs_inode_bitmap_loc(fs, i);
+ if (b != ib_blk) {
+ ext2fs_mark_block_bitmap2(move_map, b);
+ ext2fs_inode_bitmap_loc_set(fs, i, ib_blk);
+ new_loc[i].ib = b;
+ ext2fs_unmark_block_bitmap2(move_map, ib_blk);
+ }
+
+ new_table_loc = ext2fs_inode_table_loc(fs, i);
+ if (new_table_loc != table_loc) {
+ /*
+ * Restore original inode table location. We
+ * will move inode table after we make sure all
+ * blocks are moved out of the way.
+ */
+ ext2fs_inode_table_loc_set(fs, i, table_loc);
+ ext2fs_mark_block_bitmap_range2(g_meta_map,
+ table_loc,
+ fs->inode_blocks_per_group);
+ /*
+ * Mark blocks that are used by the new inode
+ * table and not by the old inode table as
+ * needing to be moved. Note that we clear all
+ * blocks under the original inode table so
+ * that block_mover() doesn't think it has to
+ * move them. Blocks won't get used for
+ * anything else since they are still marked as
+ * used by the inode table.
+ */
+ ext2fs_mark_block_bitmap_range2(move_map,
+ new_table_loc,
+ fs->inode_blocks_per_group);
+ ext2fs_unmark_block_bitmap_range2(move_map,
+ table_loc,
+ fs->inode_blocks_per_group);
+ new_loc[i].itable = new_table_loc;
+ }
+ ext2fs_group_desc_csum_set(fs, i);
+ ext2fs_mark_super_dirty(fs);
+ }
+
+ if (fs->progress_ops && fs->progress_ops->update)
+ fs->progress_ops->update(fs, &progress, i);
+ }
+ retval = 0;
+out_progress:
+ if (fs->progress_ops && fs->progress_ops->close)
+ fs->progress_ops->close(fs, &progress, NULL);
+out:
+ if (g_meta_map)
+ ext2fs_free_block_bitmap(g_meta_map);
+ ext2fs_free_mem(&buf);
+ return retval;
+}
+
+/*
+ * Move bitmaps and inode tables to new location described in new_loc. All
+ * blocks underlying new bitmap locations must be free, all blocks underlying
+ * new inode table location must be free or used by the inode table itself.
+ */
+static errcode_t finish_group_metadata_move(ext2_filsys fs,
+ struct group_metadata_loc *new_loc)
+{
+ dgrp_t i;
+ errcode_t retval;
+ char *buf;
+
+ retval = ext2fs_get_array(fs->blocksize, fs->inode_blocks_per_group,
+ &buf);
+ if (retval)
+ return retval;
+
+ for (i = 0; i < fs->group_desc_count; i++) {
+ if (new_loc[i].itable) {
+ retval = relocate_inode_table(fs, i,
+ ext2fs_inode_table_loc(fs, i),
+ new_loc[i].itable, buf);
+ if (retval)
+ goto out;
+ }
+ if (new_loc[i].bb) {
+ relocate_bitmap(fs, i, ext2fs_block_bitmap_loc(fs, i),
+ new_loc[i].bb, 1);
+ }
+ if (new_loc[i].ib) {
+ relocate_bitmap(fs, i, ext2fs_inode_bitmap_loc(fs, i),
+ new_loc[i].ib, 0);
+ }
+ if (new_loc[i].itable || new_loc[i].bb || new_loc[i].ib) {
+ ext2fs_group_desc_csum_set(fs, i);
+ ext2fs_mark_super_dirty(fs);
+ }
+ }
+out:
+ /*
+ * Flush everything so that changes to group descriptors get written
+ * out and bitmaps get written to new locations.
+ */
+ ext2fs_flush(fs);
+ ext2fs_free_mem(&buf);
+ return retval;
+}
+
+/*
+ * Journal may have been relocated; update the backup journal blocks
+ * in the superblock.
+ */
+static errcode_t fix_sb_journal_backup(ext2_filsys fs)
+{
+ errcode_t retval;
+ struct ext2_inode inode;
+
+ if (!(fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
+ return 0;
+
+ /* External journal? Nothing to do. */
+ if (fs->super->s_journal_dev && !fs->super->s_journal_inum)
+ return 0;
+
+ retval = ext2fs_read_inode(fs, fs->super->s_journal_inum, &inode);
+ if (retval)
+ return retval;
+ memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
+ fs->super->s_jnl_blocks[15] = inode.i_size_high;
+ fs->super->s_jnl_blocks[16] = inode.i_size;
+ fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
+ ext2fs_mark_super_dirty(fs);
+ return 0;
+}
+
+/*
+ * Generic block moving function. It moves blocks specified in move_map so that
+ * they become unused (it marks these blocks as free in the block bitmap). It
+ * takes care of moving block bitmaps, inode bitmaps, inode tables, xattr
+ * blocks, indirect blocks, data blocks, ... It also takes care of updating
+ * backup of journal blocks in the superblock. Blocks specified in reuse_map
+ * will be used only if there are no other blocks free.
+ *
+ * Subtle trap: resize2fs / tune2fs uses this function make space for group
+ * descriptor blocks. In memory structures are already updated however there
+ * isn't space on disk for new descriptor blocks yet. So we must be careful not
+ * to write descriptor blocks before we are done moving!
+ */
+errcode_t ext2fs_move_blocks(ext2_filsys fs, ext2fs_block_bitmap move_map,
+ ext2fs_block_bitmap reuse_map)
+{
+ errcode_t retval;
+ ext2_map_extent bmap = NULL;
+ blk64_t blk;
+ blk64_t blks_to_move = 0, blks_free = 0;
+ struct group_metadata_loc *new_loc = NULL;
+ ext2fs_block_bitmap my_move_map = NULL;
+ ext2fs_block_bitmap cluster_bmap = NULL, new_cluster_bmap = NULL;
+
+ retval = ext2fs_read_bitmaps(fs);
+ if (retval)
+ goto out;
+
+ /* Cannot proceed without our allocation callback */
+ if (fs->get_alloc_block) {
+ retval = EINVAL;
+ goto out;
+ }
+
+ for (blk = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+ blk < ext2fs_blocks_count(fs->super);
+ blk += EXT2FS_CLUSTER_RATIO(fs)) {
+ int used, move;
+
+ used = ext2fs_fast_test_block_bitmap2(fs->block_map, blk);
+ move = ext2fs_fast_test_block_bitmap2(move_map, blk);
+
+ if (!used && !move)
+ blks_free++;
+ else if (used && move)
+ blks_to_move++;
+ }
+
+ if (blks_free < blks_to_move) {
+ retval = ENOSPC;
+ goto out;
+ }
+
+ retval = ext2fs_get_arrayzero(fs->group_desc_count,
+ sizeof(struct group_metadata_loc),
+ &new_loc);
+ if (retval)
+ goto out;
+
+ /*
+ * Create own copy of move_map so that we don't clobber the user
+ * provided one
+ */
+ retval = ext2fs_copy_bitmap(move_map, &my_move_map);
+ if (retval)
+ goto out;
+
+ if (EXT2FS_CLUSTER_RATIO(fs) > 1) {
+ /*
+ * For clustered allocation we cannot immediately tell which
+ * clusters remain used and which become free since clusters
+ * can be shared by different group metadata. We thus update
+ * bitmaps only after all the metadata is relocated.
+ */
+ retval = ext2fs_allocate_block_bitmap(fs, "cluster meta blocks",
+ &cluster_bmap);
+ if (retval)
+ goto out;
+
+ retval = mark_table_blocks(fs, cluster_bmap);
+ if (retval)
+ goto out;
+ }
+
+ retval = ext2fs_move_group_metadata(fs, my_move_map, new_loc);
+ if (retval)
+ goto out;
+
+ retval = ext2fs_create_extent_table(&bmap, 0);
+ if (retval)
+ goto out;
+
+ retval = block_mover(fs, my_move_map, reuse_map, bmap);
+ if (retval) {
+ /* block_mover() returns -1 if there's nothing to move */
+ if (retval != -1)
+ goto out;
+ retval = 0;
+ }
+
+ /*
+ * Free our table now, it's not needed anymore and it frees some memory
+ * for further processing
+ */
+ if (my_move_map) {
+ ext2fs_free_block_bitmap(my_move_map);
+ my_move_map = NULL;
+ }
+
+ retval = fix_block_refs(fs, bmap);
+ if (retval)
+ goto out;
+
+ retval = fix_sb_journal_backup(fs);
+ if (retval)
+ goto out;
+
+ retval = finish_group_metadata_move(fs, new_loc);
+ if (retval)
+ goto out;
+
+ /*
+ * For clustered allocation we now have to walk bitmaps and mark
+ * clusters that got freed by group metadata relocation.
+ */
+ if (EXT2FS_CLUSTER_RATIO(fs) > 1) {
+ retval = ext2fs_allocate_block_bitmap(fs,
+ "new cluster meta blocks",
+ &new_cluster_bmap);
+ if (retval)
+ goto out;
+
+ retval = mark_table_blocks(fs, new_cluster_bmap);
+ if (retval)
+ goto out;
+
+ for (blk = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+ blk < ext2fs_blocks_count(fs->super);
+ blk += EXT2FS_CLUSTER_RATIO(fs)) {
+ if (ext2fs_test_block_bitmap2(cluster_bmap, blk) &&
+ !ext2fs_test_block_bitmap2(new_cluster_bmap, blk))
+ ext2fs_block_alloc_stats2(fs, blk, -1);
+ }
+ }
+out:
+ if (bmap)
+ ext2fs_free_extent_table(bmap);
+ if (new_loc)
+ ext2fs_free_mem(&new_loc);
+ if (my_move_map)
+ ext2fs_free_block_bitmap(my_move_map);
+ if (new_cluster_bmap)
+ ext2fs_free_block_bitmap(new_cluster_bmap);
+ if (cluster_bmap)
+ ext2fs_free_block_bitmap(cluster_bmap);
+
+ return retval;
+}
diff --git a/lib/ext2fs/move.h b/lib/ext2fs/move.h
new file mode 100644
index 000000000000..730e6745eccf
--- /dev/null
+++ b/lib/ext2fs/move.h
@@ -0,0 +1,19 @@
+#ifndef _EXT2FS_MOVE_H
+#define _EXT2FS_MOVE_H
+
+#include "ext2fs.h"
+
+typedef struct _ext2_map_extent *ext2_map_extent;
+
+/* extent_map.c */
+extern int ext2fs_extent_table_empty(ext2_map_extent extent);
+extern errcode_t ext2fs_create_extent_table(ext2_map_extent *ret_extent,
+ __u64 size);
+extern void ext2fs_free_extent_table(ext2_map_extent extent);
+extern errcode_t ext2fs_add_extent_entry(ext2_map_extent extent,
+ __u64 old_loc, __u64 new_loc);
+extern __u64 ext2fs_extent_translate(ext2_map_extent extent, __u64 old_loc);
+extern errcode_t ext2fs_iterate_extent(ext2_map_extent extent, __u64 *old_loc,
+ __u64 *new_loc, __u64 *size);
+
+#endif
--
2.1.4


2015-08-26 16:22:54

by Jan Kara

[permalink] [raw]
Subject: [PATCH 09/21] mke2fs: Allow specifying number of reserved inodes

From: Jan Kara <[email protected]>

Add option to specify number of reserved inodes in the created
filesystem.

Signed-off-by: Jan Kara <[email protected]>
---
misc/mke2fs.8.in | 6 ++++++
misc/mke2fs.c | 40 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
index 40c40d3ed065..4165c0a9d051 100644
--- a/misc/mke2fs.8.in
+++ b/misc/mke2fs.8.in
@@ -384,6 +384,12 @@ Do not attempt to discard blocks at mkfs time.
@[email protected] quota
@QUOTA_MAN_COMMENT@feature is set. Without this extended option, the default
@QUOTA_MAN_COMMENT@behavior is to initialize both user and group quotas.
+.TP
+.BI reserved_inodes= number
+Specify the number of inodes reserved for system files. This number must be
+at least 10. Currently 10 is enough but future features may require additional
+reserved inodes. Reserving more inodes after the file system is created
+requires full file system scan which can take a long time.
.RE
.TP
.BI \-f " fragment-size"
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 78b1252d8519..d61d1a332e67 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -1024,6 +1024,34 @@ static void parse_extended_opts(struct ext2_super_block *param,
r_usage++;
continue;
}
+ } else if (!strcmp(token, "reserved_inodes")) {
+ unsigned int reserved_inodes;
+
+ if (!arg) {
+ r_usage++;
+ badopt = token;
+ continue;
+ }
+ reserved_inodes = strtoul(arg, &p, 0);
+ if (*p) {
+ fprintf(stderr,
+ _("Invalid number of reserved inodes "
+ "%s\n"),
+ arg);
+ r_usage++;
+ continue;
+ }
+ /* Ino 0 is invalid so bump by 1... */
+ reserved_inodes++;
+ if (reserved_inodes < EXT2_GOOD_OLD_FIRST_INO) {
+ fprintf(stderr,
+ _("Too few reserved inodes "
+ "%s (must be at least %u)\n"),
+ arg, EXT2_GOOD_OLD_FIRST_INO - 1);
+ r_usage++;
+ continue;
+ }
+ param->s_first_ino = reserved_inodes;
} else {
r_usage++;
badopt = token;
@@ -1049,7 +1077,8 @@ static void parse_extended_opts(struct ext2_super_block *param,
"\ttest_fs\n"
"\tdiscard\n"
"\tnodiscard\n"
- "\tquotatype=<usr OR grp>\n\n"),
+ "\tquotatype=<usr OR grp>\n"
+ "\treserved_inodes=<number of reserved inodes>\n\n"),
badopt ? badopt : "");
free(buf);
exit(1);
@@ -2422,6 +2451,15 @@ profile_error:
exit(1);
}

+ /* Count with one more inode for lost+found */
+ if (fs_param.s_first_ino >= fs_param.s_inodes_count + 1) {
+ com_err(program_name, 0, _("asked for more reserved inodes than filesystem has "
+ "available (%u >= %u)\n"),
+ (unsigned int)fs_param.s_first_ino,
+ (unsigned int)fs_param.s_inodes_count + 1);
+ exit(1);
+ }
+
/*
* Calculate number of blocks to reserve
*/
--
2.1.4


2015-08-26 16:22:54

by Jan Kara

[permalink] [raw]
Subject: [PATCH 10/21] ext2fs: Fixup inline directory test

Inline directory test had hardwired number of reserved inodes. Fix the
test to read the first available inode number from the superblock.

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/inline_data.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
index 6260c5f35c1a..98c732bb2e3c 100644
--- a/lib/ext2fs/inline_data.c
+++ b/lib/ext2fs/inline_data.c
@@ -706,22 +706,23 @@ static errcode_t dir_test(ext2_filsys fs)
errcode_t retval;
char dirname[PATH_MAX];
int i;
+ ext2_ino_t ino = EXT2_FIRST_INO(fs->super);

- retval = ext2fs_mkdir(fs, 11, 11, stub_name);
+ retval = ext2fs_mkdir(fs, ino, ino, stub_name);
if (retval) {
com_err("dir_test", retval, "while creating %s dir", stub_name);
return retval;
}

- retval = ext2fs_mkdir(fs, 11, 0, parent_name);
+ retval = ext2fs_mkdir(fs, ino, 0, parent_name);
if (retval) {
com_err("dir_test", retval,
"while creating %s dir", parent_name);
return retval;
}

- retval = ext2fs_lookup(fs, 11, parent_name, strlen(parent_name),
- 0, &parent);
+ retval = ext2fs_lookup(fs, ino, parent_name,
+ strlen(parent_name), 0, &parent);
if (retval) {
com_err("dir_test", retval,
"while looking up %s dir", parent_name);
@@ -742,7 +743,7 @@ static errcode_t dir_test(ext2_filsys fs)
return 1;
}

- for (i = 0, dir = 13; i < 4; i++, dir++) {
+ for (i = 0, dir = ino + 2; i < 4; i++, dir++) {
tmp = 0;
snprintf(dirname, sizeof(dirname), "%d", i);
retval = ext2fs_mkdir(fs, parent, 0, dirname);
--
2.1.4


2015-08-26 16:22:55

by Jan Kara

[permalink] [raw]
Subject: [PATCH 06/21] ext2fs: Implement inode moving in libext2fs

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/ext2fs.h | 1 +
lib/ext2fs/move.c | 439 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 440 insertions(+)

diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 2e07bddf6e39..e76ceaa699e6 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1526,6 +1526,7 @@ extern int ext2fs_journal_sb_start(int blocksize);
/* move.c */
errcode_t ext2fs_move_blocks(ext2_filsys fs, ext2fs_block_bitmap move_map,
ext2fs_block_bitmap reuse_map);
+errcode_t ext2fs_move_inodes(ext2_filsys fs, ext2fs_inode_bitmap move_map);

/* openfs.c */
extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
diff --git a/lib/ext2fs/move.c b/lib/ext2fs/move.c
index 691b6d78acca..af1a3a70cf71 100644
--- a/lib/ext2fs/move.c
+++ b/lib/ext2fs/move.c
@@ -948,3 +948,442 @@ out:

return retval;
}
+
+static int add_dir_block(ext2_filsys fs, blk64_t *block_nr,
+ e2_blkcnt_t blockcnt,
+ blk64_t ref_block EXT2FS_ATTR((unused)),
+ int ref_offset EXT2FS_ATTR((unused)),
+ void *priv_data)
+{
+ struct update_ref_process_block_struct *pb;
+ errcode_t retval;
+
+ pb = (struct update_ref_process_block_struct *) priv_data;
+ retval = ext2fs_add_dir_block2(fs->dblist, pb->ino, *block_nr,
+ blockcnt);
+ if (retval) {
+ pb->error = retval;
+ return BLOCK_ABORT;
+ }
+ return 0;
+}
+static errcode_t build_dblist(ext2_filsys fs)
+{
+ errcode_t retval;
+ ext2_inode_scan scan = NULL;
+ ext2_ino_t ino;
+ struct ext2_inode *inode = NULL;
+ int inode_size;
+ char *block_buf = NULL;
+ struct ext2fs_numeric_progress_struct progress;
+ struct update_ref_process_block_struct pb;
+
+ retval = ext2fs_init_dblist(fs, NULL);
+ if (retval)
+ goto out;
+
+ retval = ext2fs_get_array(fs->blocksize, 3, &block_buf);
+ if (retval)
+ goto out;
+
+ retval = ext2fs_open_inode_scan(fs, 0, &scan);
+ if (retval)
+ goto out;
+
+ if (fs->progress_ops) {
+ if (fs->progress_ops->init)
+ fs->progress_ops->init(fs, &progress,
+ "Building list of directory blocks",
+ fs->group_desc_count);
+ ext2fs_set_inode_callback(scan, progress_callback, &progress);
+ }
+
+ inode_size = EXT2_INODE_SIZE(fs->super);
+ inode = malloc(inode_size);
+ if (!inode) {
+ retval = ENOMEM;
+ goto out;
+ }
+ pb.inode = inode;
+ pb.error = 0;
+ pb.bmap = NULL;
+
+ while (1) {
+ retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size);
+ if (retval)
+ goto out_progress;
+ if (!ino)
+ break;
+
+ if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO)
+ continue; /* inode not in use */
+
+ if (!LINUX_S_ISDIR(inode->i_mode))
+ continue;
+
+ if (ext2fs_inode_has_valid_blocks2(fs, inode)) {
+ pb.ino = ino;
+ retval = ext2fs_block_iterate3(fs, ino, 0, block_buf,
+ add_dir_block,
+ &pb);
+ if (retval)
+ goto out_progress;
+ if (pb.error) {
+ retval = pb.error;
+ goto out_progress;
+ }
+ } else if (inode->i_flags & EXT4_INLINE_DATA_FL) {
+ /* Add inline directory inodes to the list */
+ retval = ext2fs_add_dir_block2(fs->dblist, ino, 0, 0);
+ if (retval)
+ goto out_progress;
+ }
+ }
+out_progress:
+ if (fs->progress_ops && fs->progress_ops->close)
+ fs->progress_ops->close(fs, &progress, NULL);
+out:
+ if (scan)
+ ext2fs_close_inode_scan(scan);
+ if (block_buf)
+ ext2fs_free_mem(&block_buf);
+ if (inode)
+ free(inode);
+ if (retval && fs->dblist) {
+ ext2fs_free_dblist(fs->dblist);
+ fs->dblist = NULL;
+ }
+ return retval;
+}
+
+/* Allocate space for inodes that need moving and move them there */
+static errcode_t alloc_copy_inodes(ext2_filsys fs, ext2fs_inode_bitmap move_map,
+ ext2_map_extent imap,
+ ext2fs_inode_bitmap new_map)
+{
+ errcode_t retval;
+ __u64 ino;
+ ext2_ino_t new_ino;
+ dgrp_t group;
+ int inode_size;
+ struct ext2_inode *inode = NULL;
+ ext2fs_inode_bitmap merged_map = NULL;
+ struct ext2fs_numeric_progress_struct progress;
+
+ inode_size = EXT2_INODE_SIZE(fs->super);
+ inode = malloc(inode_size);
+ if (!inode) {
+ retval = ENOMEM;
+ goto out;
+ }
+
+ retval = ext2fs_copy_bitmap(fs->inode_map, &merged_map);
+ if (retval)
+ goto out;
+
+ for (ino = 1; ino <= fs->super->s_inodes_count; ino++) {
+ if (!ext2fs_test_inode_bitmap2(fs->inode_map, ino) &&
+ ext2fs_test_inode_bitmap2(move_map, ino))
+ ext2fs_mark_inode_bitmap2(merged_map, ino);
+ }
+
+ if (fs->progress_ops && fs->progress_ops->init)
+ fs->progress_ops->init(fs, &progress, "Moving inodes",
+ fs->group_desc_count);
+ for (group = 0; group < fs->group_desc_count; group++) {
+ if (fs->progress_ops && fs->progress_ops->update) {
+ io_channel_flush(fs->io);
+ fs->progress_ops->update(fs, &progress, group);
+ }
+ if (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT))
+ continue;
+
+ for (ino = fs->super->s_inodes_per_group * group + 1;
+ ino <= fs->super->s_inodes_count &&
+ ino <= fs->super->s_inodes_per_group * (group + 1);
+ ino++) {
+ if (!ext2fs_fast_test_inode_bitmap2(move_map, ino))
+ continue;
+
+ retval = ext2fs_read_inode_full(fs, ino, inode,
+ inode_size);
+ if (retval)
+ goto out_progress;
+
+ if (inode->i_links_count == 0 &&
+ ino != EXT2_RESIZE_INO)
+ continue; /* inode not in use */
+
+ retval = ext2fs_new_inode(fs, 0, 0, merged_map,
+ &new_ino);
+ if (retval)
+ goto out_progress;
+ ext2fs_inode_alloc_stats2(fs, new_ino, +1,
+ LINUX_S_ISDIR(inode->i_mode));
+ ext2fs_inode_alloc_stats2(fs, ino, -1,
+ LINUX_S_ISDIR(inode->i_mode));
+ ext2fs_mark_inode_bitmap2(merged_map, new_ino);
+ ext2fs_mark_inode_bitmap2(new_map, new_ino);
+ inode->i_ctime = time(0);
+ retval = ext2fs_write_inode_full(fs, new_ino, inode,
+ inode_size);
+ if (retval)
+ goto out_progress;
+
+ retval = ext2fs_add_extent_entry(imap, ino, new_ino);
+ if (retval)
+ goto out_progress;
+ }
+ }
+ io_channel_flush(fs->io);
+out_progress:
+ if (fs->progress_ops && fs->progress_ops->close)
+ fs->progress_ops->close(fs, &progress, NULL);
+out:
+ if (inode)
+ free(inode);
+ if (merged_map)
+ ext2fs_free_inode_bitmap(merged_map);
+ return retval;
+}
+
+struct dblist_scan_data {
+ ext2_filsys fs;
+ blk_t cur_block;
+ blk_t blocks;
+ ext2_ino_t last_dir_ino;
+ int dir_moved;
+ int times_updated;
+ errcode_t error;
+ ext2_map_extent imap;
+ ext2fs_inode_bitmap new_map;
+ struct ext2fs_numeric_progress_struct progress;
+};
+
+static int remap_db_entry(ext2_filsys fs, struct ext2_db_entry2 *db_info,
+ void *priv_data)
+{
+ struct dblist_scan_data *data = priv_data;
+ __u64 new_ino;
+
+ new_ino = ext2fs_extent_translate(data->imap, db_info->ino);
+ if (new_ino)
+ db_info->ino = new_ino;
+ if (fs->progress_ops && fs->progress_ops->update)
+ fs->progress_ops->update(fs, &data->progress,
+ data->cur_block++);
+ return 0;
+}
+
+/* Update inode numbers in fs->dblist */
+static errcode_t rewrite_dblist_refs(ext2_filsys fs, ext2_map_extent imap)
+{
+ errcode_t retval;
+ struct dblist_scan_data data;
+
+ data.fs = fs;
+ data.cur_block = 0;
+ data.blocks = ext2fs_dblist_count2(fs->dblist);
+ data.last_dir_ino = 0;
+ data.error = 0;
+ data.imap = imap;
+ data.new_map = NULL;
+
+ if (fs->progress_ops && fs->progress_ops->init)
+ fs->progress_ops->init(fs, &data.progress,
+ "Remapping list of directory blocks",
+ data.blocks);
+
+ retval = ext2fs_dblist_iterate2(fs->dblist, remap_db_entry, &data);
+ if (retval)
+ return retval;
+ if (data.error)
+ return data.error;
+
+ if (fs->progress_ops && fs->progress_ops->close)
+ fs->progress_ops->close(fs, &data.progress, NULL);
+ return 0;
+}
+
+static int check_and_change_inodes(ext2_ino_t dir,
+ int entry EXT2FS_ATTR((unused)),
+ struct ext2_dir_entry *dirent, int offset,
+ int blocksize EXT2FS_ATTR((unused)),
+ char *buf EXT2FS_ATTR((unused)),
+ void *priv_data)
+{
+ struct dblist_scan_data *data = priv_data;
+ struct ext2_inode inode;
+ ext2_ino_t new_ino;
+ errcode_t retval;
+ int ret = 0;
+
+ if (data->last_dir_ino != dir) {
+ data->last_dir_ino = dir;
+ data->times_updated = 0;
+ data->dir_moved = 0;
+ /*
+ * If we have checksums enabled and the has moved, then we must
+ * rewrite all dir blocks with new checksums.
+ */
+ if (EXT2_HAS_RO_COMPAT_FEATURE(data->fs->super,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) &&
+ ext2fs_test_inode_bitmap2(data->new_map, dir))
+ data->dir_moved = 1;
+ }
+
+ if (data->dir_moved)
+ ret |= DIRENT_CHANGED;
+
+ if (!dirent->inode)
+ return ret;
+
+ new_ino = ext2fs_extent_translate(data->imap, dirent->inode);
+ if (!new_ino)
+ return ret;
+ dirent->inode = new_ino;
+ ret |= DIRENT_CHANGED;
+
+ /* Update directory mtime and ctime for each dir */
+ if (!data->times_updated) {
+ retval = ext2fs_read_inode(data->fs, dir, &inode);
+ if (retval == 0) {
+ inode.i_mtime = inode.i_ctime = time(0);
+ retval = ext2fs_write_inode(data->fs, dir, &inode);
+ if (retval) {
+ data->error = retval;
+ ret |= DIRENT_ABORT;
+ }
+ }
+ data->times_updated = 1;
+ }
+
+ if (data->fs->progress_ops && data->fs->progress_ops->update &&
+ !offset) {
+ io_channel_flush(data->fs->io);
+ data->fs->progress_ops->update(data->fs, &data->progress,
+ data->cur_block++);
+ }
+ return ret;
+}
+
+/* Scan all directory blocks and update inode references */
+static errcode_t fix_inode_refs(ext2_filsys fs, ext2_map_extent imap,
+ ext2fs_inode_bitmap new_map)
+{
+ errcode_t retval;
+ struct dblist_scan_data data;
+
+ data.fs = fs;
+ data.cur_block = 0;
+ data.blocks = ext2fs_dblist_count2(fs->dblist);
+ data.last_dir_ino = 0;
+ data.error = 0;
+ data.imap = imap;
+ data.new_map = new_map;
+
+ if (fs->progress_ops && fs->progress_ops->init)
+ fs->progress_ops->init(fs, &data.progress,
+ "Updating inode references",
+ data.blocks);
+
+ /*
+ * dblist still has old inode numbers so iteration will use inodes
+ * at old positions. That is fine though because we didn't clobber
+ * that space yet.
+ */
+ fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+ retval = ext2fs_dblist_dir_iterate(fs->dblist,
+ DIRENT_FLAG_INCLUDE_EMPTY, 0,
+ check_and_change_inodes, &data);
+ fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
+ if (fs->progress_ops && fs->progress_ops->close)
+ fs->progress_ops->close(fs, &data.progress, NULL);
+ if (retval)
+ return retval;
+ if (data.error)
+ return data.error;
+
+ return 0;
+}
+
+/*
+ * Generic inode moving function. It moves inodes specified in move_map so that
+ * they become unused (it marks these inodes as free in the inode bitmap). It
+ * takes care of rewriting references from directory entries as well.
+ *
+ * The function uses fs->dblist for rewriting if present (the caller is
+ * responsible for it to be correct and complete in that case) and updates
+ * inode numbers there. Otherwise we build our own fs->dblist.
+ */
+errcode_t ext2fs_move_inodes(ext2_filsys fs, ext2fs_inode_bitmap move_map)
+{
+ errcode_t retval;
+ ext2_map_extent imap = NULL;
+ ext2fs_inode_bitmap new_map = NULL;
+ ext2_ino_t ino;
+ unsigned int inodes_to_move = 0, inodes_free = 0;
+
+ retval = ext2fs_read_bitmaps(fs);
+ if (retval)
+ return retval;
+
+ for (ino = 1; ino <= fs->super->s_inodes_count; ino++) {
+ int used, move;
+
+ used = ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino);
+ move = ext2fs_fast_test_inode_bitmap2(move_map, ino);
+ if (!used && !move)
+ inodes_free++;
+ else if (used && move)
+ inodes_to_move++;
+ }
+
+ if (inodes_free < inodes_to_move) {
+ retval = ENOSPC;
+ goto out;
+ }
+
+ retval = ext2fs_create_extent_table(&imap, 0);
+ if (retval)
+ goto out;
+
+ retval = ext2fs_allocate_inode_bitmap(fs, "new inodes", &new_map);
+ if (retval)
+ goto out;
+
+ if (!fs->dblist) {
+ retval = build_dblist(fs);
+ if (retval)
+ goto out;
+ }
+
+ retval = alloc_copy_inodes(fs, move_map, imap, new_map);
+ if (retval)
+ goto out;
+
+ /* Nothing to map? */
+ if (ext2fs_extent_table_empty(imap))
+ goto out;
+
+ retval = rewrite_dblist_refs(fs, imap);
+ if (retval)
+ goto out;
+
+ retval = fix_inode_refs(fs, imap, new_map);
+ if (retval)
+ goto out;
+
+ retval = rewrite_dblist_refs(fs, imap);
+out:
+ if (retval && fs->dblist) {
+ /* dblist is likely invalid, free it */
+ ext2fs_free_dblist(fs->dblist);
+ fs->dblist = NULL;
+ }
+ if (imap)
+ ext2fs_free_extent_table(imap);
+ if (new_map)
+ ext2fs_free_inode_bitmap(new_map);
+ return retval;
+}
--
2.1.4


2015-08-26 16:22:55

by Jan Kara

[permalink] [raw]
Subject: [PATCH 07/21] tune2fs: Implement setting and disabling of 64-bit feature

Currently resize2fs is used to toggle 64-bit feature. However tune2fs
should logically handle that as toggling any other feature. Since we
have now factored out block moving code from resize2fs it is relatively
easy to implement toggling of the feature within tune2fs.

For now we leave the same functionality also in resize2fs for testing.
Later we can make resize2fs call tune2fs for backward compatibility.

Signed-off-by: Jan Kara <[email protected]>
---
misc/tune2fs.c | 376 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 354 insertions(+), 22 deletions(-)

diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index d2e8b20f64e2..e7e5ccde25c2 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -447,10 +447,329 @@ static void request_fsck_afterwards(ext2_filsys fs)
printf("%s", _("(and reboot afterwards!)\n"));
}

-static void convert_64bit(ext2_filsys fs, int direction)
+static errcode_t fix_resize_inode(ext2_filsys fs)
{
- if (!direction)
- return;
+ errcode_t retval;
+
+ if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE))
+ return 0;
+
+ retval = ext2fs_wipe_resize_inode(fs);
+ if (retval)
+ return retval;
+
+ return ext2fs_create_resize_inode(fs);
+}
+
+/*
+ * Make blocks that are needed for new group metadata unused and write there
+ * new group descriptors
+ */
+static errcode_t move_bg_metadata(ext2_filsys fs, ext2_filsys new_fs)
+{
+ dgrp_t i;
+ blk64_t b, c, d, old_desc_blocks, new_desc_blocks, j;
+ ext2fs_block_bitmap old_map = NULL, new_map = NULL;
+ int old, new;
+ errcode_t retval;
+ int cluster_ratio;
+ int need_new_block = 0;
+
+ retval = ext2fs_allocate_block_bitmap(fs, "old map", &old_map);
+ if (retval)
+ goto out;
+
+ retval = ext2fs_allocate_block_bitmap(fs, "new map", &new_map);
+ if (retval)
+ goto out;
+
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_INCOMPAT_META_BG)) {
+ old_desc_blocks = fs->super->s_first_meta_bg;
+ new_desc_blocks = new_fs->super->s_first_meta_bg;
+ } else {
+ old_desc_blocks = fs->desc_blocks +
+ fs->super->s_reserved_gdt_blocks;
+ new_desc_blocks = new_fs->desc_blocks +
+ new_fs->super->s_reserved_gdt_blocks;
+ }
+
+ /* Construct bitmaps of super/descriptor blocks in old and new fs */
+ for (i = 0; i < fs->group_desc_count; i++) {
+ retval = ext2fs_super_and_bgd_loc2(fs, i, &b, &c, &d, NULL);
+ if (retval)
+ goto out;
+ if (b)
+ ext2fs_mark_block_bitmap2(old_map, b);
+ for (j = 0; c != 0 && j < old_desc_blocks; j++)
+ ext2fs_mark_block_bitmap2(old_map, c + j);
+ if (d)
+ ext2fs_mark_block_bitmap2(old_map, d);
+
+ retval = ext2fs_super_and_bgd_loc2(new_fs, i, &b, &c, &d, NULL);
+ if (retval)
+ goto out;
+ if (b)
+ ext2fs_mark_block_bitmap2(new_map, b);
+ for (j = 0; c != 0 && j < new_desc_blocks; j++)
+ ext2fs_mark_block_bitmap2(new_map, c + j);
+ if (d)
+ ext2fs_mark_block_bitmap2(new_map, d);
+ }
+
+ cluster_ratio = EXT2FS_CLUSTER_RATIO(new_fs);
+
+ /* Find changes in block allocations for bg metadata */
+ for (b = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+ b < ext2fs_blocks_count(new_fs->super);
+ b += cluster_ratio) {
+ old = ext2fs_test_block_bitmap2(old_map, b);
+ new = ext2fs_test_block_bitmap2(new_map, b);
+
+ if (old && !new) {
+ /* mark old_map, unmark new_map */
+ if (cluster_ratio == 1)
+ ext2fs_block_alloc_stats2(new_fs, b, -1);
+ } else if (!old && new)
+ need_new_block = 1; /* unmark old_map, mark new_map */
+ else {
+ ext2fs_unmark_block_bitmap2(old_map, b);
+ ext2fs_unmark_block_bitmap2(new_map, b);
+ }
+ }
+
+ /*
+ * new_map now shows blocks that have been newly allocated.
+ * old_map now shows blocks that have been newly freed.
+ */
+
+ if (need_new_block) {
+ /*
+ * Now relocate metadata & data conflicting with new descriptor
+ * blocks
+ */
+ retval = ext2fs_move_blocks(new_fs, new_map, old_map);
+ if (retval)
+ goto out;
+
+ /* Now mark blocks for new group descriptors as used */
+ for (b = EXT2FS_B2C(new_fs, new_fs->super->s_first_data_block);
+ b < ext2fs_blocks_count(new_fs->super);
+ b += cluster_ratio) {
+ if (ext2fs_test_block_bitmap2(new_map, b) &&
+ !ext2fs_test_block_bitmap2(new_fs->block_map, b))
+ ext2fs_block_alloc_stats2(new_fs, b, +1);
+ }
+ }
+
+ if (cluster_ratio > 1) {
+ /* Free unused clusters */
+ for (b = EXT2FS_B2C(new_fs, new_fs->super->s_first_data_block);
+ b < ext2fs_blocks_count(new_fs->super);
+ b += cluster_ratio)
+ if (ext2fs_test_block_bitmap2(old_map, b))
+ ext2fs_block_alloc_stats2(new_fs, b, -1);
+ }
+
+ /* Now update resize inode */
+ retval = fix_resize_inode(new_fs);
+out:
+ if (old_map)
+ ext2fs_free_block_bitmap(old_map);
+ if (new_map)
+ ext2fs_free_block_bitmap(new_map);
+ return retval;
+}
+
+
+/* Toggle 64bit mode */
+static errcode_t resize_group_descriptors(ext2_filsys *fs_p, int direction)
+{
+ void *o, *n, *new_group_desc;
+ dgrp_t i;
+ int copy_size;
+ errcode_t retval;
+ ext2_filsys new_fs = NULL;
+ ext2_filsys fs = *fs_p;
+
+ retval = ext2fs_dup_handle(fs, &new_fs);
+ if (retval)
+ return retval;
+
+ if (direction < 0) {
+ new_fs->super->s_feature_incompat &=
+ ~EXT4_FEATURE_INCOMPAT_64BIT;
+ new_fs->super->s_desc_size = EXT2_MIN_DESC_SIZE;
+ } else {
+ new_fs->super->s_feature_incompat |=
+ EXT4_FEATURE_INCOMPAT_64BIT;
+ new_fs->super->s_desc_size = EXT2_MIN_DESC_SIZE_64BIT;
+ }
+
+ o = new_fs->group_desc;
+ new_fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
+ EXT2_DESC_PER_BLOCK(new_fs->super));
+ retval = ext2fs_get_arrayzero(new_fs->desc_blocks,
+ fs->blocksize, &new_group_desc);
+ if (retval)
+ goto out;
+
+ n = new_group_desc;
+
+ if (EXT2_DESC_SIZE(fs->super) <= EXT2_DESC_SIZE(new_fs->super))
+ copy_size = EXT2_DESC_SIZE(fs->super);
+ else
+ copy_size = EXT2_DESC_SIZE(new_fs->super);
+ for (i = 0; i < fs->group_desc_count; i++) {
+ memcpy(n, o, copy_size);
+ n += EXT2_DESC_SIZE(new_fs->super);
+ o += EXT2_DESC_SIZE(fs->super);
+ }
+
+ ext2fs_free_mem(&new_fs->group_desc);
+ new_fs->group_desc = new_group_desc;
+
+ for (i = 0; i < fs->group_desc_count; i++)
+ ext2fs_group_desc_csum_set(new_fs, i);
+
+ /*
+ * Update number of reserved blocks so that we need to alloc / free as
+ * few blocks as possible
+ */
+ if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE) &&
+ (fs->desc_blocks != new_fs->desc_blocks)) {
+ int new;
+
+ new = ((int) new_fs->super->s_reserved_gdt_blocks) +
+ (fs->desc_blocks - new_fs->desc_blocks);
+ if (new < 0)
+ new = 0;
+ if (new > (int) fs->blocksize / 4)
+ new = fs->blocksize / 4;
+ new_fs->super->s_reserved_gdt_blocks = new;
+ }
+
+ retval = move_bg_metadata(fs, new_fs);
+
+ /* Return the modified filesystem */
+ new_fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
+ ext2fs_mark_super_dirty(new_fs);
+ ext2fs_free(fs);
+ *fs_p = new_fs;
+ new_fs = NULL;
+out:
+ if (new_fs)
+ ext2fs_free(new_fs);
+ return retval;
+}
+
+/* Zero out the high bits of extent fields */
+static errcode_t zero_high_bits_in_extents(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode)
+{
+ ext2_extent_handle_t handle;
+ struct ext2fs_extent extent;
+ int op = EXT2_EXTENT_ROOT;
+ errcode_t errcode;
+
+ if (!(inode->i_flags & EXT4_EXTENTS_FL))
+ return 0;
+
+ errcode = ext2fs_extent_open(fs, ino, &handle);
+ if (errcode)
+ return errcode;
+
+ while (1) {
+ errcode = ext2fs_extent_get(handle, op, &extent);
+ if (errcode)
+ break;
+
+ op = EXT2_EXTENT_NEXT_SIB;
+
+ if (extent.e_pblk > (1ULL << 32)) {
+ extent.e_pblk &= (1ULL << 32) - 1;
+ errcode = ext2fs_extent_replace(handle, 0, &extent);
+ if (errcode)
+ break;
+ }
+ }
+
+ /* Ok if we run off the end */
+ if (errcode == EXT2_ET_EXTENT_NO_NEXT)
+ errcode = 0;
+ ext2fs_extent_free(handle);
+ return errcode;
+}
+
+/* Zero out the high bits of inodes. */
+static errcode_t zero_high_bits_in_inodes(ext2_filsys fs)
+{
+ int length = EXT2_INODE_SIZE(fs->super);
+ struct ext2_inode *inode = NULL;
+ ext2_inode_scan scan = NULL;
+ errcode_t retval;
+ ext2_ino_t ino;
+
+ if (fs->super->s_creator_os != EXT2_OS_LINUX)
+ return 0;
+
+ retval = ext2fs_open_inode_scan(fs, 0, &scan);
+ if (retval)
+ return retval;
+
+ retval = ext2fs_get_mem(length, &inode);
+ if (retval)
+ goto out;
+
+ do {
+ retval = ext2fs_get_next_inode_full(scan, &ino, inode, length);
+ if (retval)
+ goto out;
+ if (!ino)
+ break;
+ if (!ext2fs_test_inode_bitmap2(fs->inode_map, ino))
+ continue;
+
+ /*
+ * Here's how we deal with high block number fields:
+ *
+ * - i_size_high has been been written out with i_size_lo
+ * since the ext2 days, so no conversion is needed.
+ *
+ * - i_blocks_hi is guarded by both the huge_file feature and
+ * inode flags and has always been written out with
+ * i_blocks_lo if the feature is set. The field is only
+ * ever read if both feature and inode flag are set, so
+ * we don't need to zero it now.
+ *
+ * - i_file_acl_high can be uninitialized, so zero it if
+ * it isn't already.
+ */
+ if (inode->osd2.linux2.l_i_file_acl_high) {
+ inode->osd2.linux2.l_i_file_acl_high = 0;
+ retval = ext2fs_write_inode_full(fs, ino, inode,
+ length);
+ if (retval)
+ goto out;
+ }
+
+ retval = zero_high_bits_in_extents(fs, ino, inode);
+ if (retval)
+ goto out;
+ } while (ino);
+
+out:
+ if (inode)
+ ext2fs_free_mem(&inode);
+ if (scan)
+ ext2fs_close_inode_scan(scan);
+ return retval;
+}
+
+static errcode_t convert_64bit(ext2_filsys *fs_p, int direction)
+{
+ ext2_filsys fs = *fs_p;
+ errcode_t retval;

/*
* Is resize2fs going to demand a fsck run? Might as well tell the
@@ -459,21 +778,25 @@ static void convert_64bit(ext2_filsys fs, int direction)
if (!fsck_requested &&
((fs->super->s_state & EXT2_ERROR_FS) ||
!(fs->super->s_state & EXT2_VALID_FS) ||
- fs->super->s_lastcheck < fs->super->s_mtime))
+ fs->super->s_lastcheck < fs->super->s_mtime)) {
request_fsck_afterwards(fs);
- if (fsck_requested)
- fprintf(stderr, _("After running e2fsck, please run `resize2fs %s %s"),
- direction > 0 ? "-b" : "-s", fs->device_name);
- else
- fprintf(stderr, _("Please run `resize2fs %s %s"),
- direction > 0 ? "-b" : "-s", fs->device_name);
+ return 0;
+ }

- if (undo_file)
- fprintf(stderr, _(" -z \"%s\""), undo_file);
- if (direction > 0)
- fprintf(stderr, _("' to enable 64-bit mode.\n"));
- else
- fprintf(stderr, _("' to disable 64-bit mode.\n"));
+ /*
+ * Read bitmaps now since we are definitely going to need them and they
+ * get properly duplicated when creating new fs handle in
+ * resize_group_descriptors()
+ */
+ retval = ext2fs_read_bitmaps(fs);
+ if (retval)
+ return retval;
+
+ retval = resize_group_descriptors(fs_p, direction);
+ if (retval)
+ return retval;
+
+ return zero_high_bits_in_inodes(*fs_p);
}

/* Rewrite extents */
@@ -1253,9 +1576,9 @@ mmp_error:
}

/*
- * We don't actually toggle 64bit; resize2fs does that. But this
- * must come after the metadata_csum feature_on so that it won't
- * complain about the lack of 64bit.
+ * Handle 64-bit conversion. We return the feature to the original
+ * value for now until the conversion really takes place. Otherwise
+ * some helper macros get confused.
*/
if (FEATURE_ON(E2P_FEATURE_INCOMPAT,
EXT4_FEATURE_INCOMPAT_64BIT)) {
@@ -1264,8 +1587,8 @@ mmp_error:
"while mounted!\n"));
exit(1);
}
- sb->s_feature_incompat &= ~EXT4_FEATURE_INCOMPAT_64BIT;
feature_64bit = 1;
+ sb->s_feature_incompat &= ~EXT4_FEATURE_INCOMPAT_64BIT;
}
if (FEATURE_OFF(E2P_FEATURE_INCOMPAT,
EXT4_FEATURE_INCOMPAT_64BIT)) {
@@ -1274,8 +1597,8 @@ mmp_error:
"while mounted!\n"));
exit(1);
}
- sb->s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT;
feature_64bit = -1;
+ sb->s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT;
}

if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
@@ -3080,6 +3403,16 @@ retry_open:
}
}

+ if (feature_64bit) {
+ retval = convert_64bit(&fs, feature_64bit);
+ if (retval) {
+ com_err(program_name, retval, "%s",
+ _("while changing 64-bit feature"));
+ rc = 1;
+ goto closefs;
+ }
+ }
+
if (rewrite_checksums)
rewrite_metadata_checksums(fs);

@@ -3113,6 +3446,5 @@ closefs:
exit(1);
}

- convert_64bit(fs, feature_64bit);
return (ext2fs_close_free(&fs) ? 1 : 0);
}
--
2.1.4


2015-08-26 16:22:56

by Jan Kara

[permalink] [raw]
Subject: [PATCH 13/21] tune2fs: Add support for changing number of reserved inodes

Signed-off-by: Jan Kara <[email protected]>
---
misc/tune2fs.8.in | 5 +++
misc/tune2fs.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 115 insertions(+)

diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in
index 4373fc49b255..922705329112 100644
--- a/misc/tune2fs.8.in
+++ b/misc/tune2fs.8.in
@@ -236,6 +236,11 @@ program.
This superblock setting is only honored in 2.6.35+ kernels;
and not at all by the ext2 and ext3 file system drivers.
.TP
+.BI reserved_inodes= number_of_reserved_inodes
+Set the number of inodes reserved for system files. This number must be
+at least 10. Currently 10 is enough but future features may require additional
+reserved inodes. Reserving more inodes requires full file system scan so it
+can take a long time.
.B test_fs
Set a flag in the filesystem superblock indicating that it may be
mounted using experimental kernel code, such as the ext4dev filesystem.
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index e7e5ccde25c2..873a7e2b08c2 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -92,6 +92,7 @@ static char *features_cmd;
static char *mntopts_cmd;
static int stride, stripe_width;
static int stride_set, stripe_width_set;
+static unsigned long new_first_ino;
static char *extended_cmd;
static unsigned long new_inode_size;
static char *ext_mount_opts;
@@ -2300,6 +2301,42 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts)
continue;
}
ext_mount_opts = strdup(arg);
+ } else if (!strcmp(token, "reserved_inodes")) {
+ if (!arg) {
+ r_usage++;
+ continue;
+ }
+ new_first_ino = strtoul(arg, &p, 0);
+ if (*p || new_first_ino == ULONG_MAX) {
+ fprintf(stderr,
+ _("Invalid number of reserved inodes "
+ "%s\n"),
+ arg);
+ r_usage++;
+ continue;
+ }
+ /* Ino 0 is invalid so bump by 1... */
+ new_first_ino++;
+ if (new_first_ino < EXT2_GOOD_OLD_FIRST_INO) {
+ fprintf(stderr,
+ _("Too few reserved inodes "
+ "%s (must be at least %u)\n"),
+ arg, EXT2_GOOD_OLD_FIRST_INO - 1);
+ r_usage++;
+ continue;
+ }
+ if (new_first_ino > fs->super->s_inodes_count) {
+ fprintf(stderr,
+ _("Too many reserved inodes %s "
+ "(must be at most %u)\n"),
+ arg, fs->super->s_inodes_count - 1);
+ r_usage++;
+ continue;
+ }
+ /*
+ * Here should go further feature tests to disallow
+ * admin to free used system inode
+ */
} else
r_usage++;
}
@@ -2314,6 +2351,7 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts)
"\tmount_opts=<extended default mount options>\n"
"\tstride=<RAID per-disk chunk size in blocks>\n"
"\tstripe_width=<RAID stride*data disks in blocks>\n"
+ "\treserved_inodes=<number of reserved inodes>\n"
"\ttest_fs\n"
"\t^test_fs\n"));
free(buf);
@@ -2988,6 +3026,75 @@ fs_update_journal_user(struct ext2_super_block *sb, __u8 old_uuid[UUID_SIZE])
return 0;
}

+/* Zero range of inodes and mark them as free / used */
+static errcode_t zero_inodes_range(ext2_filsys fs, ext2_ino_t start,
+ ext2_ino_t end, int inuse)
+{
+ char *inode;
+ int length = EXT2_INODE_SIZE(fs->super);
+ ext2_ino_t ino;
+ errcode_t retval;
+
+ retval = ext2fs_get_memzero(length, &inode);
+ if (retval)
+ return retval;
+
+ for (ino = start; ino <= end; ino++) {
+ ext2fs_inode_alloc_stats(fs, ino, inuse);
+ retval = ext2fs_write_inode_full(fs, ino,
+ (struct ext2_inode *)inode,
+ length);
+ if (retval)
+ break;
+ }
+ ext2fs_free_mem(inode);
+
+ return retval;
+}
+
+static errcode_t update_reserved_inodes(ext2_filsys fs)
+{
+ errcode_t retval = 0;
+ ext2fs_inode_bitmap imap;
+ ext2_ino_t ino, first_ino = fs->super->s_first_ino;
+
+ if (new_first_ino == first_ino)
+ return 0;
+
+ /* Group descriptors will need writing as well */
+ fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
+
+ /* Freeing reserved inodes is easy */
+ if (new_first_ino < first_ino) {
+ retval = zero_inodes_range(fs, new_first_ino, first_ino - 1,
+ -1);
+ if (retval)
+ return retval;
+ goto out;
+ }
+
+ retval = ext2fs_allocate_inode_bitmap(fs, "inodes to move", &imap);
+ if (retval)
+ return retval;
+
+ for (ino = fs->super->s_first_ino; ino < new_first_ino; ino++)
+ ext2fs_mark_inode_bitmap2(imap, ino);
+
+ retval = ext2fs_move_inodes(fs, imap);
+ ext2fs_free_inode_bitmap(imap);
+ if (retval)
+ return retval;
+
+ retval = zero_inodes_range(fs, first_ino, new_first_ino - 1, +1);
+ if (retval)
+ return retval;
+out:
+ fs->super->s_first_ino = new_first_ino;
+ ext2fs_mark_super_dirty(fs);
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
errcode_t retval;
@@ -3413,6 +3520,9 @@ retry_open:
}
}

+ if (new_first_ino)
+ update_reserved_inodes(fs);
+
if (rewrite_checksums)
rewrite_metadata_checksums(fs);

--
2.1.4


2015-08-26 16:22:56

by Jan Kara

[permalink] [raw]
Subject: [PATCH 11/21] tests: Specify number of reserved inodes for tests where it matters

There are some tests which rely on number of reserved inodes being 10.
In some cases they expect particular blocks being allocated to
particular files or they specify rather small number of inodes in the
filesystem. Make these tests explicitly set number of reserved inodes to
the expected value since the default is going to change and these tests
would start failing.

Signed-off-by: Jan Kara <[email protected]>
---
tests/d_special_files/expect | 2 +-
tests/d_special_files/script | 4 ++--
tests/f_desc_size_bad/script | 2 +-
tests/f_dup4/script | 2 +-
tests/f_uninit_last_uninit/script | 2 +-
tests/m_bigjournal/script | 2 +-
tests/r_move_itable/expect | 2 +-
tests/r_move_itable/script | 4 ++--
8 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/tests/d_special_files/expect b/tests/d_special_files/expect
index f729b0f1c7be..511cd215fae6 100644
--- a/tests/d_special_files/expect
+++ b/tests/d_special_files/expect
@@ -1,5 +1,5 @@
debugfs create special files
-mke2fs -Fq -b 1024 test.img 512
+mke2fs -Fq -b 1024 -E reserved_inodes=10 test.img 512
Exit status is 0
debugfs -R ''stat foo'' -w test.img
Inode: 12 Type: symlink Mode: 0777 Flags: 0x0
diff --git a/tests/d_special_files/script b/tests/d_special_files/script
index 9bdff5d005a4..ab0a4120945c 100644
--- a/tests/d_special_files/script
+++ b/tests/d_special_files/script
@@ -11,9 +11,9 @@ echo "debugfs create special files" > $OUT

dd if=/dev/zero of=$TMPFILE bs=1k count=512 > /dev/null 2>&1

-echo "mke2fs -Fq -b 1024 test.img 512" >> $OUT
+echo "mke2fs -Fq -b 1024 -E reserved_inodes=10 test.img 512" >> $OUT

-$MKE2FS -Fq $TMPFILE 512 > /dev/null 2>&1
+$MKE2FS -Fq -E reserved_inodes=10 $TMPFILE 512 > /dev/null 2>&1
status=$?
echo Exit status is $status >> $OUT

diff --git a/tests/f_desc_size_bad/script b/tests/f_desc_size_bad/script
index 544032860641..1c639f2e6ebb 100644
--- a/tests/f_desc_size_bad/script
+++ b/tests/f_desc_size_bad/script
@@ -6,7 +6,7 @@ fi
DESCRIPTION="bad superblock s_desc_size"
SKIP_GUNZIP=true
touch $TMPFILE
-$MKE2FS -F -o Linux -O 64bit,extents -N 32 -b 1024 -g 512 -E desc_size=128 $TMPFILE 2048 > $test_name.log 2>&1
+$MKE2FS -F -o Linux -O 64bit,extents -N 32 -b 1024 -g 512 -E desc_size=128,reserved_inodes=10 $TMPFILE 2048 > $test_name.log 2>&1
$DEBUGFS -R "ssv desc_size 129" -w $TMPFILE >> $test_name.log 2>&1

E2FSCK_TIME=200704102100
diff --git a/tests/f_dup4/script b/tests/f_dup4/script
index 498f5259c388..2d9946dd4285 100644
--- a/tests/f_dup4/script
+++ b/tests/f_dup4/script
@@ -6,7 +6,7 @@ TEST_DATA="$test_name.tmp"
echo "/ Murphy Magic. The SeCrEt of the UnIvErSe is 43, NOT 42" > $TEST_DATA

touch $TMPFILE
-$MKE2FS -N 32 -F -o Linux -b 1024 $TMPFILE 100 > /dev/null 2>&1
+$MKE2FS -N 32 -E reserved_inodes=10 -F -o Linux -b 1024 $TMPFILE 100 > /dev/null 2>&1
$DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1
set_current_time 20070410210000
set_super_value lastcheck 0
diff --git a/tests/f_uninit_last_uninit/script b/tests/f_uninit_last_uninit/script
index 376c97823d59..543b7b2a5f67 100644
--- a/tests/f_uninit_last_uninit/script
+++ b/tests/f_uninit_last_uninit/script
@@ -3,7 +3,7 @@ if test -x $DEBUGFS_EXE; then
SKIP_GUNZIP="true"

touch $TMPFILE
-$MKE2FS -N 32 -F -o Linux -O uninit_bg -b 1024 $TMPFILE 10000 > /dev/null 2>&1
+$MKE2FS -N 32 -F -o Linux -O uninit_bg -E reserved_inodes=10 -b 1024 $TMPFILE 10000 > /dev/null 2>&1
$DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1
set_current_time 20070410210000
set_super_value lastcheck 0
diff --git a/tests/m_bigjournal/script b/tests/m_bigjournal/script
index 576d99ecb23f..6660244b30a5 100644
--- a/tests/m_bigjournal/script
+++ b/tests/m_bigjournal/script
@@ -2,7 +2,7 @@ DESCRIPTION="journal over 4GB in size"
FS_SIZE=11000000
DUMPE2FS_IGNORE_80COL=1
export DUMPE2FS_IGNORE_80COL
-MKE2FS_OPTS="-t ext4 -G 512 -N 1280 -J size=5000 -q -E lazy_journal_init,lazy_itable_init,nodiscard"
+MKE2FS_OPTS="-t ext4 -G 512 -N 1280 -J size=5000 -q -E lazy_journal_init,lazy_itable_init,nodiscard,reserved_inodes=10"
if [ $(uname -s) = "Darwin" ]; then
echo "$test_name: $DESCRIPTION: skipped for HFS+ (no sparse files)"
return 0
diff --git a/tests/r_move_itable/expect b/tests/r_move_itable/expect
index cec0038ae6fe..b798604c7ce0 100644
--- a/tests/r_move_itable/expect
+++ b/tests/r_move_itable/expect
@@ -1,4 +1,4 @@
-mke2fs -q -F -o Linux -b 1024 -g 256 test.img 1024
+mke2fs -q -F -o Linux -b 1024 -g 256 -E reserved_inodes=10 test.img 1024
resize2fs -p test.img 10000
Resizing the filesystem on test.img to 10000 (1k) blocks.
Begin pass 1 (max = 35)
diff --git a/tests/r_move_itable/script b/tests/r_move_itable/script
index 3f02a799f2f5..b2ffb527c7c5 100644
--- a/tests/r_move_itable/script
+++ b/tests/r_move_itable/script
@@ -13,8 +13,8 @@ cp /dev/null $OUT

dd if=/dev/zero of=$TMPFILE bs=1k count=512 > /dev/null 2>&1

-echo mke2fs -q -F -o Linux -b 1024 -g 256 test.img 1024 > $OUT
-$MKE2FS -q -F -o Linux -b 1024 -g 256 $TMPFILE 1024 2>&1 |
+echo mke2fs -q -F -o Linux -b 1024 -g 256 -E reserved_inodes=10 test.img 1024 > $OUT
+$MKE2FS -q -F -o Linux -b 1024 -g 256 -E reserved_inodes=10 $TMPFILE 1024 2>&1 |
sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" >> $OUT

echo resize2fs -p test.img 10000 >> $OUT
--
2.1.4


2015-08-26 16:22:51

by Jan Kara

[permalink] [raw]
Subject: [PATCH 03/21] resize2fs: Use ext2fs_allocate_group_table2()

Signed-off-by: Jan Kara <[email protected]>
---
resize/resize2fs.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 041ff75029b2..df6fdf1de913 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -1482,8 +1482,10 @@ static errcode_t blocks_to_move(ext2_resize_t rfs)
ext2fs_block_bitmap_loc(fs, i))
continue;

- retval = ext2fs_allocate_group_table(fs, i,
- rfs->reserve_blocks);
+ retval = ext2fs_allocate_group_table2(fs, i,
+ rfs->reserve_blocks,
+ EXT2FS_ALLOC_TABLE_UPDATE_STATS |
+ EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP);
if (retval)
goto errout;

@@ -1493,7 +1495,6 @@ static errcode_t blocks_to_move(ext2_resize_t rfs)
*/
if (ext2fs_block_bitmap_loc(old_fs, i) !=
(blk = ext2fs_block_bitmap_loc(fs, i))) {
- ext2fs_block_alloc_stats2(fs, blk, +1);
if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
!ext2fs_test_block_bitmap2(meta_bmap, blk))
ext2fs_mark_block_bitmap2(rfs->move_blocks,
@@ -1501,7 +1502,6 @@ static errcode_t blocks_to_move(ext2_resize_t rfs)
}
if (ext2fs_inode_bitmap_loc(old_fs, i) !=
(blk = ext2fs_inode_bitmap_loc(fs, i))) {
- ext2fs_block_alloc_stats2(fs, blk, +1);
if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
!ext2fs_test_block_bitmap2(meta_bmap, blk))
ext2fs_mark_block_bitmap2(rfs->move_blocks,
@@ -1527,7 +1527,6 @@ static errcode_t blocks_to_move(ext2_resize_t rfs)
*/
for (blk = ext2fs_inode_table_loc(fs, i), j=0;
j < fs->inode_blocks_per_group ; j++, blk++) {
- ext2fs_block_alloc_stats2(fs, blk, +1);
if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
!ext2fs_test_block_bitmap2(meta_bmap, blk))
ext2fs_mark_block_bitmap2(rfs->move_blocks,
--
2.1.4


2015-08-26 16:22:51

by Jan Kara

[permalink] [raw]
Subject: [PATCH 02/21] ext2fs: Implement ext2fs_allocate_group_table2()

Implement ext2fs_allocate_group_table2() which marks blocks also in
fs->block_map unconditionally and which always updates allocation
statistics.

Signed-off-by: Jan Kara <[email protected]>
---
lib/ext2fs/alloc_tables.c | 97 ++++++++++++++++++++++++++++++++++-------------
lib/ext2fs/ext2fs.h | 7 ++++
2 files changed, 78 insertions(+), 26 deletions(-)

diff --git a/lib/ext2fs/alloc_tables.c b/lib/ext2fs/alloc_tables.c
index 3e1952fa63e8..7b1f9da22fb8 100644
--- a/lib/ext2fs/alloc_tables.c
+++ b/lib/ext2fs/alloc_tables.c
@@ -81,19 +81,62 @@ static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
return first_free;
}

-errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
- ext2fs_block_bitmap bmap)
+static void update_block_bitmap_stats(ext2_filsys fs, blk64_t blk, int len,
+ unsigned long flags, int flex_bg)
+{
+ if (flags & EXT2FS_ALLOC_TABLE_UPDATE_STATS) {
+ ext2fs_block_alloc_stats_range(fs, blk, len, +1);
+ if (!(flags & EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP))
+ ext2fs_unmark_block_bitmap_range2(fs->block_map, blk,
+ len);
+ } else if (flags & EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP) {
+ dgrp_t g, end;
+
+ ext2fs_mark_block_bitmap_range2(fs->block_map, blk, len);
+ /* For fs without FLEX_BG, bitmaps can stay uninitialized */
+ if (!flex_bg)
+ return;
+ /*
+ * It's an overkill to assume more than two groups can be
+ * touched but the code is easy to understand this way.
+ */
+ end = ext2fs_group_of_blk2(fs, blk + len - 1);
+ for (g = ext2fs_group_of_blk2(fs, blk); g <= end; g++) {
+ if (ext2fs_bg_flags_test(fs, g, EXT2_BG_BLOCK_UNINIT)) {
+ ext2fs_bg_flags_clear(fs, g,
+ EXT2_BG_BLOCK_UNINIT);
+ ext2fs_group_desc_csum_set(fs, g);
+ }
+ }
+ }
+}
+
+/*
+ * Allocate group metadata (bitmaps, inode table) if not present. If
+ * reserve_bmap is set, we use that as a bitmap of blocks free for allocation
+ * (and update used blocks there as well as in fs->block_map).
+ */
+errcode_t ext2fs_allocate_group_table2(ext2_filsys fs, dgrp_t group,
+ ext2fs_block_bitmap reserve_bmap,
+ unsigned long flags)
{
errcode_t retval;
blk64_t group_blk, start_blk, last_blk, new_blk;
dgrp_t last_grp = 0;
int rem_grps = 0, flexbg_size = 0, table_offset = 0;
+ ext2fs_block_bitmap bmap;

group_blk = ext2fs_group_first_block2(fs, group);
last_blk = ext2fs_group_last_block2(fs, group);

- if (!bmap)
+ if (reserve_bmap == fs->block_map)
+ reserve_bmap = NULL;
+
+ if (!reserve_bmap) {
bmap = fs->block_map;
+ flags |= EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP;
+ } else
+ bmap = reserve_bmap;

if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
@@ -153,15 +196,10 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
last_blk, 1, bmap, &new_blk);
if (retval)
return retval;
- ext2fs_mark_block_bitmap2(bmap, new_blk);
ext2fs_block_bitmap_loc_set(fs, group, new_blk);
- if (flexbg_size) {
- dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
- ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
- ext2fs_free_blocks_count_add(fs->super, -1);
- ext2fs_bg_flags_clear(fs, gr, EXT2_BG_BLOCK_UNINIT);
- ext2fs_group_desc_csum_set(fs, gr);
- }
+ update_block_bitmap_stats(fs, new_blk, 1, flags, flexbg_size);
+ if (reserve_bmap)
+ ext2fs_mark_block_bitmap2(bmap, new_blk);
}

if (flexbg_size) {
@@ -186,15 +224,10 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
last_blk, 1, bmap, &new_blk);
if (retval)
return retval;
- ext2fs_mark_block_bitmap2(bmap, new_blk);
ext2fs_inode_bitmap_loc_set(fs, group, new_blk);
- if (flexbg_size) {
- dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
- ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
- ext2fs_free_blocks_count_add(fs->super, -1);
- ext2fs_bg_flags_clear(fs, gr, EXT2_BG_BLOCK_UNINIT);
- ext2fs_group_desc_csum_set(fs, gr);
- }
+ update_block_bitmap_stats(fs, new_blk, 1, flags, flexbg_size);
+ if (reserve_bmap)
+ ext2fs_mark_block_bitmap2(bmap, new_blk);
}

/*
@@ -223,18 +256,30 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
bmap, &new_blk);
if (retval)
return retval;
- if (flexbg_size)
- ext2fs_block_alloc_stats_range(fs, new_blk,
- fs->inode_blocks_per_group, +1);
- else
- ext2fs_mark_block_bitmap_range2(fs->block_map,
- new_blk, fs->inode_blocks_per_group);
ext2fs_inode_table_loc_set(fs, group, new_blk);
+ update_block_bitmap_stats(fs, new_blk,
+ fs->inode_blocks_per_group, flags,
+ flexbg_size);
+ if (reserve_bmap)
+ ext2fs_mark_block_bitmap_range2(bmap,
+ new_blk, fs->inode_blocks_per_group);
}
ext2fs_group_desc_csum_set(fs, group);
return 0;
}

+errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
+ ext2fs_block_bitmap bmap)
+{
+ unsigned long flags = 0;
+
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_INCOMPAT_FLEX_BG))
+ flags |= EXT2FS_ALLOC_TABLE_UPDATE_STATS;
+
+ return ext2fs_allocate_group_table2(fs, group, bmap, flags);
+}
+
errcode_t ext2fs_allocate_tables(ext2_filsys fs)
{
errcode_t retval;
@@ -248,7 +293,7 @@ errcode_t ext2fs_allocate_tables(ext2_filsys fs)
for (i = 0; i < fs->group_desc_count; i++) {
if (fs->progress_ops && fs->progress_ops->update)
(fs->progress_ops->update)(fs, &progress, i);
- retval = ext2fs_allocate_group_table(fs, i, fs->block_map);
+ retval = ext2fs_allocate_group_table(fs, i, 0);
if (retval)
return retval;
}
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 13cbe567b19c..3eda8d1f4ad3 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -713,6 +713,13 @@ void ext2fs_block_alloc_stats_range(ext2_filsys fs, blk64_t blk,
extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
extern errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
ext2fs_block_bitmap bmap);
+/* Update allocation statistics */
+#define EXT2FS_ALLOC_TABLE_UPDATE_STATS 0x0001
+/* Set fs->block_map in addition to provided bmap */
+#define EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP 0x0002
+extern errcode_t ext2fs_allocate_group_table2(ext2_filsys fs, dgrp_t group,
+ ext2fs_block_bitmap bmap,
+ unsigned long flags);

/* badblocks.c */
extern errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size);
--
2.1.4