2008-03-17 13:28:51

by Theodore Ts'o

[permalink] [raw]
Subject: Respin of the uninit_group patches

I've reworked this patch series to clean them up a bit. In
particular, an unused ext2fs_scan_inode flag (EXT2_SF_DO_CSUM) was
removed, and I made ext2fs_group_desc_csum() static, and added
ext2fs_group_desc_csum_set(). In addition, ext2fs_group_desc_set()
and ext2fs_group_desc_verify() take an ext2_filsys argument instead of
a superblock and a pointer to a group descriptor, in order to simplify
the calling code.

If this looks good, this should be the next set of patches to move
into the 'next' branch.

- Ted




2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 03/11] Rename feature name from gdt_checksum to uninit_groups

From: Jose R. Santos <[email protected]>

This name is a more intuitive option when running mke2fs.

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
lib/e2p/feature.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c
index fc6052c..cf37447 100644
--- a/lib/e2p/feature.c
+++ b/lib/e2p/feature.c
@@ -45,7 +45,7 @@ static struct feature feature_list[] = {
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_HUGE_FILE,
"huge_file" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
- "gdt_checksum" },
+ "uninit_groups" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_DIR_NLINK,
"dir_nlink" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE,
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 05/11] Make tune2fs uninit block group aware

From: Jose R. Santos <[email protected]>

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
misc/tune2fs.8.in | 7 +++++++
misc/tune2fs.c | 8 ++++++--
2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in
index 8b59c17..b5af4d0 100644
--- a/misc/tune2fs.8.in
+++ b/misc/tune2fs.8.in
@@ -439,10 +439,17 @@ Reserve space so the block group descriptor table may grow in the
future.
.B Tune2fs
only supports clearing this filesystem feature.
+.TP
+.B uninit_groups
+Allow the kernel to initialize bitmaps and inode tables and keep a high
+watermark for the unused inodes in a filesystem, to reduce
+.BR e2fsck (8)
+time.
.RE
.IP
After setting or clearing
.BR sparse_super ,
+.BR uninit_groups ,
.BR filetype ,
or
.B resize_inode
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index dc44d56..8f5d564 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -118,6 +118,7 @@ static __u32 ok_features[3] = {
EXT4_FEATURE_INCOMPAT_FLEX_BG,
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM |
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
};

@@ -130,7 +131,8 @@ static __u32 clear_ok_features[3] = {
EXT2_FEATURE_INCOMPAT_FILETYPE |
EXT4_FEATURE_INCOMPAT_FLEX_BG,
/* R/O compat */
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM
};

/*
@@ -245,6 +247,7 @@ static int release_blocks_proc(ext2_filsys fs, blk_t *blocknr,
ext2fs_unmark_block_bitmap(fs->block_map,block);
group = ext2fs_group_of_blk(fs, block);
fs->group_desc[group].bg_free_blocks_count++;
+ ext2fs_group_desc_csum_set(fs, group);
fs->super->s_free_blocks_count++;
return 0;
}
@@ -315,7 +318,6 @@ static void update_mntopts(ext2_filsys fs, char *mntopts)
static void update_feature_set(ext2_filsys fs, char *features)
{
struct ext2_super_block *sb= fs->super;
- __u32 old_compat, old_incompat, old_ro_compat;
__u32 old_features[3];
int type_err;
unsigned int mask_err;
@@ -410,6 +412,8 @@ static void update_feature_set(ext2_filsys fs, char *features)

if (FEATURE_CHANGED(E2P_FEATURE_RO_INCOMPAT,
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
+ FEATURE_CHANGED(E2P_FEATURE_RO_INCOMPAT,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM) ||
FEATURE_CHANGED(E2P_FEATURE_INCOMPAT,
EXT2_FEATURE_INCOMPAT_FILETYPE) ||
FEATURE_CHANGED(E2P_FEATURE_COMPAT,
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 07/11] Make resize2fs uninit block group aware

From: Jose R. Santos <[email protected]>

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
resize/main.c | 7 +++++++
resize/resize2fs.c | 19 ++++++++++++++-----
2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/resize/main.c b/resize/main.c
index f283e41..5811ec8 100644
--- a/resize/main.c
+++ b/resize/main.c
@@ -298,6 +298,13 @@ int main (int argc, char ** argv)
printf (_("Couldn't find valid filesystem superblock.\n"));
exit (1);
}
+
+ if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
+ com_err(program_name, EXT2_ET_RO_UNSUPP_FEATURE,
+ ":- uninit_groups");
+ exit(1);
+ }
+
/*
* Check for compatibility with the feature sets. We need to
* be more stringent than ext2fs_open().
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index da86ece..3d1c003 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -339,7 +339,8 @@ retry:
numblocks = fs->super->s_blocks_per_group;
i = old_fs->group_desc_count - 1;
fs->group_desc[i].bg_free_blocks_count += (numblocks-old_numblocks);
-
+ ext2fs_group_desc_csum_set(fs, i);
+
/*
* If the number of block groups is staying the same, we're
* done and can exit now. (If the number block groups is
@@ -414,6 +415,7 @@ retry:
fs->group_desc[i].bg_free_inodes_count =
fs->super->s_inodes_per_group;
fs->group_desc[i].bg_used_dirs_count = 0;
+ ext2fs_group_desc_csum_set(fs, i);

retval = ext2fs_allocate_group_table(fs, i, 0);
if (retval) goto errout;
@@ -1231,9 +1233,11 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
if (retval) goto errout;

group = (new_inode-1) / EXT2_INODES_PER_GROUP(rfs->new_fs->super);
- if (LINUX_S_ISDIR(inode->i_mode))
+ if (LINUX_S_ISDIR(inode->i_mode)) {
rfs->new_fs->group_desc[group].bg_used_dirs_count++;
-
+ ext2fs_group_desc_csum_set(rfs->new_fs, group);
+ }
+
#ifdef RESIZE2FS_DEBUG
if (rfs->flags & RESIZE_DEBUG_INODEMAP)
printf("Inode moved %u->%u\n", ino, new_inode);
@@ -1488,6 +1492,7 @@ static errcode_t move_itables(ext2_resize_t rfs)
ext2fs_unmark_block_bitmap(fs->block_map, blk);

rfs->old_fs->group_desc[i].bg_inode_table = new_blk;
+ ext2fs_group_desc_csum_set(rfs->old_fs, i);
ext2fs_mark_super_dirty(rfs->old_fs);
ext2fs_flush(rfs->old_fs);

@@ -1585,8 +1590,10 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs)
count++;
if ((count == fs->super->s_blocks_per_group) ||
(blk == fs->super->s_blocks_count-1)) {
- fs->group_desc[group++].bg_free_blocks_count =
+ fs->group_desc[group].bg_free_blocks_count =
group_free;
+ ext2fs_group_desc_csum_set(fs, group);
+ group++;
count = 0;
group_free = 0;
}
@@ -1610,8 +1617,10 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs)
count++;
if ((count == fs->super->s_inodes_per_group) ||
(ino == fs->super->s_inodes_count)) {
- fs->group_desc[group++].bg_free_inodes_count =
+ fs->group_desc[group].bg_free_inodes_count =
group_free;
+ ext2fs_group_desc_csum_set(fs, group);
+ group++;
count = 0;
group_free = 0;
}
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 04/11] Add support for creating filesystems using uninit block group

From: Jose R. Santos <[email protected]>

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
misc/mke2fs.8.in | 7 +++++++
misc/mke2fs.c | 44 ++++++++++++++++++++++++++++++++------------
2 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
index 14c3ca5..a32c34a 100644
--- a/misc/mke2fs.8.in
+++ b/misc/mke2fs.8.in
@@ -427,6 +427,13 @@ Store file type information in directory entries.
.TP
.B has_journal
Create an ext3 journal (as if using the
+.TP
+.B uninit_groups
+Create a filesystem without initializing all of the groups. This speeds
+up filesystem creation time noticably, and can also reduce
+.BR e2fsck time
+dramatically. This feature causes the filesystem to be read-only in
+older kernels is not supported in most Linux kernels, use with caution.
.B \-j
option).
@[email protected]
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 072a3a8..acff08b 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -433,6 +433,8 @@ static void write_inode_tables(ext2_filsys fs)
num, blk, error_message(retval));
exit(1);
}
+ /* The kernel doesn't need to zero the itable blocks */
+ fs->group_desc[i].bg_flags |= EXT2_BG_INODE_ZEROED;
}
if (sync_kludge) {
if (sync_kludge == 1)
@@ -448,34 +450,49 @@ static void write_inode_tables(ext2_filsys fs)
static void setup_lazy_bg(ext2_filsys fs)
{
dgrp_t i;
- int blks;
+ int blks, csum_flag;
struct ext2_super_block *sb = fs->super;
struct ext2_group_desc *bg = fs->group_desc;

- if (EXT2_HAS_COMPAT_FEATURE(fs->super,
- EXT2_FEATURE_COMPAT_LAZY_BG)) {
+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
+ if (EXT2_HAS_COMPAT_FEATURE(fs->super, EXT2_FEATURE_COMPAT_LAZY_BG) ||
+ csum_flag) {
for (i = 0; i < fs->group_desc_count; i++, bg++) {
if ((i == 0) ||
- (i == fs->group_desc_count-1))
+ (i == fs->group_desc_count - 1 && !csum_flag))
continue;
if (bg->bg_free_inodes_count ==
sb->s_inodes_per_group) {
- bg->bg_free_inodes_count = 0;
bg->bg_flags |= EXT2_BG_INODE_UNINIT;
- sb->s_free_inodes_count -=
- sb->s_inodes_per_group;
+ if (!csum_flag) {
+ bg->bg_free_inodes_count = 0;
+ sb->s_free_inodes_count -=
+ sb->s_inodes_per_group;
+ }
}
+
+ /* Skip groups with GDT backups because the resize
+ * inode has blocks allocated in them, and the last
+ * group because it needs block bitmap padding. */
+ if ((ext2fs_bg_has_super(fs, i) &&
+ sb->s_reserved_gdt_blocks) ||
+ i == fs->group_desc_count - 1)
+ continue;
+
blks = ext2fs_super_and_bgd_loc(fs, i, 0, 0, 0, 0);
- if (bg->bg_free_blocks_count == blks) {
- bg->bg_free_blocks_count = 0;
+ if (bg->bg_free_blocks_count == blks &&
+ bg->bg_flags & EXT2_BG_INODE_UNINIT) {
bg->bg_flags |= EXT2_BG_BLOCK_UNINIT;
- sb->s_free_blocks_count -= blks;
+ if (!csum_flag) {
+ bg->bg_free_blocks_count = 0;
+ sb->s_free_blocks_count -= blks;
+ }
}
}
}
}

-
static void create_root_dir(ext2_filsys fs)
{
errcode_t retval;
@@ -912,7 +929,8 @@ static __u32 ok_features[3] = {
EXT4_FEATURE_INCOMPAT_FLEX_BG,
/* R/O compat */
EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
+ EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM
};


@@ -1774,6 +1792,8 @@ int main (int argc, char *argv[])
}
no_journal:

+ if (!super_only)
+ ext2fs_set_gdt_csum(fs);
if (!quiet)
printf(_("Writing superblocks and "
"filesystem accounting information: "));
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 10/11] Add new m_lazy test case

From: Jose R. Santos <[email protected]>

Add test case for lazy bg feature.

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
tests/m_lazy/expect.1 | 166 +++++++++++++++++++++++++++++++++++++++++++++++++
tests/m_lazy/script | 4 +
2 files changed, 170 insertions(+), 0 deletions(-)
create mode 100644 tests/m_lazy/expect.1
create mode 100644 tests/m_lazy/script

diff --git a/tests/m_lazy/expect.1 b/tests/m_lazy/expect.1
new file mode 100644
index 0000000..e0e459c
--- /dev/null
+++ b/tests/m_lazy/expect.1
@@ -0,0 +1,166 @@
+Filesystem label=
+OS type: Linux
+Block size=1024 (log=0)
+Fragment size=1024 (log=0)
+32768 inodes, 131072 blocks
+6553 blocks (5.00%) reserved for the super user
+First data block=1
+Maximum filesystem blocks=67371008
+16 block groups
+8192 blocks per group, 8192 fragments per group
+2048 inodes per group
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729
+
+Writing inode tables: done
+Writing superblocks and filesystem accounting information: done
+
+Filesystem features: ext_attr resize_inode dir_index lazy_bg 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: 28683/32768 files (0.0% non-contiguous), 77097/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 lazy_bg filetype sparse_super
+Default mount options: (none)
+Filesystem state: clean
+Errors behavior: Continue
+Filesystem OS type: Linux
+Inode count: 32768
+Block count: 131072
+Reserved block count: 6553
+Free blocks: 53975
+Free inodes: 4085
+First block: 1
+Block size: 1024
+Fragment size: 1024
+Reserved GDT blocks: 256
+Blocks per group: 8192
+Fragments per group: 8192
+Inodes per group: 2048
+Inode blocks per group: 256
+Mount count: 0
+Check interval: 15552000 (6 months)
+Reserved blocks uid: 0
+Reserved blocks gid: 0
+First inode: 11
+Inode size: 128
+Default directory hash: tea
+
+
+Group 0: (Blocks 1-8192)
+ Primary superblock at 1, Group descriptors at 2-2
+ 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
+ Free blocks: 531-8192
+ Free inodes: 12-2048
+Group 1: (Blocks 8193-16384) [Inode not init]
+ Backup superblock at 8193, Group descriptors at 8194-8194
+ Reserved GDT blocks at 8195-8450
+ Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
+ Inode table at 8453-8708 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 8709-16384
+ Free inodes:
+Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
+ Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
+ Inode table at 16387-16642 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 3: (Blocks 24577-32768) [Inode not init]
+ Backup superblock at 24577, Group descriptors at 24578-24578
+ Reserved GDT blocks at 24579-24834
+ Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
+ Inode table at 24837-25092 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 25093-32768
+ Free inodes:
+Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
+ Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
+ Inode table at 32771-33026 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 5: (Blocks 40961-49152) [Inode not init]
+ Backup superblock at 40961, Group descriptors at 40962-40962
+ Reserved GDT blocks at 40963-41218
+ Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
+ Inode table at 41221-41476 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 41477-49152
+ Free inodes:
+Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
+ Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
+ Inode table at 49155-49410 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 7: (Blocks 57345-65536) [Inode not init]
+ Backup superblock at 57345, Group descriptors at 57346-57346
+ Reserved GDT blocks at 57347-57602
+ Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
+ Inode table at 57605-57860 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 57861-65536
+ Free inodes:
+Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
+ Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
+ Inode table at 65539-65794 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 9: (Blocks 73729-81920) [Inode not init]
+ Backup superblock at 73729, Group descriptors at 73730-73730
+ Reserved GDT blocks at 73731-73986
+ Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
+ Inode table at 73989-74244 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 74245-81920
+ Free inodes:
+Group 10: (Blocks 81921-90112) [Inode not init, Block not init]
+ Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
+ Inode table at 81923-82178 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 11: (Blocks 90113-98304) [Inode not init, Block not init]
+ Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
+ Inode table at 90115-90370 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 12: (Blocks 98305-106496) [Inode not init, Block not init]
+ Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
+ Inode table at 98307-98562 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 13: (Blocks 106497-114688) [Inode not init, Block not init]
+ Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
+ Inode table at 106499-106754 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 14: (Blocks 114689-122880) [Inode not init, Block not init]
+ Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
+ Inode table at 114691-114946 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 15: (Blocks 122881-131071)
+ Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
+ Inode table at 122883-123138 (+2)
+ 7933 free blocks, 2048 free inodes, 0 directories
+ Free blocks: 123139-131071
+ Free inodes: 30721-32768
diff --git a/tests/m_lazy/script b/tests/m_lazy/script
new file mode 100644
index 0000000..35be0c8
--- /dev/null
+++ b/tests/m_lazy/script
@@ -0,0 +1,4 @@
+DESCRIPTION="lazy group feature"
+FS_SIZE=131072
+MKE2FS_OPTS="-O lazy_bg"
+. $cmd_dir/run_mke2fs
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 06/11] Make dumpe2fs uninit block group aware

From: Jose R. Santos <[email protected]>

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
misc/dumpe2fs.c | 13 +++++++++----
1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c
index f6e7972..10ec5c0 100644
--- a/misc/dumpe2fs.c
+++ b/misc/dumpe2fs.c
@@ -112,7 +112,8 @@ static void print_bg_opts(ext2_filsys fs, dgrp_t i)
{
int first = 1, bg_flags;

- if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_LAZY_BG)
+ if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_LAZY_BG ||
+ fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
bg_flags = fs->group_desc[i].bg_flags;
else
bg_flags = 0;
@@ -210,11 +211,15 @@ static void list_desc (ext2_filsys fs)
diff = fs->group_desc[i].bg_inode_table - first_block;
if (diff > 0)
printf(" (+%ld)", diff);
- printf (_("\n %d free blocks, %d free inodes, "
- "%d directories\n"),
+ printf (_("\n %u free blocks, %u free inodes, "
+ "%u directories%s"),
fs->group_desc[i].bg_free_blocks_count,
fs->group_desc[i].bg_free_inodes_count,
- fs->group_desc[i].bg_used_dirs_count);
+ fs->group_desc[i].bg_used_dirs_count,
+ fs->group_desc[i].bg_itable_unused ? "" : "\n");
+ if (fs->group_desc[i].bg_itable_unused)
+ printf (_(", %u unused inodes\n"),
+ fs->group_desc[i].bg_itable_unused);
if (block_bitmap) {
fputs(_(" Free blocks: "), stdout);
ext2fs_get_block_bitmap_range(fs->block_map,
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 08/11] Make debugfs uninit block group aware

From: Jose R. Santos <[email protected]>

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
debugfs/debugfs.c | 18 +++++++++++++++---
1 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index c4da2a2..1a4471f 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -288,7 +288,10 @@ void do_show_super_stats(int argc, char *argv[])
FILE *out;
struct ext2_group_desc *gdp;
int c, header_only = 0;
- int numdirs = 0, first;
+ int numdirs = 0, first, gdt_csum;
+
+ gdt_csum = EXT2_HAS_RO_COMPAT_FEATURE(current_fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);

reset_getopt();
while ((c = getopt (argc, argv, "h")) != EOF) {
@@ -324,7 +327,7 @@ void do_show_super_stats(int argc, char *argv[])
"inode table at %u\n"
" %d free %s, "
"%d free %s, "
- "%d used %s\n",
+ "%d used %s%s",
i, gdp->bg_block_bitmap,
gdp->bg_inode_bitmap, gdp->bg_inode_table,
gdp->bg_free_blocks_count,
@@ -333,12 +336,21 @@ void do_show_super_stats(int argc, char *argv[])
gdp->bg_free_inodes_count != 1 ? "inodes" : "inode",
gdp->bg_used_dirs_count,
gdp->bg_used_dirs_count != 1 ? "directories"
- : "directory");
+ : "directory", gdt_csum ? ", " : "\n");
+ if (gdt_csum)
+ fprintf(out, "%d unused %s\n",
+ gdp->bg_itable_unused,
+ gdp->bg_itable_unused != 1 ? "inodes":"inode");
first = 1;
print_bg_opts(gdp, EXT2_BG_INODE_UNINIT, "Inode not init",
&first, out);
print_bg_opts(gdp, EXT2_BG_BLOCK_UNINIT, "Block not init",
&first, out);
+ if (gdt_csum) {
+ fprintf(out, "%sChecksum 0x%04x",
+ first ? " [":", ", gdp->bg_checksum);
+ first = 0;
+ }
if (!first)
fputs("]\n", out);
}
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 11/11] Add m_uninit test case

From: Jose R. Santos <[email protected]>

Add test case to test for uninit block groups.

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
tests/m_uninit/expect.1 | 166 +++++++++++++++++++++++++++++++++++++++++++++++
tests/m_uninit/script | 4 +
2 files changed, 170 insertions(+), 0 deletions(-)
create mode 100644 tests/m_uninit/expect.1
create mode 100644 tests/m_uninit/script

diff --git a/tests/m_uninit/expect.1 b/tests/m_uninit/expect.1
new file mode 100644
index 0000000..c6c32b9
--- /dev/null
+++ b/tests/m_uninit/expect.1
@@ -0,0 +1,166 @@
+Filesystem label=
+OS type: Linux
+Block size=1024 (log=0)
+Fragment size=1024 (log=0)
+32768 inodes, 131072 blocks
+6553 blocks (5.00%) reserved for the super user
+First data block=1
+Maximum filesystem blocks=67371008
+16 block groups
+8192 blocks per group, 8192 fragments per group
+2048 inodes per group
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729
+
+Writing inode tables: done
+Writing superblocks and filesystem accounting information: done
+
+Filesystem features: ext_attr resize_inode dir_index filetype sparse_super uninit_groups
+
+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/32768 files (9.1% non-contiguous), 5691/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 uninit_groups
+Default mount options: (none)
+Filesystem state: clean
+Errors behavior: Continue
+Filesystem OS type: Linux
+Inode count: 32768
+Block count: 131072
+Reserved block count: 6553
+Free blocks: 125381
+Free inodes: 32757
+First block: 1
+Block size: 1024
+Fragment size: 1024
+Reserved GDT blocks: 256
+Blocks per group: 8192
+Fragments per group: 8192
+Inodes per group: 2048
+Inode blocks per group: 256
+Mount count: 0
+Check interval: 15552000 (6 months)
+Reserved blocks uid: 0
+Reserved blocks gid: 0
+First inode: 11
+Inode size: 128
+Default directory hash: tea
+
+
+Group 0: (Blocks 1-8192)
+ Primary superblock at 1, Group descriptors at 2-2
+ 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
+ Free blocks: 531-8192
+ Free inodes: 12-2048
+Group 1: (Blocks 8193-16384) [Inode not init]
+ Backup superblock at 8193, Group descriptors at 8194-8194
+ Reserved GDT blocks at 8195-8450
+ Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
+ Inode table at 8453-8708 (+260)
+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks: 8709-16384
+ Free inodes:
+Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
+ Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
+ Inode table at 16387-16642 (+2)
+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
+Group 3: (Blocks 24577-32768) [Inode not init]
+ Backup superblock at 24577, Group descriptors at 24578-24578
+ Reserved GDT blocks at 24579-24834
+ Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
+ Inode table at 24837-25092 (+260)
+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks: 25093-32768
+ Free inodes:
+Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
+ Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
+ Inode table at 32771-33026 (+2)
+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
+Group 5: (Blocks 40961-49152) [Inode not init]
+ Backup superblock at 40961, Group descriptors at 40962-40962
+ Reserved GDT blocks at 40963-41218
+ Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
+ Inode table at 41221-41476 (+260)
+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks: 41477-49152
+ Free inodes:
+Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
+ Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
+ Inode table at 49155-49410 (+2)
+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
+Group 7: (Blocks 57345-65536) [Inode not init]
+ Backup superblock at 57345, Group descriptors at 57346-57346
+ Reserved GDT blocks at 57347-57602
+ Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
+ Inode table at 57605-57860 (+260)
+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks: 57861-65536
+ Free inodes:
+Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
+ Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
+ Inode table at 65539-65794 (+2)
+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
+Group 9: (Blocks 73729-81920) [Inode not init]
+ Backup superblock at 73729, Group descriptors at 73730-73730
+ Reserved GDT blocks at 73731-73986
+ Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
+ Inode table at 73989-74244 (+260)
+ 7676 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks: 74245-81920
+ Free inodes:
+Group 10: (Blocks 81921-90112) [Inode not init, Block not init]
+ Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
+ Inode table at 81923-82178 (+2)
+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
+Group 11: (Blocks 90113-98304) [Inode not init, Block not init]
+ Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
+ Inode table at 90115-90370 (+2)
+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
+Group 12: (Blocks 98305-106496) [Inode not init, Block not init]
+ Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
+ Inode table at 98307-98562 (+2)
+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
+Group 13: (Blocks 106497-114688) [Inode not init, Block not init]
+ Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
+ Inode table at 106499-106754 (+2)
+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
+Group 14: (Blocks 114689-122880) [Inode not init, Block not init]
+ Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
+ Inode table at 114691-114946 (+2)
+ 7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
+Group 15: (Blocks 122881-131071) [Inode not init, Block not init]
+ Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
+ Inode table at 122883-123138 (+2)
+ 7933 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
+ Free blocks:
+ Free inodes:
diff --git a/tests/m_uninit/script b/tests/m_uninit/script
new file mode 100644
index 0000000..0de2699
--- /dev/null
+++ b/tests/m_uninit/script
@@ -0,0 +1,4 @@
+DESCRIPTION="uninitialized group feature"
+FS_SIZE=131072
+MKE2FS_OPTS="-O uninit_groups"
+. $cmd_dir/run_mke2fs
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 02/11] Add uninit block group support to various libext2fs functions

From: Jose R. Santos <[email protected]>

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
lib/ext2fs/Makefile.in | 10 ++++++----
lib/ext2fs/alloc_stats.c | 22 ++++++++++++++++++++++
lib/ext2fs/alloc_tables.c | 4 +---
lib/ext2fs/ext2fs.h | 3 ++-
lib/ext2fs/initialize.c | 1 +
lib/ext2fs/inode.c | 29 +++++++++++++++++++++++------
lib/ext2fs/openfs.c | 16 ++++++++++++++++
lib/ext2fs/rw_bitmaps.c | 12 ++++++++----
8 files changed, 79 insertions(+), 18 deletions(-)

diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index f0f02dc..1de037d 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -195,11 +195,13 @@ ext2fs.pc: $(srcdir)/ext2fs.pc.in $(top_builddir)/config.status
@cd $(top_builddir); CONFIG_FILES=lib/ext2fs/ext2fs.pc ./config.status

tst_badblocks: tst_badblocks.o freefs.o bitmaps.o rw_bitmaps.o \
- read_bb_file.o write_bb_file.o badblocks.o
+ read_bb_file.o write_bb_file.o badblocks.o csum.o crc16.o \
+ closefs.o io_manager.o
@echo " LD $@"
- @$(CC) -o tst_badblocks tst_badblocks.o freefs.o \
- read_bb_file.o write_bb_file.o badblocks.o rw_bitmaps.o \
- inline.o bitops.o gen_bitmap.o bitmaps.o $(LIBCOM_ERR)
+ @$(CC) -o tst_badblocks tst_badblocks.o freefs.o read_bb_file.o \
+ write_bb_file.o badblocks.o rw_bitmaps.o inline.o bitops.o \
+ gen_bitmap.o bitmaps.o csum.o crc16.o closefs.o io_manager.o \
+ $(LIBCOM_ERR)

tst_icount: icount.c initialize.o $(STATIC_LIBEXT2FS)
@echo " LD $@"
diff --git a/lib/ext2fs/alloc_stats.c b/lib/ext2fs/alloc_stats.c
index 4088f7b..725f28d 100644
--- a/lib/ext2fs/alloc_stats.c
+++ b/lib/ext2fs/alloc_stats.c
@@ -27,6 +27,25 @@ void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
fs->group_desc[group].bg_free_inodes_count -= inuse;
if (isdir)
fs->group_desc[group].bg_used_dirs_count += inuse;
+
+ /* We don't strictly need to be clearing these if inuse < 0
+ * (i.e. freeing inodes) but it also means something is bad. */
+ fs->group_desc[group].bg_flags &= ~(EXT2_BG_INODE_UNINIT |
+ EXT2_BG_BLOCK_UNINIT);
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+ ext2_ino_t first_unused_inode = fs->super->s_inodes_per_group -
+ fs->group_desc[group].bg_itable_unused +
+ group * fs->super->s_inodes_per_group + 1;
+
+ if (ino >= first_unused_inode)
+ fs->group_desc[group].bg_itable_unused =
+ group * fs->super->s_inodes_per_group +
+ fs->super->s_inodes_per_group - ino;
+
+ ext2fs_group_desc_csum_set(fs, group);
+ }
+
fs->super->s_free_inodes_count -= inuse;
ext2fs_mark_super_dirty(fs);
ext2fs_mark_ib_dirty(fs);
@@ -46,6 +65,9 @@ void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse)
else
ext2fs_unmark_block_bitmap(fs->block_map, blk);
fs->group_desc[group].bg_free_blocks_count -= inuse;
+ fs->group_desc[group].bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
+ ext2fs_group_desc_csum_set(fs, group);
+
fs->super->s_free_blocks_count -= inuse;
ext2fs_mark_super_dirty(fs);
ext2fs_mark_bb_dirty(fs);
diff --git a/lib/ext2fs/alloc_tables.c b/lib/ext2fs/alloc_tables.c
index 4ad2ba9..9b4f0e5 100644
--- a/lib/ext2fs/alloc_tables.c
+++ b/lib/ext2fs/alloc_tables.c
@@ -95,13 +95,11 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
ext2fs_mark_block_bitmap(bmap, blk);
fs->group_desc[group].bg_inode_table = new_blk;
}
+ ext2fs_group_desc_csum_set(fs, group);

-
return 0;
}

-
-
errcode_t ext2fs_allocate_tables(ext2_filsys fs)
{
errcode_t retval;
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index fbea854..0504a7f 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -516,7 +516,8 @@ typedef struct ext2_icount *ext2_icount_t;
EXT4_FEATURE_INCOMPAT_FLEX_BG)
#endif
#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM)

/*
* These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index 2edcd17..c2e00e8 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -377,6 +377,7 @@ ipg_retry:
fs->group_desc[i].bg_free_inodes_count =
fs->super->s_inodes_per_group;
fs->group_desc[i].bg_used_dirs_count = 0;
+ ext2fs_group_desc_csum_set(fs, i);
}

c = (char) 255;
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index 818abc9..b4a445d 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -167,6 +167,9 @@ errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
if (EXT2_HAS_COMPAT_FEATURE(fs->super,
EXT2_FEATURE_COMPAT_LAZY_BG))
scan->scan_flags |= EXT2_SF_DO_LAZY;
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
+ scan->scan_flags |= EXT2_SF_DO_LAZY;
*ret_scan = scan;
return 0;
}
@@ -218,18 +221,30 @@ int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
*/
static errcode_t get_next_blockgroup(ext2_inode_scan scan)
{
+ ext2_filsys fs = scan->fs;
+
scan->current_group++;
scan->groups_left--;
-
- scan->current_block = scan->fs->
- group_desc[scan->current_group].bg_inode_table;
+
+ scan->current_block =fs->group_desc[scan->current_group].bg_inode_table;

scan->current_inode = scan->current_group *
- EXT2_INODES_PER_GROUP(scan->fs->super);
+ EXT2_INODES_PER_GROUP(fs->super);

scan->bytes_left = 0;
- scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
- scan->blocks_left = scan->fs->inode_blocks_per_group;
+ scan->inodes_left = EXT2_INODES_PER_GROUP(fs->super);
+ scan->blocks_left = fs->inode_blocks_per_group;
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+ scan->inodes_left -=
+ fs->group_desc[scan->current_group].bg_itable_unused;
+ scan->blocks_left =
+ (EXT2_INODES_PER_GROUP(fs->super) -
+ fs->group_desc[scan->current_group].bg_itable_unused +
+ fs->blocksize / scan->inode_size - 1) *
+ scan->inode_size / fs->blocksize;
+ }
+
return 0;
}

@@ -417,6 +432,8 @@ errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, ext2_ino_t *ino,
(scan->fs->group_desc[scan->current_group].bg_flags &
EXT2_BG_INODE_UNINIT))
goto force_new_group;
+ if (scan->inodes_left == 0)
+ goto force_new_group;
if (scan->current_block == 0) {
if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {
goto force_new_group;
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index a6a8217..996fbb4 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -303,6 +303,22 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,

fs->stride = fs->super->s_raid_stride;

+ /*
+ * If recovery is from backup superblock, Clear _UNININT flags &
+ * reset bg_itable_unused to zero
+ */
+ if (superblock > 1 && EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+ struct ext2_group_desc *gd;
+ for (i = 0, gd = fs->group_desc; i < fs->group_desc_count;
+ i++, gd++) {
+ gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
+ gd->bg_flags &= ~EXT2_BG_INODE_UNINIT;
+ gd->bg_itable_unused = 0;
+ }
+ ext2fs_mark_super_dirty(fs);
+ }
+
fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
*ret_fs = fs;
return 0;
diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c
index 1897ec3..dd5dc46 100644
--- a/lib/ext2fs/rw_bitmaps.c
+++ b/lib/ext2fs/rw_bitmaps.c
@@ -152,8 +152,10 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)

fs->write_bitmaps = ext2fs_write_bitmaps;

- if (EXT2_HAS_COMPAT_FEATURE(fs->super,
- EXT2_FEATURE_COMPAT_LAZY_BG))
+ if (EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_LAZY_BG) ||
+ EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
lazy_flag = 1;

retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf);
@@ -233,7 +235,8 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
if (block_bitmap) {
blk = fs->group_desc[i].bg_block_bitmap;
if (lazy_flag && fs->group_desc[i].bg_flags &
- EXT2_BG_BLOCK_UNINIT)
+ EXT2_BG_BLOCK_UNINIT &&
+ ext2fs_group_desc_csum_verify(fs, i))
blk = 0;
if (blk) {
retval = io_channel_read_blk(fs->io, blk,
@@ -254,7 +257,8 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
if (inode_bitmap) {
blk = fs->group_desc[i].bg_inode_bitmap;
if (lazy_flag && fs->group_desc[i].bg_flags &
- EXT2_BG_INODE_UNINIT)
+ EXT2_BG_INODE_UNINIT &&
+ ext2fs_group_desc_csum_verify(fs, i))
blk = 0;
if (blk) {
retval = io_channel_read_blk(fs->io, blk,
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 09/11] Make e2fsck uninit block group aware

From: Jose R. Santos <[email protected]>

This patch has all the necesary pieces to open and fix filesystems created
with the uninit block group feature.

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
e2fsck/e2fsck.h | 2 +
e2fsck/journal.c | 1 +
e2fsck/pass2.c | 77 ++++++++++++++++++++++++++++++++++++++-----
e2fsck/pass5.c | 61 +++++++++++++++++++++++++----------
e2fsck/problem.c | 42 +++++++++++++++++++++++-
e2fsck/problem.h | 26 ++++++++++++++-
e2fsck/super.c | 38 +++++++++++++++++++++
e2fsck/unix.c | 11 +++++-
e2fsck/util.c | 61 ++++++++++++++++++++++++++++++++++
tests/f_dupfsblks/expect.1 | 3 +-
tests/m_raid_opt/expect.1 | 33 ++++++++++++------
11 files changed, 313 insertions(+), 42 deletions(-)

diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 21208e0..bd173af 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -471,6 +471,8 @@ extern void e2fsck_read_bitmaps(e2fsck_t ctx);
extern void e2fsck_write_bitmaps(e2fsck_t ctx);
extern void preenhalt(e2fsck_t ctx);
extern char *string_copy(e2fsck_t ctx, const char *str, int len);
+extern errcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
+ blk_t *ret_blk, int *ret_count);
#ifdef RESOURCE_TRACK
extern void print_resource_track(const char *desc,
struct resource_track *track,
diff --git a/e2fsck/journal.c b/e2fsck/journal.c
index f5f4647..ec0af4b 100644
--- a/e2fsck/journal.c
+++ b/e2fsck/journal.c
@@ -988,6 +988,7 @@ void e2fsck_move_ext3_journal(e2fsck_t ctx)
ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
ext2fs_mark_ib_dirty(fs);
fs->group_desc[group].bg_free_inodes_count++;
+ ext2fs_group_desc_csum_set(fs, group);
fs->super->s_free_inodes_count++;
return;

diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 56f352b..906662d 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -151,7 +151,7 @@ void e2fsck_pass2(e2fsck_t ctx)

cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
&cd);
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
+ if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART)
return;
if (cd.pctx.errcode) {
fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
@@ -727,7 +727,7 @@ static int check_dir_block(ext2_filsys fs,
buf = cd->buf;
ctx = cd->ctx;

- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
+ if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART)
return DIRENT_ABORT;

if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
@@ -831,6 +831,9 @@ out_htree:
dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
prev = 0;
do {
+ int group;
+ ext2_ino_t first_unused_inode;
+
problem = 0;
dirent = (struct ext2_dir_entry *) (buf + offset);
cd->pctx.dirent = dirent;
@@ -880,12 +883,6 @@ out_htree:
(dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
(dirent->inode > fs->super->s_inodes_count)) {
problem = PR_2_BAD_INO;
- } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
- dirent->inode))) {
- /*
- * If the inode is unused, offer to clear it.
- */
- problem = PR_2_UNUSED_INODE;
} else if (ctx->inode_bb_map &&
(ext2fs_test_inode_bitmap(ctx->inode_bb_map,
dirent->inode))) {
@@ -962,6 +959,67 @@ out_htree:
return DIRENT_ABORT;
}

+ group = ext2fs_group_of_ino(fs, dirent->inode);
+ first_unused_inode = group * fs->super->s_inodes_per_group +
+ 1 + fs->super->s_inodes_per_group -
+ fs->group_desc[group].bg_itable_unused;
+ cd->pctx.group = group;
+
+ /*
+ * Check if the inode was missed out because _INODE_UNINIT
+ * flag was set or bg_itable_unused was incorrect.
+ * If that is the case restart e2fsck.
+ * XXX Optimisations TODO:
+ * 1. only restart e2fsck once
+ * 2. only exposed inodes are checked again.
+ */
+ if (fs->group_desc[group].bg_flags & EXT2_BG_INODE_UNINIT) {
+ if (fix_problem(ctx, PR_2_INOREF_BG_INO_UNINIT,
+ &cd->pctx)){
+ fs->group_desc[group].bg_flags &=
+ ~EXT2_BG_INODE_UNINIT;
+ ctx->flags |= E2F_FLAG_RESTART |
+ E2F_FLAG_SIGNAL_MASK;
+ } else {
+ ext2fs_unmark_valid(fs);
+ if (problem == PR_2_BAD_INO)
+ goto next;
+ }
+ } else if (dirent->inode >= first_unused_inode) {
+ if (fix_problem(ctx, PR_2_INOREF_IN_UNUSED, &cd->pctx)){
+ fs->group_desc[group].bg_itable_unused = 0;
+ fs->group_desc[group].bg_flags &=
+ ~EXT2_BG_INODE_UNINIT;
+ ext2fs_mark_super_dirty(fs);
+ ctx->flags |= E2F_FLAG_RESTART;
+ goto restart_fsck;
+ } else {
+ ext2fs_unmark_valid(fs);
+ if (problem == PR_2_BAD_INO)
+ goto next;
+ }
+ }
+
+ if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
+ dirent->inode))) {
+ /*
+ * If the inode is unused, offer to clear it.
+ */
+ problem = PR_2_UNUSED_INODE;
+ }
+
+ if (problem) {
+ if (fix_problem(ctx, problem, &cd->pctx)) {
+ dirent->inode = 0;
+ dir_modified++;
+ goto next;
+ } else {
+ ext2fs_unmark_valid(fs);
+ if (problem == PR_2_BAD_INO)
+ goto next;
+ }
+ }
+
if (check_name(ctx, dirent, ino, &cd->pctx))
dir_modified++;

@@ -1071,8 +1129,9 @@ out_htree:
dict_free_nodes(&de_dict);
return 0;
abort_free_dict:
- dict_free_nodes(&de_dict);
ctx->flags |= E2F_FLAG_ABORT;
+restart_fsck:
+ dict_free_nodes(&de_dict);
return DIRENT_ABORT;
}

diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c
index 8e3794d..b70e8d1 100644
--- a/e2fsck/pass5.c
+++ b/e2fsck/pass5.c
@@ -121,7 +121,7 @@ static void check_block_bitmaps(e2fsck_t ctx)
struct problem_context pctx;
int problem, save_problem, fixit, had_problem;
errcode_t retval;
- int lazy_bg = 0;
+ int lazy_flag, csum_flag;
int skip_group = 0;

clear_problem_context(&pctx);
@@ -158,15 +158,16 @@ static void check_block_bitmaps(e2fsck_t ctx)
goto errout;
}

- if (EXT2_HAS_COMPAT_FEATURE(fs->super, EXT2_FEATURE_COMPAT_LAZY_BG))
- lazy_bg++;
-
+ lazy_flag = EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_LAZY_BG);
+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
redo_counts:
had_problem = 0;
save_problem = 0;
pctx.blk = pctx.blk2 = NO_BLK;
- if (lazy_bg && (fs->group_desc[group].bg_flags &
- EXT2_BG_BLOCK_UNINIT))
+ if ((lazy_flag || csum_flag) &&
+ (fs->group_desc[group].bg_flags & EXT2_BG_BLOCK_UNINIT))
skip_group++;
super = fs->super->s_first_data_block;
for (i = fs->super->s_first_data_block;
@@ -206,6 +207,17 @@ redo_counts:
* Block used, but not marked in use in the bitmap.
*/
problem = PR_5_BLOCK_USED;
+
+ if (skip_group) {
+ struct problem_context pctx2;
+ pctx2.blk = i;
+ pctx2.group = group;
+ if (fix_problem(ctx, PR_5_BLOCK_UNINIT,&pctx2)){
+ fs->group_desc[group].bg_flags &=
+ ~EXT2_BG_BLOCK_UNINIT;
+ skip_group = 0;
+ }
+ }
}
if (pctx.blk == NO_BLK) {
pctx.blk = pctx.blk2 = i;
@@ -224,7 +236,7 @@ redo_counts:
had_problem++;

do_counts:
- if (!bitmap && !skip_group) {
+ if (!bitmap && (!skip_group || csum_flag)) {
group_free++;
free_blocks++;
}
@@ -241,7 +253,7 @@ redo_counts:
if ((ctx->progress)(ctx, 5, group,
fs->group_desc_count*2))
goto errout;
- if (lazy_bg &&
+ if ((lazy_flag || csum_flag) &&
(i != fs->super->s_blocks_count-1) &&
(fs->group_desc[group].bg_flags &
EXT2_BG_BLOCK_UNINIT))
@@ -321,7 +333,7 @@ static void check_inode_bitmaps(e2fsck_t ctx)
errcode_t retval;
struct problem_context pctx;
int problem, save_problem, fixit, had_problem;
- int lazy_bg = 0;
+ int lazy_flag, csum_flag;
int skip_group = 0;

clear_problem_context(&pctx);
@@ -358,16 +370,16 @@ static void check_inode_bitmaps(e2fsck_t ctx)
goto errout;
}

- if (EXT2_HAS_COMPAT_FEATURE(fs->super,
- EXT2_FEATURE_COMPAT_LAZY_BG))
- lazy_bg++;
-
+ lazy_flag = EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_LAZY_BG);
+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
redo_counts:
had_problem = 0;
save_problem = 0;
pctx.ino = pctx.ino2 = 0;
- if (lazy_bg && (fs->group_desc[group].bg_flags &
- EXT2_BG_INODE_UNINIT))
+ if ((lazy_flag || csum_flag) &&
+ (fs->group_desc[group].bg_flags & EXT2_BG_INODE_UNINIT))
skip_group++;

/* Protect loop from wrap-around if inodes_count is maxed */
@@ -390,6 +402,21 @@ redo_counts:
* Inode used, but not in bitmap
*/
problem = PR_5_INODE_USED;
+
+ /* We should never hit this, because it means that
+ * inodes were marked in use that weren't noticed
+ * in pass1 or pass 2. It is easier to fix the problem
+ * than to kill e2fsck and leave the user stuck. */
+ if (skip_group) {
+ struct problem_context pctx2;
+ pctx2.blk = i;
+ pctx2.group = group;
+ if (fix_problem(ctx, PR_5_INODE_UNINIT,&pctx2)){
+ fs->group_desc[group].bg_flags &=
+ ~EXT2_BG_INODE_UNINIT;
+ skip_group = 0;
+ }
+ }
}
if (pctx.ino == 0) {
pctx.ino = pctx.ino2 = i;
@@ -411,7 +438,7 @@ do_counts:
if (bitmap) {
if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
dirs_count++;
- } else if (!skip_group) {
+ } else if (!skip_group || csum_flag) {
group_free++;
free_inodes++;
}
@@ -430,7 +457,7 @@ do_counts:
group + fs->group_desc_count,
fs->group_desc_count*2))
goto errout;
- if (lazy_bg &&
+ if ((lazy_flag || csum_flag) &&
(i != fs->super->s_inodes_count) &&
(fs->group_desc[group].bg_flags &
EXT2_BG_INODE_UNINIT))
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index d3e2fd7..b6a3a81 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -351,8 +351,28 @@ static struct e2fsck_problem problem_table[] = {
N_("Adding dirhash hint to @f.\n\n"),
PROMPT_NONE, 0 },

+ /* group descriptor N checksum is invalid. */
+ { PR_0_GDT_CSUM,
+ N_("@g descriptor %g checksum is invalid. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
+ /* group descriptor N marked uninitialized without feature set. */
+ { PR_0_GDT_UNINIT,
+ N_("@g descriptor %g marked uninitialized without feature set.\n"),
+ PROMPT_FIX, PR_PREEN_OK },
+
+ /* group N block bitmap uninitialized but inode bitmap in use. */
+ { PR_0_BB_UNINIT_IB_INIT,
+ N_("@g %g @b @B uninitialized but @i @B in use.\n"),
+ PROMPT_FIX, PR_PREEN_OK },
+
+ /* Group descriptor N has invalid unused inodes count. */
+ { PR_0_GDT_ITABLE_UNUSED,
+ N_("@g descriptor %g has invalid unused inodes count %b. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
/* Pass 1 errors */
-
+
/* Pass 1: Checking inodes, blocks, and sizes */
{ PR_1_PASS_HEADER,
N_("Pass 1: Checking @is, @bs, and sizes\n"),
@@ -1232,6 +1252,16 @@ static struct e2fsck_problem problem_table[] = {
{ PR_2_UNEXPECTED_HTREE_BLOCK,
N_("Unexpected @b in @h %d (%q).\n"), PROMPT_CLEAR_HTREE, 0 },

+ /* Inode found in group where _INODE_UNINIT is set */
+ { PR_2_INOREF_BG_INO_UNINIT,
+ N_("@i %i found in @g %g where _INODE_UNINIT is set. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
+ /* Inode found in group unused inodes area */
+ { PR_2_INOREF_IN_UNUSED,
+ N_("@i %i found in @g %g unused inodes area. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
/* Pass 3 errors */

/* Pass 3: Checking directory connectivity */
@@ -1543,6 +1573,16 @@ static struct e2fsck_problem problem_table[] = {
N_("Recreate journal to make the filesystem ext3 again?\n"),
PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },

+ /* Group N block(s) in use but group is marked BLOCK_UNINIT */
+ { PR_5_BLOCK_UNINIT,
+ N_("@g %g @b(s) in use but @g is marked BLOCK_UNINIT\n"),
+ PROMPT_FIX, PR_PREEN_OK },
+
+ /* Group N inode(s) in use but group is marked INODE_UNINIT */
+ { PR_5_INODE_UNINIT,
+ N_("@g %g @i(s) in use but @g is marked INODE_UNINIT\n"),
+ PROMPT_FIX, PR_PREEN_OK },
+
{ 0 }
};

diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 48a4a2b..a2bd2b5 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -196,6 +196,18 @@ struct problem_context {
/* Superblock hint for external journal incorrect */
#define PR_0_DIRHASH_HINT 0x000034

+/* Group descriptor N checksum is invalid */
+#define PR_0_GDT_CSUM 0x000035
+
+/* Group descriptor N marked uninitialized without feature set. */
+#define PR_0_GDT_UNINIT 0x000036
+
+/* Block bitmap is not initialised and Inode bitmap is */
+#define PR_0_BB_UNINIT_IB_INIT 0x000037
+
+/* Group descriptor N has invalid unused inodes count. */
+#define PR_0_GDT_ITABLE_UNUSED 0x000038
+
/*
* Pass 1 errors
*/
@@ -735,6 +747,12 @@ struct problem_context {
/* Unexpected HTREE block */
#define PR_2_UNEXPECTED_HTREE_BLOCK 0x020045

+/* Inode found in group where _INODE_UNINIT is set */
+#define PR_2_INOREF_BG_INO_UNINIT 0x020046
+
+/* Inode found in group unused inodes area */
+#define PR_2_INOREF_IN_UNUSED 0x020047
+
/*
* Pass 3 errors
*/
@@ -923,10 +941,16 @@ struct problem_context {

/* Inode range not used, but marked in bitmap */
#define PR_5_INODE_RANGE_UNUSED 0x050016
-
+
/* Inode rangeused, but not marked used in bitmap */
#define PR_5_INODE_RANGE_USED 0x050017

+/* Block in use but group is marked BLOCK_UNINIT */
+#define PR_5_BLOCK_UNINIT 0x050018
+
+/* Inode in use but group is marked INODE_UNINIT */
+#define PR_5_INODE_UNINIT 0x050019
+
/*
* Post-Pass 5 errors
*/
diff --git a/e2fsck/super.c b/e2fsck/super.c
index b93ec95..56c3931 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -469,6 +469,7 @@ void check_super_block(e2fsck_t ctx)
struct problem_context pctx;
blk_t free_blocks = 0;
ino_t free_inodes = 0;
+ int lazy_flag, csum_flag;

inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
ipg_max = inodes_per_block * (blocks_per_group - 4);
@@ -578,6 +579,10 @@ void check_super_block(e2fsck_t ctx)
first_block = sb->s_first_data_block;
last_block = sb->s_blocks_count-1;

+ lazy_flag = EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_LAZY_BG);
+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
pctx.group = i;

@@ -626,6 +631,39 @@ void check_super_block(e2fsck_t ctx)
(gd->bg_used_dirs_count > sb->s_inodes_per_group))
ext2fs_unmark_valid(fs);

+ if (!ext2fs_group_desc_csum_verify(fs, i)) {
+ if (fix_problem(ctx, PR_0_GDT_CSUM, &pctx)) {
+ gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT |
+ EXT2_BG_INODE_UNINIT);
+ gd->bg_itable_unused = 0;
+ }
+ ext2fs_unmark_valid(fs);
+ }
+
+ if (!lazy_flag && !csum_flag &&
+ (gd->bg_flags &(EXT2_BG_BLOCK_UNINIT|EXT2_BG_INODE_UNINIT)||
+ gd->bg_itable_unused != 0)){
+ if (fix_problem(ctx, PR_0_GDT_UNINIT, &pctx)) {
+ gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT |
+ EXT2_BG_INODE_UNINIT);
+ gd->bg_itable_unused = 0;
+ }
+ ext2fs_unmark_valid(fs);
+ }
+ if (gd->bg_flags & EXT2_BG_BLOCK_UNINIT &&
+ !(gd->bg_flags & EXT2_BG_INODE_UNINIT)) {
+ if (fix_problem(ctx, PR_0_BB_UNINIT_IB_INIT, &pctx))
+ gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
+ ext2fs_unmark_valid(fs);
+ }
+ if (csum_flag &&
+ (gd->bg_itable_unused > gd->bg_free_inodes_count ||
+ gd->bg_itable_unused > sb->s_inodes_per_group)) {
+ pctx.blk = gd->bg_itable_unused;
+ if (fix_problem(ctx, PR_0_GDT_ITABLE_UNUSED, &pctx))
+ gd->bg_itable_unused = 0;
+ ext2fs_unmark_valid(fs);
+ }
}

/*
diff --git a/e2fsck/unix.c b/e2fsck/unix.c
index 3a5cf47..7b662e4 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -558,7 +558,9 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts)
"and may take an argument which\n"
"is set off by an equals ('=') sign. "
"Valid extended options are:\n"
- "\tea_ver=<ea_version (1 or 2)>\n\n"), stderr);
+ "\tea_ver=<ea_version (1 or 2)>\n"
+ "\tuninit_groups\n"
+ "\tinit_groups\n\n"), stderr);
exit(1);
}
}
@@ -745,6 +747,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
!cflag && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
ctx->options |= E2F_OPT_READONLY;
+
ctx->io_options = strchr(argv[optind], '?');
if (ctx->io_options)
*ctx->io_options++ = 0;
@@ -843,7 +846,7 @@ sscanf_err:

static const char *my_ver_string = E2FSPROGS_VERSION;
static const char *my_ver_date = E2FSPROGS_DATE;
-
+
int main (int argc, char *argv[])
{
errcode_t retval = 0, orig_retval = 0;
@@ -1336,6 +1339,10 @@ no_journal:
}
}

+ if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM &&
+ !(ctx->options & E2F_OPT_READONLY))
+ ext2fs_set_gdt_csum(ctx->fs);
+
e2fsck_write_bitmaps(ctx);
#ifdef RESOURCE_TRACK
io_channel_flush(ctx->fs->io);
diff --git a/e2fsck/util.c b/e2fsck/util.c
index 27301f0..315a575 100644
--- a/e2fsck/util.c
+++ b/e2fsck/util.c
@@ -29,6 +29,10 @@
#include <malloc.h>
#endif

+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
#include "e2fsck.h"

extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
@@ -546,3 +550,60 @@ int ext2_file_type(unsigned int mode)

return 0;
}
+
+#define STRIDE_LENGTH 8
+/*
+ * Helper function which zeros out _num_ blocks starting at _blk_. In
+ * case of an error, the details of the error is returned via _ret_blk_
+ * and _ret_count_ if they are non-NULL pointers. Returns 0 on
+ * success, and an error code on an error.
+ *
+ * As a special case, if the first argument is NULL, then it will
+ * attempt to free the static zeroizing buffer. (This is to keep
+ * programs that check for memory leaks happy.)
+ */
+errcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
+ blk_t *ret_blk, int *ret_count)
+{
+ int j, count, next_update, next_update_incr;
+ static char *buf;
+ errcode_t retval;
+
+ /* If fs is null, clean up the static buffer and return */
+ if (!fs) {
+ if (buf) {
+ free(buf);
+ buf = 0;
+ }
+ return 0;
+ }
+ /* Allocate the zeroizing buffer if necessary */
+ if (!buf) {
+ buf = malloc(fs->blocksize * STRIDE_LENGTH);
+ if (!buf) {
+ com_err("malloc", ENOMEM,
+ _("while allocating zeroizing buffer"));
+ exit(1);
+ }
+ memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
+ }
+ /* OK, do the write loop */
+ next_update = 0;
+ next_update_incr = num / 100;
+ if (next_update_incr < 1)
+ next_update_incr = 1;
+ for (j = 0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {
+ count = num - j;
+ if (count > STRIDE_LENGTH)
+ count = STRIDE_LENGTH;
+ retval = io_channel_write_blk(fs->io, blk, count, buf);
+ if (retval) {
+ if (ret_count)
+ *ret_count = count;
+ if (ret_blk)
+ *ret_blk = blk;
+ return retval;
+ }
+ }
+ return 0;
+}
diff --git a/tests/f_dupfsblks/expect.1 b/tests/f_dupfsblks/expect.1
index 661e164..32ce89b 100644
--- a/tests/f_dupfsblks/expect.1
+++ b/tests/f_dupfsblks/expect.1
@@ -44,7 +44,8 @@ Salvage? yes
Directory inode 12, block 3, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (12) has deleted/unused inode 32. Clear? yes
+Entry '' in ??? (12) has a zero-length name.
+Clear? yes

Directory inode 12, block 4, offset 100: directory corrupted
Salvage? yes
diff --git a/tests/m_raid_opt/expect.1 b/tests/m_raid_opt/expect.1
index 9bd7894..25b283a 100644
--- a/tests/m_raid_opt/expect.1
+++ b/tests/m_raid_opt/expect.1
@@ -46,57 +46,68 @@ Setting filetype for entry '..' in ??? (11) to 2.
Directory inode 11, block 1, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1063. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 2, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1064. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 3, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1065. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 4, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1066. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 5, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1067. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 6, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1068. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 7, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1069. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 8, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1070. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 9, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1071. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 10, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1072. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Directory inode 11, block 11, offset 0: directory corrupted
Salvage? yes

-Entry '' in ??? (11) has deleted/unused inode 1073. Clear? yes
+Entry '' in ??? (11) has a zero-length name.
+Clear? yes

Pass 3: Checking directory connectivity
'..' in / (2) is <The NULL inode> (0), should be / (2).
--
1.5.4.1.144.gdfee-dirty


2008-03-17 13:29:05

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, REWORKED 01/11] Add initial checksum support for the gdt_checksum/uninit_group feature

From: Jose R. Santos <[email protected]>

- Add support for computing CRC-16 value.
- Add call to check/verify/set csum on block_groups.
- Add a test program to verify csum operations.

Signed-off-by: Jose R. Santos <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
lib/ext2fs/Makefile.in | 21 ++++++-
lib/ext2fs/crc16.c | 61 ++++++++++++++++++
lib/ext2fs/crc16.h | 45 +++++++++++++
lib/ext2fs/csum.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++
lib/ext2fs/ext2_fs.h | 1 +
lib/ext2fs/ext2fs.h | 5 ++
lib/ext2fs/tst_csum.c | 130 ++++++++++++++++++++++++++++++++++++++
7 files changed, 423 insertions(+), 2 deletions(-)
create mode 100644 lib/ext2fs/crc16.c
create mode 100644 lib/ext2fs/crc16.h
create mode 100644 lib/ext2fs/csum.c
create mode 100644 lib/ext2fs/tst_csum.c

diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 53b738d..f0f02dc 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -30,6 +30,8 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
bmap.o \
check_desc.o \
closefs.o \
+ crc16.o \
+ csum.o \
dblist.o \
dblist_dir.o \
dirblock.o \
@@ -85,6 +87,8 @@ SRCS= ext2_err.c \
$(srcdir)/bmap.c \
$(srcdir)/check_desc.c \
$(srcdir)/closefs.c \
+ $(srcdir)/crc16.c \
+ $(srcdir)/csum.c \
$(srcdir)/dblist.c \
$(srcdir)/dblist_dir.c \
$(srcdir)/dirblock.c \
@@ -130,6 +134,7 @@ SRCS= ext2_err.c \
$(srcdir)/tst_badblocks.c \
$(srcdir)/tst_bitops.c \
$(srcdir)/tst_byteswap.c \
+ $(srcdir)/tst_csum.c \
$(srcdir)/tst_getsize.c \
$(srcdir)/tst_iscan.c \
$(srcdir)/unix_io.c \
@@ -305,17 +310,23 @@ tst_extents: $(srcdir)/extent.c extent_dbg.c $(DEBUG_OBJS) $(LIBSS) $(LIBE2P) $(
$(LIBUUID) $(STATIC_LIBEXT2FS) $(LIBBLKID) $(LIBCOM_ERR) \
-I $(top_srcdir)/debugfs

+tst_csum: tst_csum.c csum.c $(STATIC_LIBEXT2FS)
+ @echo " LD $@"
+ @$(CC) -o tst_csum $(srcdir)/csum.c $(srcdir)/tst_csum.c -DDEBUG \
+ $(ALL_CFLAGS) $(STATIC_LIBEXT2FS) $(LIBCOM_ERR)
+
mkjournal: mkjournal.c $(STATIC_LIBEXT2FS)
@echo " LD $@"
@$(CC) -o mkjournal $(srcdir)/mkjournal.c -DDEBUG $(STATIC_LIBEXT2FS) $(LIBCOM_ERR) $(ALL_CFLAGS)

-check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount tst_super_size
+check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount tst_super_size tst_types tst_csum
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_bitops
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_badblocks
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_iscan
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_types
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_icount
LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_super_size
+ LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_csum

installdirs::
@echo " MKINSTALLDIRS $(libdir) $(includedir)/ext2fs"
@@ -347,7 +358,7 @@ clean::
$(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* checker/* \
tst_badblocks tst_iscan ext2_err.et ext2_err.c ext2_err.h \
tst_byteswap tst_ismounted tst_getsize tst_sectgetsize \
- tst_bitops tst_types tst_icount tst_super_size \
+ tst_bitops tst_types tst_icount tst_super_size tst_csum \
ext2_tdbtool mkjournal debug_cmds.c \
../libext2fs.a ../libext2fs_p.a ../libext2fs_chk.a

@@ -423,6 +434,10 @@ closefs.o: $(srcdir)/closefs.c $(srcdir)/ext2_fs.h \
$(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
$(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+crc16.o: $(srcdir)/crc16.c $(srcdir)/ext2_fs.h $(srcdir)/crc16.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h
+csum.o: $(srcdir)/csum.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h
dblist.o: $(srcdir)/dblist.c $(srcdir)/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
$(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
@@ -637,3 +652,5 @@ tst_iscan.o: $(srcdir)/tst_iscan.c $(srcdir)/ext2_fs.h \
$(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
$(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+tst_csum.o: $(srcdir)/tst_csum.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h
diff --git a/lib/ext2fs/crc16.c b/lib/ext2fs/crc16.c
new file mode 100644
index 0000000..1b2b8a1
--- /dev/null
+++ b/lib/ext2fs/crc16.c
@@ -0,0 +1,61 @@
+/*
+ * crc16.c
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include "crc16.h"
+
+/** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */
+__u16 const crc16_table[256] = {
+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+
+/**
+ * Compute the CRC-16 for the data buffer
+ *
+ * @param crc previous CRC value
+ * @param buffer data pointer
+ * @param len number of bytes in the buffer
+ * @return the updated CRC value
+ */
+crc16_t crc16(crc16_t crc, const void *buffer, unsigned int len)
+{
+ const unsigned char *cp = buffer;
+
+ while (len--)
+ crc = crc16_byte(crc, *cp++);
+ return crc;
+}
diff --git a/lib/ext2fs/crc16.h b/lib/ext2fs/crc16.h
new file mode 100644
index 0000000..ab3f094
--- /dev/null
+++ b/lib/ext2fs/crc16.h
@@ -0,0 +1,45 @@
+/*
+ * crc16.h - CRC-16 routine
+ *
+ * Implements the standard CRC-16:
+ * Width 16
+ * Poly 0x8005 (x16 + x15 + x2 + 1)
+ * Init 0
+ *
+ * Copyright (c) 2005 Ben Gardner <[email protected]>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#ifndef __CRC16_H
+#define __CRC16_H
+
+#include <ext2fs/ext2_types.h>
+
+extern __u16 const crc16_table[256];
+
+#ifdef WORDS_BIGENDIAN
+/* for an unknown reason, PPC treats __u16 as signed and keeps doing sign
+ * extension on the value. Instead, use only the low 16 bits of an
+ * unsigned int for holding the CRC value to avoid this.
+ */
+typedef unsigned crc16_t;
+
+static inline crc16_t crc16_byte(crc16_t crc, const unsigned char data)
+{
+ return (((crc >> 8) & 0xffU) ^ crc16_table[(crc ^ data) & 0xffU]) &
+ 0x0000ffffU;
+}
+#else
+typedef __u16 crc16_t;
+
+static inline crc16_t crc16_byte(crc16_t crc, const unsigned char data)
+{
+ return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
+}
+#endif
+
+extern crc16_t crc16(crc16_t crc, const void *buffer, unsigned int len);
+
+#endif /* __CRC16_H */
diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
new file mode 100644
index 0000000..c35d924
--- /dev/null
+++ b/lib/ext2fs/csum.c
@@ -0,0 +1,162 @@
+/*
+ * csum.c --- checksumming of ext3 structures
+ *
+ * Copyright (C) 2006 Cluster File Systems, Inc.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+#include "crc16.h"
+#include <assert.h>
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#ifdef DEBUG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+STATIC __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group)
+{
+ __u16 crc = 0;
+ struct ext2_group_desc *desc;
+
+ desc = &fs->group_desc[group];
+
+ if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
+ int offset = offsetof(struct ext2_group_desc, bg_checksum);
+
+#ifdef WORDS_BIGENDIAN
+ struct ext2_group_desc swabdesc = *desc;
+
+ /* Have to swab back to little-endian to do the checksum */
+ ext2fs_swap_group_desc(&swabdesc);
+ desc = &swabdesc;
+
+ group = ext2fs_swab32(group);
+#endif
+ crc = crc16(~0, fs->super->s_uuid, sizeof(fs->super->s_uuid));
+ crc = crc16(crc, &group, sizeof(group));
+ crc = crc16(crc, desc, offset);
+ offset += sizeof(desc->bg_checksum); /* skip checksum */
+ assert(offset == sizeof(*desc));
+ /* for checksum of struct ext4_group_desc do the rest...*/
+ if (offset < fs->super->s_desc_size) {
+ crc = crc16(crc, (char *)desc + offset,
+ fs->super->s_desc_size - offset);
+ }
+ }
+
+ return crc;
+}
+
+int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group)
+{
+ if (fs->group_desc[group].bg_checksum !=
+ ext2fs_group_desc_csum(fs, group))
+ return 0;
+
+ return 1;
+}
+
+void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group)
+{
+ fs->group_desc[group].bg_checksum = ext2fs_group_desc_csum(fs, group);
+}
+
+static __u32 find_last_inode_ingrp(ext2fs_inode_bitmap bitmap,
+ __u32 inodes_per_grp, dgrp_t grp_no)
+{
+ ext2_ino_t i, start_ino, end_ino;
+
+ start_ino = grp_no * inodes_per_grp + 1;
+ end_ino = start_ino + inodes_per_grp - 1;
+
+ for (i = end_ino; i >= start_ino; i--) {
+ if (ext2fs_fast_test_inode_bitmap(bitmap, i))
+ return i - start_ino + 1;
+ }
+ return inodes_per_grp;
+}
+
+/* update the bitmap flags, set the itable high watermark, and calculate
+ * checksums for the group descriptors */
+void ext2fs_set_gdt_csum(ext2_filsys fs)
+{
+ struct ext2_super_block *sb = fs->super;
+ struct ext2_group_desc *bg = fs->group_desc;
+ int blks, csum_flag, dirty = 0;
+ dgrp_t i;
+
+ csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
+ if (!EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_LAZY_BG) && !csum_flag)
+ return;
+
+ for (i = 0; i < fs->group_desc_count; i++, bg++) {
+ int old_csum = bg->bg_checksum;
+
+ /* Even if it wasn't zeroed, by the time this function is
+ * called by e2fsck we have already scanned and corrected
+ * the whole inode table so we may as well not overwrite it.
+ * This is just a hint to the kernel that it could do lazy
+ * zeroing of the inode table if mke2fs didn't do it, to help
+ * out if we need to do a full itable scan sometime later. */
+ if (!(bg->bg_flags & (EXT2_BG_INODE_UNINIT |
+ EXT2_BG_INODE_ZEROED))) {
+ fs->group_desc[i].bg_flags |= EXT2_BG_INODE_ZEROED;
+ dirty = 1;
+ }
+
+ if (bg->bg_free_inodes_count == sb->s_inodes_per_group &&
+ i > 0 && (i < fs->group_desc_count - 1 || csum_flag)) {
+ if (!(bg->bg_flags & EXT2_BG_INODE_UNINIT)) {
+ bg->bg_flags |= EXT2_BG_INODE_UNINIT;
+ dirty = 1;
+ }
+ if (csum_flag) {
+ int old_unused = bg->bg_itable_unused;
+ bg->bg_itable_unused = sb->s_inodes_per_group;
+ if (old_unused != bg->bg_itable_unused)
+ dirty = 1;
+ }
+ } else if (csum_flag) {
+ int old_unused = bg->bg_itable_unused;
+ bg->bg_flags &= ~EXT2_BG_INODE_UNINIT;
+ bg->bg_itable_unused = sb->s_inodes_per_group -
+ find_last_inode_ingrp(fs->inode_map,
+ sb->s_inodes_per_group,i);
+ if (old_unused != bg->bg_itable_unused)
+ dirty = 1;
+ }
+
+ /* skip first and last groups, or groups with GDT backups
+ * because the resize inode has blocks allocated in them. */
+ if (i == 0 || (i == fs->group_desc_count - 1 && !csum_flag) ||
+ (ext2fs_bg_has_super(fs, i) && sb->s_reserved_gdt_blocks))
+ goto checksum;
+
+ blks = ext2fs_super_and_bgd_loc(fs, i, 0, 0, 0, 0);
+ if (bg->bg_free_blocks_count == blks &&
+ bg->bg_flags & EXT2_BG_INODE_UNINIT &&
+ !(bg->bg_flags & EXT2_BG_BLOCK_UNINIT)) {
+ bg->bg_flags |= EXT2_BG_BLOCK_UNINIT;
+ dirty = 1;
+ }
+checksum:
+ ext2fs_group_desc_csum_set(fs, i);
+ if (old_csum != bg->bg_checksum)
+ dirty = 1;
+ }
+ if (dirty)
+ ext2fs_mark_super_dirty(fs);
+}
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 6016b68..1188557 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -173,6 +173,7 @@ struct ext4_group_desc

#define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not initialized */
#define EXT2_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not initialized */
+#define EXT2_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */

/*
* Data structures used by the directory indexing feature
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 15f4352..fbea854 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -706,6 +706,11 @@ extern int ext2fs_super_and_bgd_loc(ext2_filsys fs,
int *ret_meta_bg);
extern void ext2fs_update_dynamic_rev(ext2_filsys fs);

+/* csum.c */
+extern void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group);
+extern int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_set_gdt_csum(ext2_filsys fs);
+
/* dblist.c */

extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
diff --git a/lib/ext2fs/tst_csum.c b/lib/ext2fs/tst_csum.c
new file mode 100644
index 0000000..e3fa9be
--- /dev/null
+++ b/lib/ext2fs/tst_csum.c
@@ -0,0 +1,130 @@
+/*
+ * This testing program verifies checksumming operations
+ *
+ * Copyright (C) 2006, 2007 by Andreas Dilger <[email protected]>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "ext2fs/ext2_fs.h"
+#include "ext2fs/ext2fs.h"
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+void print_csum(const char *msg, ext2_filsys fs, dgrp_t group)
+{
+ __u16 crc1, crc2, crc3;
+ dgrp_t swabgroup;
+ struct ext2_group_desc *desc = &fs->group_desc[group];
+ struct ext2_super_block *sb = fs->super;
+
+#ifdef WORDS_BIGENDIAN
+ struct ext2_group_desc swabdesc = fs->group_desc[group];
+
+ /* Have to swab back to little-endian to do the checksum */
+ ext2fs_swap_group_desc(&swabdesc);
+ desc = &swabdesc;
+
+ swabgroup = ext2fs_swab32(group);
+#else
+ swabgroup = group;
+#endif
+
+ crc1 = crc16(~0, sb->s_uuid, sizeof(fs->super->s_uuid));
+ crc2 = crc16(crc1, &swabgroup, sizeof(swabgroup));
+ crc3 = crc16(crc2, desc, offsetof(struct ext2_group_desc, bg_checksum));
+ printf("%s: UUID %016Lx%016Lx(%04x), grp %u(%04x): %04x=%04x\n",
+ msg, *(long long *)&sb->s_uuid, *(long long *)&sb->s_uuid[8],
+ crc1, group, crc2, crc3, ext2fs_group_desc_csum(fs, group));
+}
+
+unsigned char sb_uuid[16] = { 0x4f, 0x25, 0xe8, 0xcf, 0xe7, 0x97, 0x48, 0x23,
+ 0xbe, 0xfa, 0xa7, 0x88, 0x4b, 0xae, 0xec, 0xdb };
+
+main(int argc, char **argv)
+{
+ struct ext2_super_block param;
+ errcode_t retval;
+ ext2_filsys fs;
+ int i;
+ __u16 csum1, csum2, csum_known = 0xd3a4;
+
+ memset(&param, 0, sizeof(param));
+ param.s_blocks_count = 32768;
+
+ retval = ext2fs_initialize("test fs", 0, &param,
+ test_io_manager, &fs);
+ if (retval) {
+ com_err("setup", retval,
+ "While initializing filesystem");
+ exit(1);
+ }
+ memcpy(fs->super->s_uuid, sb_uuid, 16);
+ fs->super->s_feature_ro_compat = EXT4_FEATURE_RO_COMPAT_GDT_CSUM;
+
+ for (i=0; i < fs->group_desc_count; i++) {
+ fs->group_desc[i].bg_block_bitmap = 124;
+ fs->group_desc[i].bg_inode_bitmap = 125;
+ fs->group_desc[i].bg_inode_table = 126;
+ fs->group_desc[i].bg_free_blocks_count = 31119;
+ fs->group_desc[i].bg_free_inodes_count = 15701;
+ fs->group_desc[i].bg_used_dirs_count = 2;
+ fs->group_desc[i].bg_flags = 0;
+ };
+
+ csum1 = ext2fs_group_desc_csum(fs, 0);
+ print_csum("csum0000", fs, 0);
+
+#ifdef WORDS_BIGENDIAN
+ csum_known = ext2fs_swab16(known);
+#endif
+ if (csum1 != csum_known) {
+ printf("checksum for group 0 should be %04x\n", csum_known);
+ exit(1);
+ }
+ csum2 = ext2fs_group_desc_csum(fs, 1);
+ print_csum("csum0001", fs, 1);
+ if (csum1 == csum2) {
+ printf("checksums for different groups shouldn't match\n");
+ exit(1);
+ }
+ csum2 = ext2fs_group_desc_csum(fs, 2);
+ print_csum("csumffff", fs, 2);
+ if (csum1 == csum2) {
+ printf("checksums for different groups shouldn't match\n");
+ exit(1);
+ }
+ fs->group_desc[0].bg_checksum = csum1;
+ csum2 = ext2fs_group_desc_csum(fs, 0);
+ print_csum("csum_set", fs, 0);
+ if (csum1 != csum2) {
+ printf("checksums should not depend on checksum field\n");
+ exit(1);
+ }
+ if (!ext2fs_group_desc_csum_verify(fs, 0)) {
+ printf("checksums should verify against gd_checksum\n");
+ exit(1);
+ }
+ memset(fs->super->s_uuid, 0x30, sizeof(fs->super->s_uuid));
+ print_csum("new_uuid", fs, 0);
+ if (ext2fs_group_desc_csum_verify(fs, 0) != 0) {
+ printf("checksums for different filesystems shouldn't match\n");
+ exit(1);
+ }
+ csum1 = fs->group_desc[0].bg_checksum = ext2fs_group_desc_csum(fs, 0);
+ print_csum("csum_new", fs, 0);
+ fs->group_desc[0].bg_free_blocks_count = 1;
+ csum2 = ext2fs_group_desc_csum(fs, 0);
+ print_csum("csum_blk", fs, 0);
+ if (csum1 == csum2) {
+ printf("checksums for different data shouldn't match\n");
+ exit(1);
+ }
+
+ return 0;
+}
--
1.5.4.1.144.gdfee-dirty


2008-03-17 17:23:56

by Andreas Dilger

[permalink] [raw]
Subject: Re: [PATCH, REWORKED 01/11] Add initial checksum support for the gdt_checksum/uninit_group feature

On Mar 17, 2008 09:28 -0400, Theodore Ts'o wrote:
> +STATIC __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group)
> +{
> + __u16 crc = 0;
> + struct ext2_group_desc *desc;
> +
> + desc = &fs->group_desc[group];
> +
> + if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
> + int offset = offsetof(struct ext2_group_desc, bg_checksum);
> +
> +#ifdef WORDS_BIGENDIAN
> + struct ext2_group_desc swabdesc = *desc;
> +
> + /* Have to swab back to little-endian to do the checksum */
> + ext2fs_swap_group_desc(&swabdesc);
> + desc = &swabdesc;
> +
> + group = ext2fs_swab32(group);
> +#endif
> + crc = crc16(~0, fs->super->s_uuid, sizeof(fs->super->s_uuid));
> + crc = crc16(crc, &group, sizeof(group));
> + crc = crc16(crc, desc, offset);
> + offset += sizeof(desc->bg_checksum); /* skip checksum */
> + assert(offset == sizeof(*desc));

Note that this assertion needs to be removed when the group descriptor
becomes larger, unless ext2_group_desc never changes in the future..

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.


2008-03-17 18:05:29

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH, REWORKED 01/11] Add initial checksum support for the gdt_checksum/uninit_group feature

On Tue, Mar 18, 2008 at 01:22:54AM +0800, Andreas Dilger wrote:
> On Mar 17, 2008 09:28 -0400, Theodore Ts'o wrote:
> > +STATIC __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group)
....
> > + if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
> > + int offset = offsetof(struct ext2_group_desc, bg_checksum);
> > +
...
> > + offset += sizeof(desc->bg_checksum); /* skip checksum */
> > + assert(offset == sizeof(*desc));
>
> Note that this assertion needs to be removed when the group descriptor
> becomes larger, unless ext2_group_desc never changes in the future..

Yeah, I looked at this, and was half tempted to remove it.

Indeed ext2_group_desc will never change in the future. Too many
things would break if we change it. That's why there is an
ext4_group_desc which looks exactly like ext2_group_desc for the first
32 bytes, and adds the high 32-bits for the various fields in the
second 32-bytes.

But if ext2_group_desc is never going to change, then there's no real
good reason to use a run-time check here. Better to turn it into a
compile time check, using #error. The tricky part is doing it in a
way which is ANSI-C compliant (or maybe we just wrap it in a #ifdef
GCC and only do the sanity check if you are compiling with GCC).

- Ted

2008-03-18 00:27:15

by Andreas Dilger

[permalink] [raw]
Subject: Re: [PATCH, REWORKED 01/11] Add initial checksum support for the gdt_checksum/uninit_group feature

On Mar 17, 2008 14:05 -0400, Theodore Ts'o wrote:
> On Tue, Mar 18, 2008 at 01:22:54AM +0800, Andreas Dilger wrote:
> > On Mar 17, 2008 09:28 -0400, Theodore Ts'o wrote:
> > > +STATIC __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group)
> ....
> > > + if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
> > > + int offset = offsetof(struct ext2_group_desc, bg_checksum);
> > > +
> ...
> > > + offset += sizeof(desc->bg_checksum); /* skip checksum */
> > > + assert(offset == sizeof(*desc));
> >
> > Note that this assertion needs to be removed when the group descriptor
> > becomes larger, unless ext2_group_desc never changes in the future..
>
> Yeah, I looked at this, and was half tempted to remove it.
>
> Indeed ext2_group_desc will never change in the future. Too many
> things would break if we change it. That's why there is an
> ext4_group_desc which looks exactly like ext2_group_desc for the first
> 32 bytes, and adds the high 32-bits for the various fields in the
> second 32-bytes.
>
> But if ext2_group_desc is never going to change, then there's no real
> good reason to use a run-time check here. Better to turn it into a
> compile time check, using #error. The tricky part is doing it in a
> way which is ANSI-C compliant (or maybe we just wrap it in a #ifdef
> GCC and only do the sanity check if you are compiling with GCC).

We have a compile-time assertion like:

/*
* compile-time assertions. @cond has to be constant expression.
* ISO C Standard:
*
* 6.8.4.2 The switch statement
*
* ....
*
* [#3] The expression of each case label shall be an integer
* constant expression and no two of the case constant
* expressions in the same switch statement shall have the same
* value after conversion...
* *
*/
#define CLASSERT(cond) ({ switch(42) { case (cond): case 0: break; } })

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.


2008-03-19 19:39:24

by Andreas Dilger

[permalink] [raw]
Subject: Re: Respin of the uninit_group patches

On Mar 17, 2008 09:28 -0400, Theodore Ts'o wrote:
> I've reworked this patch series to clean them up a bit. In
> particular, an unused ext2fs_scan_inode flag (EXT2_SF_DO_CSUM) was
> removed

Sure.

> In addition, ext2fs_group_desc_set()
> and ext2fs_group_desc_verify() take an ext2_filsys argument instead of
> a superblock and a pointer to a group descriptor, in order to simplify
> the calling code.

Yeah, I did it that way to keep the kernel and e2fsprogs code the same.

> If this looks good, this should be the next set of patches to move
> into the 'next' branch.

Look good to me, though I didn't do a line-by-line analysis I thought
I'd let you know I gave them a once-over.

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.


2008-03-25 08:41:04

by Andreas Dilger

[permalink] [raw]
Subject: Re: Respin of the uninit_group patches

On Mar 17, 2008 09:28 -0400, Theodore Ts'o wrote:
> I've reworked this patch series to clean them up a bit. In
> particular, an unused ext2fs_scan_inode flag (EXT2_SF_DO_CSUM) was
> removed, and I made ext2fs_group_desc_csum() static, and added
> ext2fs_group_desc_csum_set(). In addition, ext2fs_group_desc_set()
> and ext2fs_group_desc_verify() take an ext2_filsys argument instead of
> a superblock and a pointer to a group descriptor, in order to simplify
> the calling code.

Sorry for the delayed reply on this. After discussions with Eric about
the endian fixes missing from e2fsck, I also looked back at the uninit
groups patches and did a line-by-line comparison to see if anything was
missing. Sure enough, there are a few checks, and all of the regression
tests are missing.

The missing code is attached here as a patch, and I've uploaded the full
set of CFS patches (against 1.40.5, which I wasn't previously able to
host anywhere) to http://downloads.lustre.org/people/adilger/ in case you
are missing any of the test cases:

tests/f_uninit_bad_free_inodes
tests/f_uninit_blk_used_not_set
tests/f_uninit_checksum_bad
tests/f_uninit_disable
tests/f_uninit_enable
tests/f_uninit_inode_past_unused
tests/f_uninit_last_uninit
tests/f_uninit_set_inode_not_set

I verified all of these tests pass with the code currently on the "next"
branch plus this patch. All of the f_extents_* patches currently fail,
but that is a different story (not sure I'll have time to look at those
before I go on vacation).

========================================================================

Add a check for the UNINIT_BLOCKS flag set in the last group. The kernel
patch doesn't handle this gracefully, because it assumes there are a full
set of blocks in each group marked UNINIT_BLOCKS. The kernel should be
fixed up, but in the meantime this avoids hitting the problem, and is
more consistent with lazy_bg not marking the last group UNINIT.

Un-static the ext2fs_group_desc_csum() so that it could be
used in parse_gd_csum(). The other alternative was to hack around and
have ext2fs_group_desc_csum_set() set the calculated checksum value in
the filesystem, extract it back into "val" and then have the caller
save it back into the filesystem... Yuck.

Add the ability to have debugfs calculate the correct group checksum.
This is used in the last_uninit testcase, and this requires re-adding the
call to ext2fs_group_desc_csum_set() in e2fsck's check_super_block(),
otherwise it doesn't update the checksums after having "fixed" these
errors and restarting e2fsck would cause the same problems to be hit
each time. It is now conditional upon having fixed some problem instead
of always being done, so this automatically makes it safe for read-only
filesystems, etc.

Split the m_lazy testcase into two tests - one that has resize enabled,
and one that does not. There were previously problems with lazy+resize
because the resize feature consumed blocks in some of the groups.

Signed-off-by: Andreas Dilger <[email protected]>

======================= e2fsprogs-uninit-update.patch ==================
diff --git a/debugfs/set_fields.c b/debugfs/set_fields.c
index a58c94e..cd371db 100644
--- a/debugfs/set_fields.c
+++ b/debugfs/set_fields.c
@@ -42,6 +42,7 @@
static struct ext2_super_block set_sb;
static struct ext2_inode set_inode;
static struct ext2_group_desc set_gd;
+static dgrp_t set_bg;
static ext2_ino_t set_ino;
static int array_idx;

@@ -63,6 +64,7 @@ static errcode_t parse_uuid(struct field_set_info *info, char *arg);
static errcode_t parse_hashalg(struct field_set_info *info, char *arg);
static errcode_t parse_time(struct field_set_info *info, char *arg);
static errcode_t parse_bmap(struct field_set_info *info, char *arg);
+static errcode_t parse_gd_csum(struct field_set_info *info, char *arg);

static struct field_set_info super_fields[] = {
{ "inodes_count", &set_sb.s_inodes_count, 4, parse_uint },
@@ -178,7 +180,7 @@ static struct field_set_info ext2_bg_fields[] = {
{ "flags", &set_gd.bg_flags, 2, parse_uint },
{ "reserved", &set_gd.bg_reserved, 2, parse_uint, FLAG_ARRAY, 2 },
{ "itable_unused", &set_gd.bg_itable_unused, 2, parse_uint },
- { "checksum", &set_gd.bg_checksum, 2, parse_uint },
+ { "checksum", &set_gd.bg_checksum, 2, parse_gd_csum },
{ 0, 0, 0, 0 }
};

@@ -402,6 +404,19 @@ static errcode_t parse_bmap(struct field_set_info *info, char *arg)
return retval;
}

+static errcode_t parse_gd_csum(struct field_set_info *info, char *arg)
+{
+
+ if (strcmp(arg, "calc") == 0) {
+ __u16 *val = info->ptr;
+
+ *val = ext2fs_group_desc_csum(current_fs, set_bg);
+
+ return 0;
+ }
+
+ return parse_uint(info, arg);
+}

static void print_possible_fields(struct field_set_info *fields)
{
@@ -521,7 +536,6 @@ void do_set_block_group_descriptor(int argc, char *argv[])
"\t\"set_block_group_descriptor -l\" will list the names of "
"the fields in a block group descriptor\n\twhich can be set.";
struct field_set_info *ss;
- dgrp_t set_bg;
char *end;

if ((argc == 2) && !strcmp(argv[1], "-l")) {
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index b6a3a81..134e767 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -371,16 +371,21 @@ static struct e2fsck_problem problem_table[] = {
N_("@g descriptor %g has invalid unused inodes count %b. "),
PROMPT_FIX, PR_PREEN_OK },

+ /* Last group block bitmap uninitialized. */
+ { PR_0_BB_UNINIT_LAST,
+ N_("last @g @b @B uninitialized. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
/* Pass 1 errors */

/* Pass 1: Checking inodes, blocks, and sizes */
{ PR_1_PASS_HEADER,
N_("Pass 1: Checking @is, @bs, and sizes\n"),
PROMPT_NONE, 0 },
-
+
/* Root directory is not an inode */
{ PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
- PROMPT_CLEAR, 0 },
+ PROMPT_CLEAR, 0 },

/* Root directory has dtime set */
{ PR_1_ROOT_DTIME,
@@ -1227,23 +1232,23 @@ static struct e2fsck_problem problem_table[] = {
{ PR_2_HTREE_BAD_DEPTH,
N_("@p @h %d: node (%B) has @n depth\n"),
PROMPT_NONE, 0 },
-
+
/* Duplicate directory entry found */
{ PR_2_DUPLICATE_DIRENT,
N_("Duplicate @E found. "),
PROMPT_CLEAR, 0 },
-
+
/* Non-unique filename found */
{ PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
N_("@E has a non-unique filename.\nRename to %s"),
PROMPT_NULL, 0 },
-
+
/* Duplicate directory entry found */
{ PR_2_REPORT_DUP_DIRENT,
N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
PROMPT_NONE, 0 },
-
- /* i_blocks_hi should be zero */
+
+ /* i_blocks_hi should be zero */
{ PR_2_BLOCKS_HI_ZERO,
N_("i_blocks_hi @F %N, @s zero.\n"),
PROMPT_CLEAR, 0 },
@@ -1251,7 +1256,7 @@ static struct e2fsck_problem problem_table[] = {
/* Unexpected HTREE block */
{ PR_2_UNEXPECTED_HTREE_BLOCK,
N_("Unexpected @b in @h %d (%q).\n"), PROMPT_CLEAR_HTREE, 0 },
-
+
/* Inode found in group where _INODE_UNINIT is set */
{ PR_2_INOREF_BG_INO_UNINIT,
N_("@i %i found in @g %g where _INODE_UNINIT is set. "),
@@ -1268,12 +1273,12 @@ static struct e2fsck_problem problem_table[] = {
{ PR_3_PASS_HEADER,
N_("Pass 3: Checking @d connectivity\n"),
PROMPT_NONE, 0 },
-
+
/* Root inode not allocated */
{ PR_3_NO_ROOT_INODE,
N_("@r not allocated. "),
- PROMPT_ALLOCATE, 0 },
-
+ PROMPT_ALLOCATE, 0 },
+
/* No room in lost+found */
{ PR_3_EXPAND_LF_DIR,
N_("No room in @l @d. "),
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index a2bd2b5..7993203 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -208,6 +208,9 @@ struct problem_context {
/* Group descriptor N has invalid unused inodes count. */
#define PR_0_GDT_ITABLE_UNUSED 0x000038

+/* Last group block bitmap is uninitialized. */
+#define PR_0_BB_UNINIT_LAST 0x000039
+
/*
* Pass 1 errors
*/
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 6753a14..87a0d78 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -631,11 +631,13 @@ void check_super_block(e2fsck_t ctx)
(gd->bg_used_dirs_count > sb->s_inodes_per_group))
ext2fs_unmark_valid(fs);

+ should_be = 0;
if (!ext2fs_group_desc_csum_verify(fs, i)) {
if (fix_problem(ctx, PR_0_GDT_CSUM, &pctx)) {
gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT |
EXT2_BG_INODE_UNINIT);
gd->bg_itable_unused = 0;
+ should_be = 1;
}
ext2fs_unmark_valid(fs);
}
@@ -647,23 +649,42 @@ void check_super_block(e2fsck_t ctx)
gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT |
EXT2_BG_INODE_UNINIT);
gd->bg_itable_unused = 0;
+ should_be = 1;
}
ext2fs_unmark_valid(fs);
}
+
+ if (i == fs->group_desc_count - 1 &&
+ gd->bg_flags & EXT2_BG_BLOCK_UNINIT) {
+ if (fix_problem(ctx, PR_0_BB_UNINIT_LAST, &pctx)) {
+ gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
+ should_be = 1;
+ }
+ ext2fs_unmark_valid(fs);
+ }
+
if (gd->bg_flags & EXT2_BG_BLOCK_UNINIT &&
!(gd->bg_flags & EXT2_BG_INODE_UNINIT)) {
- if (fix_problem(ctx, PR_0_BB_UNINIT_IB_INIT, &pctx))
+ if (fix_problem(ctx, PR_0_BB_UNINIT_IB_INIT, &pctx)) {
gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
+ should_be = 1;
+ }
ext2fs_unmark_valid(fs);
}
+
if (csum_flag &&
(gd->bg_itable_unused > gd->bg_free_inodes_count ||
gd->bg_itable_unused > sb->s_inodes_per_group)) {
pctx.blk = gd->bg_itable_unused;
- if (fix_problem(ctx, PR_0_GDT_ITABLE_UNUSED, &pctx))
+ if (fix_problem(ctx, PR_0_GDT_ITABLE_UNUSED, &pctx)) {
gd->bg_itable_unused = 0;
+ should_be = 1;
+ }
ext2fs_unmark_valid(fs);
}
+
+ if (should_be)
+ ext2fs_group_desc_csum_set(fs, i);
}

/*
diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index c35d924..6b25d6f 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -18,13 +18,7 @@
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

-#ifdef DEBUG
-#define STATIC
-#else
-#define STATIC static
-#endif
-
-STATIC __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group)
+__u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group)
{
__u16 crc = 0;
struct ext2_group_desc *desc;
@@ -104,6 +98,8 @@ void ext2fs_set_gdt_csum(ext2_filsys fs)

for (i = 0; i < fs->group_desc_count; i++, bg++) {
int old_csum = bg->bg_checksum;
+ int old_unused = bg->bg_itable_unused;
+ int old_flags = bg->bg_flags;

/* Even if it wasn't zeroed, by the time this function is
* called by e2fsck we have already scanned and corrected
@@ -112,48 +108,44 @@ void ext2fs_set_gdt_csum(ext2_filsys fs)
* zeroing of the inode table if mke2fs didn't do it, to help
* out if we need to do a full itable scan sometime later. */
if (!(bg->bg_flags & (EXT2_BG_INODE_UNINIT |
- EXT2_BG_INODE_ZEROED))) {
+ EXT2_BG_INODE_ZEROED)))
fs->group_desc[i].bg_flags |= EXT2_BG_INODE_ZEROED;
- dirty = 1;
- }

if (bg->bg_free_inodes_count == sb->s_inodes_per_group &&
i > 0 && (i < fs->group_desc_count - 1 || csum_flag)) {
- if (!(bg->bg_flags & EXT2_BG_INODE_UNINIT)) {
+ if (!(bg->bg_flags & EXT2_BG_INODE_UNINIT))
bg->bg_flags |= EXT2_BG_INODE_UNINIT;
- dirty = 1;
- }
- if (csum_flag) {
- int old_unused = bg->bg_itable_unused;
+
+ if (csum_flag)
bg->bg_itable_unused = sb->s_inodes_per_group;
- if (old_unused != bg->bg_itable_unused)
- dirty = 1;
- }
} else if (csum_flag) {
- int old_unused = bg->bg_itable_unused;
- bg->bg_flags &= ~EXT2_BG_INODE_UNINIT;
- bg->bg_itable_unused = sb->s_inodes_per_group -
- find_last_inode_ingrp(fs->inode_map,
+ if (fs->inode_map)
+ bg->bg_itable_unused = sb->s_inodes_per_group -
+ find_last_inode_ingrp(fs->inode_map,
sb->s_inodes_per_group,i);
- if (old_unused != bg->bg_itable_unused)
- dirty = 1;
+ else if (bg->bg_flags & EXT2_BG_INODE_UNINIT)
+ bg->bg_itable_unused = 0;
+
+ bg->bg_flags &= ~EXT2_BG_INODE_UNINIT;
}

/* skip first and last groups, or groups with GDT backups
* because the resize inode has blocks allocated in them. */
- if (i == 0 || (i == fs->group_desc_count - 1 && !csum_flag) ||
+ if (i == 0 || i == fs->group_desc_count - 1 ||
(ext2fs_bg_has_super(fs, i) && sb->s_reserved_gdt_blocks))
goto checksum;

blks = ext2fs_super_and_bgd_loc(fs, i, 0, 0, 0, 0);
if (bg->bg_free_blocks_count == blks &&
bg->bg_flags & EXT2_BG_INODE_UNINIT &&
- !(bg->bg_flags & EXT2_BG_BLOCK_UNINIT)) {
+ !(bg->bg_flags & EXT2_BG_BLOCK_UNINIT))
bg->bg_flags |= EXT2_BG_BLOCK_UNINIT;
- dirty = 1;
- }
checksum:
ext2fs_group_desc_csum_set(fs, i);
+ if (old_flags != bg->bg_flags)
+ dirty = 1;
+ if (old_unused != bg->bg_itable_unused)
+ dirty = 1;
if (old_csum != bg->bg_checksum)
dirty = 1;
}
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index b4a445d..bd568b3 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -239,9 +239,8 @@ static errcode_t get_next_blockgroup(ext2_inode_scan scan)
scan->inodes_left -=
fs->group_desc[scan->current_group].bg_itable_unused;
scan->blocks_left =
- (EXT2_INODES_PER_GROUP(fs->super) -
- fs->group_desc[scan->current_group].bg_itable_unused +
- fs->blocksize / scan->inode_size - 1) *
+ (scan->inodes_left +
+ (fs->blocksize / scan->inode_size - 1)) *
scan->inode_size / fs->blocksize;
}

diff --git a/lib/ext2fs/tst_csum.c b/lib/ext2fs/tst_csum.c
index e3fa9be..efeeb0a 100644
--- a/lib/ext2fs/tst_csum.c
+++ b/lib/ext2fs/tst_csum.c
@@ -4,8 +4,8 @@
* Copyright (C) 2006, 2007 by Andreas Dilger <[email protected]>
*
* %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
+ * This file may be redistributed under the terms of the GNU General Public
+ * License, Version 2. See the file COPYING for more details.
* %End-Header%
*/

diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
index a32c34a..79929b4 100644
--- a/misc/mke2fs.8.in
+++ b/misc/mke2fs.8.in
@@ -227,7 +227,7 @@ for the filesystem. (For administrators who are creating
filesystems on RAID arrays, it is preferable to use the
.I stride
RAID parameter as part of the
-.B \-R
+.B \-E
option rather than manipulating the number of blocks per group.)
This option is generally used by developers who
are developing test cases.
@@ -433,7 +433,7 @@ Create a filesystem without initializing all of the groups. This speeds
up filesystem creation time noticably, and can also reduce
.BR e2fsck time
dramatically. This feature causes the filesystem to be read-only in
-older kernels is not supported in most Linux kernels, use with caution.
+older kernels, and is not supported in most Linux kernels. Use with caution.
.B \-j
option).
@[email protected]
diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in
index b5af4d0..c6f1ca7 100644
--- a/misc/tune2fs.8.in
+++ b/misc/tune2fs.8.in
@@ -444,7 +444,9 @@ only supports clearing this filesystem feature.
Allow the kernel to initialize bitmaps and inode tables and keep a high
watermark for the unused inodes in a filesystem, to reduce
.BR e2fsck (8)
-time.
+time. This first e2fsck run after enabling this feature will take the
+full time, but subsequent e2fsck runs will take only a fraction of the
+original time, depending on how full the file system is.
.RE
.IP
After setting or clearing
@@ -464,6 +466,12 @@ if necessary. After setting the
feature,
.B e2fsck -D
can be run to convert existing directories to the hashed B-tree format.
+Enabling certain filesystem features may prevent the filesystem from being
+mounted by kernels which do not support those features. In particular the
+.BR uninit_groups
+and
+.BR flex_bg
+features are only supported by the ext4 filesystem.
.TP
.BI \-r " reserved-blocks-count"
Set the number of reserved filesystem blocks.
diff --git a/tests/f_uninit_last_uninit/expect.1 b/tests/f_uninit_last_uninit/expect.1
new file mode 100644
index 0000000..dae50e4
--- /dev/null
+++ b/tests/f_uninit_last_uninit/expect.1
@@ -0,0 +1,9 @@
+last group block bitmap uninitialized. Fix? yes
+
+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/32 files (9.1% non-contiguous), 105/10000 blocks
+Exit status is 0
diff --git a/tests/f_uninit_last_uninit/expect.2 b/tests/f_uninit_last_uninit/expect.2
new file mode 100644
index 0000000..435a8a7
--- /dev/null
+++ b/tests/f_uninit_last_uninit/expect.2
@@ -0,0 +1,7 @@
+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/32 files (9.1% non-contiguous), 105/10000 blocks
+Exit status is 0
diff --git a/tests/f_uninit_last_uninit/name b/tests/f_uninit_last_uninit/name
new file mode 100644
index 0000000..4f93e23
--- /dev/null
+++ b/tests/f_uninit_last_uninit/name
@@ -0,0 +1,2 @@
+last group has BLOCK_UNINIT set
+
diff --git a/tests/f_uninit_last_uninit/script b/tests/f_uninit_last_uninit/script
new file mode 100644
index 0000000..477357a
--- /dev/null
+++ b/tests/f_uninit_last_uninit/script
@@ -0,0 +1,20 @@
+SKIP_GUNZIP="true"
+
+touch $TMPFILE
+$MKE2FS -N 32 -F -o Linux -O uninit_groups -b 1024 $TMPFILE 10000 > /dev/null 2>&1
+$DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1
+set_current_time 200704102100
+set_super_value lastcheck 0
+set_super_value hash_seed null
+set_super_value mkfs_time 0
+set_bg 1 flags 0x7
+set_bg 1 checksum calc
+q
+EOF
+
+E2FSCK_TIME=200704102100
+export E2FSCK_TIME
+
+. $cmd_dir/run_e2fsck
+
+unset E2FSCK_TIME
diff --git a/tests/m_lazy/expect.1 b/tests/m_lazy/expect.1
index e0e459c..901133b 100644
--- a/tests/m_lazy/expect.1
+++ b/tests/m_lazy/expect.1
@@ -5,7 +5,6 @@ Fragment size=1024 (log=0)
32768 inodes, 131072 blocks
6553 blocks (5.00%) reserved for the super user
First data block=1
-Maximum filesystem blocks=67371008
16 block groups
8192 blocks per group, 8192 fragments per group
2048 inodes per group
@@ -15,21 +14,21 @@ Superblock backups stored on blocks:
Writing inode tables: done
Writing superblocks and filesystem accounting information: done

-Filesystem features: ext_attr resize_inode dir_index lazy_bg filetype sparse_super
+Filesystem features: ext_attr dir_index lazy_bg 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: 28683/32768 files (0.0% non-contiguous), 77097/131072 blocks
+test_filesys: 28683/32768 files (0.0% non-contiguous), 115220/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 lazy_bg filetype sparse_super
+Filesystem features: ext_attr dir_index lazy_bg filetype sparse_super
Default mount options: (none)
Filesystem state: clean
Errors behavior: Continue
@@ -37,12 +36,11 @@ Filesystem OS type: Linux
Inode count: 32768
Block count: 131072
Reserved block count: 6553
-Free blocks: 53975
+Free blocks: 15852
Free inodes: 4085
First block: 1
Block size: 1024
Fragment size: 1024
-Reserved GDT blocks: 256
Blocks per group: 8192
Fragments per group: 8192
Inodes per group: 2048
@@ -58,19 +56,17 @@ Default directory hash: tea

Group 0: (Blocks 1-8192)
Primary superblock at 1, Group descriptors at 2-2
- 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
- Free blocks: 531-8192
+ Block bitmap at 3 (+2), Inode bitmap at 4 (+3)
+ Inode table at 5-260 (+4)
+ 7919 free blocks, 2037 free inodes, 2 directories
+ Free blocks: 274-8192
Free inodes: 12-2048
-Group 1: (Blocks 8193-16384) [Inode not init]
+Group 1: (Blocks 8193-16384) [Inode not init, Block not init]
Backup superblock at 8193, Group descriptors at 8194-8194
- Reserved GDT blocks at 8195-8450
- Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
- Inode table at 8453-8708 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 8709-16384
+ Block bitmap at 8195 (+2), Inode bitmap at 8196 (+3)
+ Inode table at 8197-8452 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
@@ -78,13 +74,12 @@ Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
0 free blocks, 0 free inodes, 0 directories
Free blocks:
Free inodes:
-Group 3: (Blocks 24577-32768) [Inode not init]
+Group 3: (Blocks 24577-32768) [Inode not init, Block not init]
Backup superblock at 24577, Group descriptors at 24578-24578
- Reserved GDT blocks at 24579-24834
- Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
- Inode table at 24837-25092 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 25093-32768
+ Block bitmap at 24579 (+2), Inode bitmap at 24580 (+3)
+ Inode table at 24581-24836 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
@@ -92,13 +87,12 @@ Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
0 free blocks, 0 free inodes, 0 directories
Free blocks:
Free inodes:
-Group 5: (Blocks 40961-49152) [Inode not init]
+Group 5: (Blocks 40961-49152) [Inode not init, Block not init]
Backup superblock at 40961, Group descriptors at 40962-40962
- Reserved GDT blocks at 40963-41218
- Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
- Inode table at 41221-41476 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 41477-49152
+ Block bitmap at 40963 (+2), Inode bitmap at 40964 (+3)
+ Inode table at 40965-41220 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
@@ -106,13 +100,12 @@ Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
0 free blocks, 0 free inodes, 0 directories
Free blocks:
Free inodes:
-Group 7: (Blocks 57345-65536) [Inode not init]
+Group 7: (Blocks 57345-65536) [Inode not init, Block not init]
Backup superblock at 57345, Group descriptors at 57346-57346
- Reserved GDT blocks at 57347-57602
- Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
- Inode table at 57605-57860 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 57861-65536
+ Block bitmap at 57347 (+2), Inode bitmap at 57348 (+3)
+ Inode table at 57349-57604 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
@@ -120,13 +113,12 @@ Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
0 free blocks, 0 free inodes, 0 directories
Free blocks:
Free inodes:
-Group 9: (Blocks 73729-81920) [Inode not init]
+Group 9: (Blocks 73729-81920) [Inode not init, Block not init]
Backup superblock at 73729, Group descriptors at 73730-73730
- Reserved GDT blocks at 73731-73986
- Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
- Inode table at 73989-74244 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 74245-81920
+ Block bitmap at 73731 (+2), Inode bitmap at 73732 (+3)
+ Inode table at 73733-73988 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 10: (Blocks 81921-90112) [Inode not init, Block not init]
Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
diff --git a/tests/m_lazy/script b/tests/m_lazy/script
index 35be0c8..aaac8f0 100644
--- a/tests/m_lazy/script
+++ b/tests/m_lazy/script
@@ -1,4 +1,4 @@
DESCRIPTION="lazy group feature"
FS_SIZE=131072
-MKE2FS_OPTS="-O lazy_bg"
+MKE2FS_OPTS="-O ^resize_inode,lazy_bg"
. $cmd_dir/run_mke2fs
diff --git a/tests/m_lazy_resize/expect.1 b/tests/m_lazy_resize/expect.1
new file mode 100644
index 0000000..e0e459c
--- /dev/null
+++ b/tests/m_lazy_resize/expect.1
@@ -0,0 +1,166 @@
+Filesystem label=
+OS type: Linux
+Block size=1024 (log=0)
+Fragment size=1024 (log=0)
+32768 inodes, 131072 blocks
+6553 blocks (5.00%) reserved for the super user
+First data block=1
+Maximum filesystem blocks=67371008
+16 block groups
+8192 blocks per group, 8192 fragments per group
+2048 inodes per group
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729
+
+Writing inode tables: done
+Writing superblocks and filesystem accounting information: done
+
+Filesystem features: ext_attr resize_inode dir_index lazy_bg 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: 28683/32768 files (0.0% non-contiguous), 77097/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 lazy_bg filetype sparse_super
+Default mount options: (none)
+Filesystem state: clean
+Errors behavior: Continue
+Filesystem OS type: Linux
+Inode count: 32768
+Block count: 131072
+Reserved block count: 6553
+Free blocks: 53975
+Free inodes: 4085
+First block: 1
+Block size: 1024
+Fragment size: 1024
+Reserved GDT blocks: 256
+Blocks per group: 8192
+Fragments per group: 8192
+Inodes per group: 2048
+Inode blocks per group: 256
+Mount count: 0
+Check interval: 15552000 (6 months)
+Reserved blocks uid: 0
+Reserved blocks gid: 0
+First inode: 11
+Inode size: 128
+Default directory hash: tea
+
+
+Group 0: (Blocks 1-8192)
+ Primary superblock at 1, Group descriptors at 2-2
+ 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
+ Free blocks: 531-8192
+ Free inodes: 12-2048
+Group 1: (Blocks 8193-16384) [Inode not init]
+ Backup superblock at 8193, Group descriptors at 8194-8194
+ Reserved GDT blocks at 8195-8450
+ Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
+ Inode table at 8453-8708 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 8709-16384
+ Free inodes:
+Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
+ Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
+ Inode table at 16387-16642 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 3: (Blocks 24577-32768) [Inode not init]
+ Backup superblock at 24577, Group descriptors at 24578-24578
+ Reserved GDT blocks at 24579-24834
+ Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
+ Inode table at 24837-25092 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 25093-32768
+ Free inodes:
+Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
+ Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
+ Inode table at 32771-33026 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 5: (Blocks 40961-49152) [Inode not init]
+ Backup superblock at 40961, Group descriptors at 40962-40962
+ Reserved GDT blocks at 40963-41218
+ Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
+ Inode table at 41221-41476 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 41477-49152
+ Free inodes:
+Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
+ Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
+ Inode table at 49155-49410 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 7: (Blocks 57345-65536) [Inode not init]
+ Backup superblock at 57345, Group descriptors at 57346-57346
+ Reserved GDT blocks at 57347-57602
+ Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
+ Inode table at 57605-57860 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 57861-65536
+ Free inodes:
+Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
+ Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
+ Inode table at 65539-65794 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 9: (Blocks 73729-81920) [Inode not init]
+ Backup superblock at 73729, Group descriptors at 73730-73730
+ Reserved GDT blocks at 73731-73986
+ Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
+ Inode table at 73989-74244 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 74245-81920
+ Free inodes:
+Group 10: (Blocks 81921-90112) [Inode not init, Block not init]
+ Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
+ Inode table at 81923-82178 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 11: (Blocks 90113-98304) [Inode not init, Block not init]
+ Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
+ Inode table at 90115-90370 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 12: (Blocks 98305-106496) [Inode not init, Block not init]
+ Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
+ Inode table at 98307-98562 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 13: (Blocks 106497-114688) [Inode not init, Block not init]
+ Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
+ Inode table at 106499-106754 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 14: (Blocks 114689-122880) [Inode not init, Block not init]
+ Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
+ Inode table at 114691-114946 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 15: (Blocks 122881-131071)
+ Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
+ Inode table at 122883-123138 (+2)
+ 7933 free blocks, 2048 free inodes, 0 directories
+ Free blocks: 123139-131071
+ Free inodes: 30721-32768
diff --git a/tests/m_lazy_resize/script b/tests/m_lazy_resize/script
new file mode 100644
index 0000000..2ba081f
--- /dev/null
+++ b/tests/m_lazy_resize/script
@@ -0,0 +1,4 @@
+DESCRIPTION="lazy group feature with resize_inode"
+FS_SIZE=131072
+MKE2FS_OPTS="-O resize_inode,lazy_bg"
+. $cmd_dir/run_mke2fs
diff --git a/tests/m_uninit/expect.1 b/tests/m_uninit/expect.1
index c6c32b9..8d19a40 100644
--- a/tests/m_uninit/expect.1
+++ b/tests/m_uninit/expect.1
@@ -158,9 +158,9 @@ Group 14: (Blocks 114689-122880) [Inode not init, Block not init]
7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
Free blocks:
Free inodes:
-Group 15: (Blocks 122881-131071) [Inode not init, Block not init]
+Group 15: (Blocks 122881-131071) [Inode not init]
Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
Inode table at 122883-123138 (+2)
7933 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
- Free blocks:
+ Free blocks: 123139-131071
Free inodes:
Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.


2008-03-25 09:16:05

by Andreas Dilger

[permalink] [raw]
Subject: Re: Respin of the uninit_group patches

On Mar 17, 2008 09:28 -0400, Theodore Ts'o wrote:
> I've reworked this patch series to clean them up a bit. In
> particular, an unused ext2fs_scan_inode flag (EXT2_SF_DO_CSUM) was
> removed, and I made ext2fs_group_desc_csum() static, and added
> ext2fs_group_desc_csum_set(). In addition, ext2fs_group_desc_set()
> and ext2fs_group_desc_verify() take an ext2_filsys argument instead of
> a superblock and a pointer to a group descriptor, in order to simplify
> the calling code.
>
> If this looks good, this should be the next set of patches to move
> into the 'next' branch.

I note in our bugzilla that we still have an open bug against the
uninit_groups patch related to resize2fs, related to the fact that
resize2fs allocating new inodes or blocks will likely not clear
the UNINIT flags from the groups it is working on:

https://bugzilla.lustre.org/show_bug.cgi?id=12002

I verified that the code to disable resize2fs is still in the "next"
branch, so there is no immediate danger, but it also means that
filesystems with uninit_groups enabled can not be resized.

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.


2008-03-31 23:39:08

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] Add new regression test: f_uninit_last_uninit

From: Andreas Dilger <[email protected]>

Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
tests/f_uninit_last_uninit/expect.1 | 9 +++++++++
tests/f_uninit_last_uninit/expect.2 | 7 +++++++
tests/f_uninit_last_uninit/name | 2 ++
tests/f_uninit_last_uninit/script | 20 ++++++++++++++++++++
4 files changed, 38 insertions(+), 0 deletions(-)
create mode 100644 tests/f_uninit_last_uninit/expect.1
create mode 100644 tests/f_uninit_last_uninit/expect.2
create mode 100644 tests/f_uninit_last_uninit/name
create mode 100644 tests/f_uninit_last_uninit/script

diff --git a/tests/f_uninit_last_uninit/expect.1 b/tests/f_uninit_last_uninit/expect.1
new file mode 100644
index 0000000..85f05ee
--- /dev/null
+++ b/tests/f_uninit_last_uninit/expect.1
@@ -0,0 +1,9 @@
+Last group block bitmap uninitialized. Fix? yes
+
+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/32 files (9.1% non-contiguous), 105/10000 blocks
+Exit status is 0
diff --git a/tests/f_uninit_last_uninit/expect.2 b/tests/f_uninit_last_uninit/expect.2
new file mode 100644
index 0000000..435a8a7
--- /dev/null
+++ b/tests/f_uninit_last_uninit/expect.2
@@ -0,0 +1,7 @@
+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/32 files (9.1% non-contiguous), 105/10000 blocks
+Exit status is 0
diff --git a/tests/f_uninit_last_uninit/name b/tests/f_uninit_last_uninit/name
new file mode 100644
index 0000000..4f93e23
--- /dev/null
+++ b/tests/f_uninit_last_uninit/name
@@ -0,0 +1,2 @@
+last group has BLOCK_UNINIT set
+
diff --git a/tests/f_uninit_last_uninit/script b/tests/f_uninit_last_uninit/script
new file mode 100644
index 0000000..477357a
--- /dev/null
+++ b/tests/f_uninit_last_uninit/script
@@ -0,0 +1,20 @@
+SKIP_GUNZIP="true"
+
+touch $TMPFILE
+$MKE2FS -N 32 -F -o Linux -O uninit_groups -b 1024 $TMPFILE 10000 > /dev/null 2>&1
+$DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1
+set_current_time 200704102100
+set_super_value lastcheck 0
+set_super_value hash_seed null
+set_super_value mkfs_time 0
+set_bg 1 flags 0x7
+set_bg 1 checksum calc
+q
+EOF
+
+E2FSCK_TIME=200704102100
+export E2FSCK_TIME
+
+. $cmd_dir/run_e2fsck
+
+unset E2FSCK_TIME
--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:39:11

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] Split the m_lazy test case into two cases: m_lazy and m_lazy_resize

From: Andreas Dilger <[email protected]>

Split the m_lazy testcase into two tests - one that has resize enabled,
and one that does not. There were previously problems with lazy+resize
because the resize feature consumed blocks in some of the groups.

Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
tests/m_lazy/expect.1 | 74 ++++++++----------
tests/m_lazy/script | 2 +-
tests/m_lazy_resize/expect.1 | 166 ++++++++++++++++++++++++++++++++++++++++++
tests/m_lazy_resize/script | 4 +
4 files changed, 204 insertions(+), 42 deletions(-)
create mode 100644 tests/m_lazy_resize/expect.1
create mode 100644 tests/m_lazy_resize/script

diff --git a/tests/m_lazy/expect.1 b/tests/m_lazy/expect.1
index e0e459c..901133b 100644
--- a/tests/m_lazy/expect.1
+++ b/tests/m_lazy/expect.1
@@ -5,7 +5,6 @@ Fragment size=1024 (log=0)
32768 inodes, 131072 blocks
6553 blocks (5.00%) reserved for the super user
First data block=1
-Maximum filesystem blocks=67371008
16 block groups
8192 blocks per group, 8192 fragments per group
2048 inodes per group
@@ -15,21 +14,21 @@ Superblock backups stored on blocks:
Writing inode tables: done
Writing superblocks and filesystem accounting information: done

-Filesystem features: ext_attr resize_inode dir_index lazy_bg filetype sparse_super
+Filesystem features: ext_attr dir_index lazy_bg 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: 28683/32768 files (0.0% non-contiguous), 77097/131072 blocks
+test_filesys: 28683/32768 files (0.0% non-contiguous), 115220/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 lazy_bg filetype sparse_super
+Filesystem features: ext_attr dir_index lazy_bg filetype sparse_super
Default mount options: (none)
Filesystem state: clean
Errors behavior: Continue
@@ -37,12 +36,11 @@ Filesystem OS type: Linux
Inode count: 32768
Block count: 131072
Reserved block count: 6553
-Free blocks: 53975
+Free blocks: 15852
Free inodes: 4085
First block: 1
Block size: 1024
Fragment size: 1024
-Reserved GDT blocks: 256
Blocks per group: 8192
Fragments per group: 8192
Inodes per group: 2048
@@ -58,19 +56,17 @@ Default directory hash: tea

Group 0: (Blocks 1-8192)
Primary superblock at 1, Group descriptors at 2-2
- 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
- Free blocks: 531-8192
+ Block bitmap at 3 (+2), Inode bitmap at 4 (+3)
+ Inode table at 5-260 (+4)
+ 7919 free blocks, 2037 free inodes, 2 directories
+ Free blocks: 274-8192
Free inodes: 12-2048
-Group 1: (Blocks 8193-16384) [Inode not init]
+Group 1: (Blocks 8193-16384) [Inode not init, Block not init]
Backup superblock at 8193, Group descriptors at 8194-8194
- Reserved GDT blocks at 8195-8450
- Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
- Inode table at 8453-8708 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 8709-16384
+ Block bitmap at 8195 (+2), Inode bitmap at 8196 (+3)
+ Inode table at 8197-8452 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
@@ -78,13 +74,12 @@ Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
0 free blocks, 0 free inodes, 0 directories
Free blocks:
Free inodes:
-Group 3: (Blocks 24577-32768) [Inode not init]
+Group 3: (Blocks 24577-32768) [Inode not init, Block not init]
Backup superblock at 24577, Group descriptors at 24578-24578
- Reserved GDT blocks at 24579-24834
- Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
- Inode table at 24837-25092 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 25093-32768
+ Block bitmap at 24579 (+2), Inode bitmap at 24580 (+3)
+ Inode table at 24581-24836 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
@@ -92,13 +87,12 @@ Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
0 free blocks, 0 free inodes, 0 directories
Free blocks:
Free inodes:
-Group 5: (Blocks 40961-49152) [Inode not init]
+Group 5: (Blocks 40961-49152) [Inode not init, Block not init]
Backup superblock at 40961, Group descriptors at 40962-40962
- Reserved GDT blocks at 40963-41218
- Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
- Inode table at 41221-41476 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 41477-49152
+ Block bitmap at 40963 (+2), Inode bitmap at 40964 (+3)
+ Inode table at 40965-41220 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
@@ -106,13 +100,12 @@ Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
0 free blocks, 0 free inodes, 0 directories
Free blocks:
Free inodes:
-Group 7: (Blocks 57345-65536) [Inode not init]
+Group 7: (Blocks 57345-65536) [Inode not init, Block not init]
Backup superblock at 57345, Group descriptors at 57346-57346
- Reserved GDT blocks at 57347-57602
- Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
- Inode table at 57605-57860 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 57861-65536
+ Block bitmap at 57347 (+2), Inode bitmap at 57348 (+3)
+ Inode table at 57349-57604 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
@@ -120,13 +113,12 @@ Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
0 free blocks, 0 free inodes, 0 directories
Free blocks:
Free inodes:
-Group 9: (Blocks 73729-81920) [Inode not init]
+Group 9: (Blocks 73729-81920) [Inode not init, Block not init]
Backup superblock at 73729, Group descriptors at 73730-73730
- Reserved GDT blocks at 73731-73986
- Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
- Inode table at 73989-74244 (+260)
- 7676 free blocks, 0 free inodes, 0 directories
- Free blocks: 74245-81920
+ Block bitmap at 73731 (+2), Inode bitmap at 73732 (+3)
+ Inode table at 73733-73988 (+4)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
Free inodes:
Group 10: (Blocks 81921-90112) [Inode not init, Block not init]
Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
diff --git a/tests/m_lazy/script b/tests/m_lazy/script
index 35be0c8..aaac8f0 100644
--- a/tests/m_lazy/script
+++ b/tests/m_lazy/script
@@ -1,4 +1,4 @@
DESCRIPTION="lazy group feature"
FS_SIZE=131072
-MKE2FS_OPTS="-O lazy_bg"
+MKE2FS_OPTS="-O ^resize_inode,lazy_bg"
. $cmd_dir/run_mke2fs
diff --git a/tests/m_lazy_resize/expect.1 b/tests/m_lazy_resize/expect.1
new file mode 100644
index 0000000..e0e459c
--- /dev/null
+++ b/tests/m_lazy_resize/expect.1
@@ -0,0 +1,166 @@
+Filesystem label=
+OS type: Linux
+Block size=1024 (log=0)
+Fragment size=1024 (log=0)
+32768 inodes, 131072 blocks
+6553 blocks (5.00%) reserved for the super user
+First data block=1
+Maximum filesystem blocks=67371008
+16 block groups
+8192 blocks per group, 8192 fragments per group
+2048 inodes per group
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729
+
+Writing inode tables: done
+Writing superblocks and filesystem accounting information: done
+
+Filesystem features: ext_attr resize_inode dir_index lazy_bg 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: 28683/32768 files (0.0% non-contiguous), 77097/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 lazy_bg filetype sparse_super
+Default mount options: (none)
+Filesystem state: clean
+Errors behavior: Continue
+Filesystem OS type: Linux
+Inode count: 32768
+Block count: 131072
+Reserved block count: 6553
+Free blocks: 53975
+Free inodes: 4085
+First block: 1
+Block size: 1024
+Fragment size: 1024
+Reserved GDT blocks: 256
+Blocks per group: 8192
+Fragments per group: 8192
+Inodes per group: 2048
+Inode blocks per group: 256
+Mount count: 0
+Check interval: 15552000 (6 months)
+Reserved blocks uid: 0
+Reserved blocks gid: 0
+First inode: 11
+Inode size: 128
+Default directory hash: tea
+
+
+Group 0: (Blocks 1-8192)
+ Primary superblock at 1, Group descriptors at 2-2
+ 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
+ Free blocks: 531-8192
+ Free inodes: 12-2048
+Group 1: (Blocks 8193-16384) [Inode not init]
+ Backup superblock at 8193, Group descriptors at 8194-8194
+ Reserved GDT blocks at 8195-8450
+ Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
+ Inode table at 8453-8708 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 8709-16384
+ Free inodes:
+Group 2: (Blocks 16385-24576) [Inode not init, Block not init]
+ Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
+ Inode table at 16387-16642 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 3: (Blocks 24577-32768) [Inode not init]
+ Backup superblock at 24577, Group descriptors at 24578-24578
+ Reserved GDT blocks at 24579-24834
+ Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
+ Inode table at 24837-25092 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 25093-32768
+ Free inodes:
+Group 4: (Blocks 32769-40960) [Inode not init, Block not init]
+ Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
+ Inode table at 32771-33026 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 5: (Blocks 40961-49152) [Inode not init]
+ Backup superblock at 40961, Group descriptors at 40962-40962
+ Reserved GDT blocks at 40963-41218
+ Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
+ Inode table at 41221-41476 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 41477-49152
+ Free inodes:
+Group 6: (Blocks 49153-57344) [Inode not init, Block not init]
+ Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
+ Inode table at 49155-49410 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 7: (Blocks 57345-65536) [Inode not init]
+ Backup superblock at 57345, Group descriptors at 57346-57346
+ Reserved GDT blocks at 57347-57602
+ Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
+ Inode table at 57605-57860 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 57861-65536
+ Free inodes:
+Group 8: (Blocks 65537-73728) [Inode not init, Block not init]
+ Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
+ Inode table at 65539-65794 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 9: (Blocks 73729-81920) [Inode not init]
+ Backup superblock at 73729, Group descriptors at 73730-73730
+ Reserved GDT blocks at 73731-73986
+ Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
+ Inode table at 73989-74244 (+260)
+ 7676 free blocks, 0 free inodes, 0 directories
+ Free blocks: 74245-81920
+ Free inodes:
+Group 10: (Blocks 81921-90112) [Inode not init, Block not init]
+ Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
+ Inode table at 81923-82178 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 11: (Blocks 90113-98304) [Inode not init, Block not init]
+ Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
+ Inode table at 90115-90370 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 12: (Blocks 98305-106496) [Inode not init, Block not init]
+ Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
+ Inode table at 98307-98562 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 13: (Blocks 106497-114688) [Inode not init, Block not init]
+ Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
+ Inode table at 106499-106754 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 14: (Blocks 114689-122880) [Inode not init, Block not init]
+ Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
+ Inode table at 114691-114946 (+2)
+ 0 free blocks, 0 free inodes, 0 directories
+ Free blocks:
+ Free inodes:
+Group 15: (Blocks 122881-131071)
+ Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
+ Inode table at 122883-123138 (+2)
+ 7933 free blocks, 2048 free inodes, 0 directories
+ Free blocks: 123139-131071
+ Free inodes: 30721-32768
diff --git a/tests/m_lazy_resize/script b/tests/m_lazy_resize/script
new file mode 100644
index 0000000..2ba081f
--- /dev/null
+++ b/tests/m_lazy_resize/script
@@ -0,0 +1,4 @@
+DESCRIPTION="lazy group feature with resize_inode"
+FS_SIZE=131072
+MKE2FS_OPTS="-O resize_inode,lazy_bg"
+. $cmd_dir/run_mke2fs
--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:39:14

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] e2fsck: Add check to enforce a valid block bitmap in last block group

From: Andreas Dilger <[email protected]>

Add a check for the UNINIT_BLOCKS flag set in the last group. The kernel
patch doesn't handle this gracefully, because it assumes there are a full
set of blocks in each group marked UNINIT_BLOCKS. The kernel should be
fixed up, but in the meantime this avoids hitting the problem, and is
more consistent with lazy_bg not marking the last group UNINIT.

Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
e2fsck/problem.c | 5 +++++
e2fsck/problem.h | 3 +++
e2fsck/super.c | 25 +++++++++++++++++++++++--
3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index b6a3a81..828be88 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -371,6 +371,11 @@ static struct e2fsck_problem problem_table[] = {
N_("@g descriptor %g has invalid unused inodes count %b. "),
PROMPT_FIX, PR_PREEN_OK },

+ /* Last group block bitmap uninitialized. */
+ { PR_0_BB_UNINIT_LAST,
+ N_("Last @g @b @B uninitialized. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
/* Pass 1 errors */

/* Pass 1: Checking inodes, blocks, and sizes */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index a2bd2b5..7993203 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -208,6 +208,9 @@ struct problem_context {
/* Group descriptor N has invalid unused inodes count. */
#define PR_0_GDT_ITABLE_UNUSED 0x000038

+/* Last group block bitmap is uninitialized. */
+#define PR_0_BB_UNINIT_LAST 0x000039
+
/*
* Pass 1 errors
*/
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 6753a14..87a0d78 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -631,11 +631,13 @@ void check_super_block(e2fsck_t ctx)
(gd->bg_used_dirs_count > sb->s_inodes_per_group))
ext2fs_unmark_valid(fs);

+ should_be = 0;
if (!ext2fs_group_desc_csum_verify(fs, i)) {
if (fix_problem(ctx, PR_0_GDT_CSUM, &pctx)) {
gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT |
EXT2_BG_INODE_UNINIT);
gd->bg_itable_unused = 0;
+ should_be = 1;
}
ext2fs_unmark_valid(fs);
}
@@ -647,23 +649,42 @@ void check_super_block(e2fsck_t ctx)
gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT |
EXT2_BG_INODE_UNINIT);
gd->bg_itable_unused = 0;
+ should_be = 1;
}
ext2fs_unmark_valid(fs);
}
+
+ if (i == fs->group_desc_count - 1 &&
+ gd->bg_flags & EXT2_BG_BLOCK_UNINIT) {
+ if (fix_problem(ctx, PR_0_BB_UNINIT_LAST, &pctx)) {
+ gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
+ should_be = 1;
+ }
+ ext2fs_unmark_valid(fs);
+ }
+
if (gd->bg_flags & EXT2_BG_BLOCK_UNINIT &&
!(gd->bg_flags & EXT2_BG_INODE_UNINIT)) {
- if (fix_problem(ctx, PR_0_BB_UNINIT_IB_INIT, &pctx))
+ if (fix_problem(ctx, PR_0_BB_UNINIT_IB_INIT, &pctx)) {
gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
+ should_be = 1;
+ }
ext2fs_unmark_valid(fs);
}
+
if (csum_flag &&
(gd->bg_itable_unused > gd->bg_free_inodes_count ||
gd->bg_itable_unused > sb->s_inodes_per_group)) {
pctx.blk = gd->bg_itable_unused;
- if (fix_problem(ctx, PR_0_GDT_ITABLE_UNUSED, &pctx))
+ if (fix_problem(ctx, PR_0_GDT_ITABLE_UNUSED, &pctx)) {
gd->bg_itable_unused = 0;
+ should_be = 1;
+ }
ext2fs_unmark_valid(fs);
}
+
+ if (should_be)
+ ext2fs_group_desc_csum_set(fs, i);
}

/*
--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:39:19

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] ext2fs_set_gdt_csum(): Return an error code on errors instead of void

From: Andreas Dilger <[email protected]>

Change the function signature so that ext2fs_set_gdt_csum() returns an
error code.

If the inode bitmap hasn't been loaded return EXT2_ET_NO_INODE_BITMAP.

Signed-off-by: "Theodore Ts'o" <[email protected]>
---
e2fsck/unix.c | 10 ++++++++--
lib/ext2fs/csum.c | 8 ++++++--
lib/ext2fs/ext2fs.h | 2 +-
misc/mke2fs.c | 10 ++++++++--
4 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/e2fsck/unix.c b/e2fsck/unix.c
index deec442..93af87b 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -1349,8 +1349,14 @@ no_journal:
}

if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM &&
- !(ctx->options & E2F_OPT_READONLY))
- ext2fs_set_gdt_csum(ctx->fs);
+ !(ctx->options & E2F_OPT_READONLY)) {
+ retval = ext2fs_set_gdt_csum(ctx->fs);
+ if (retval) {
+ com_err(ctx->program_name, retval,
+ _("while setting block group checksum info"));
+ fatal_error(ctx, 0);
+ }
+ }

e2fsck_write_bitmaps(ctx);
#ifdef RESOURCE_TRACK
diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index 70deaa9..0774e00 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -89,18 +89,21 @@ static __u32 find_last_inode_ingrp(ext2fs_inode_bitmap bitmap,

/* update the bitmap flags, set the itable high watermark, and calculate
* checksums for the group descriptors */
-void ext2fs_set_gdt_csum(ext2_filsys fs)
+errcode_t ext2fs_set_gdt_csum(ext2_filsys fs)
{
struct ext2_super_block *sb = fs->super;
struct ext2_group_desc *bg = fs->group_desc;
int blks, csum_flag, dirty = 0;
dgrp_t i;

+ if (!fs->inode_map)
+ return EXT2_ET_NO_INODE_BITMAP;
+
csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
if (!EXT2_HAS_COMPAT_FEATURE(fs->super,
EXT2_FEATURE_COMPAT_LAZY_BG) && !csum_flag)
- return;
+ return 0;

for (i = 0; i < fs->group_desc_count; i++, bg++) {
int old_csum = bg->bg_checksum;
@@ -153,4 +156,5 @@ checksum:
}
if (dirty)
ext2fs_mark_super_dirty(fs);
+ return 0;
}
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index b6c1b8d..1a7cb86 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -710,7 +710,7 @@ extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
/* csum.c */
extern void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group);
extern int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_set_gdt_csum(ext2_filsys fs);
+extern errcode_t ext2fs_set_gdt_csum(ext2_filsys fs);

/* dblist.c */

diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 857d345..fd48b83 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -1792,8 +1792,14 @@ int main (int argc, char *argv[])
}
no_journal:

- if (!super_only)
- ext2fs_set_gdt_csum(fs);
+ if (!super_only) {
+ retval = ext2fs_set_gdt_csum(fs);
+ if (retval) {
+ com_err(program_name, retval,
+ _("\n\twhile setting block group checksum info"));
+ exit(1);
+ }
+ }
if (!quiet)
printf(_("Writing superblocks and "
"filesystem accounting information: "));
--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:39:24

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] Improve ext4 feature descriptions in mke2fs and tune2fs man pages

From: Andreas Dilger <[email protected]>

Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
misc/mke2fs.8.in | 14 +++++++-------
misc/tune2fs.8.in | 10 +++++++++-
2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
index 390874c..6cd10b1 100644
--- a/misc/mke2fs.8.in
+++ b/misc/mke2fs.8.in
@@ -427,13 +427,6 @@ Store file type information in directory entries.
.TP
.B has_journal
Create an ext3 journal (as if using the
-.TP
-.B uninit_groups
-Create a filesystem without initializing all of the groups. This speeds
-up filesystem creation time noticably, and can also reduce
-.BR e2fsck time
-dramatically. This feature causes the filesystem to be read-only in
-older kernels is not supported in most Linux kernels, use with caution.
.B \-j
option).
@[email protected]
@@ -445,6 +438,13 @@ option).
@JDEV@must be created with the same
@JDEV@block size as the filesystems that will be using it.
.TP
+.B uninit_groups
+Create a filesystem without initializing all of the groups. This speeds
+up filesystem creation time noticably, and can also reduce
+.BR e2fsck time
+dramatically. This feature is only supported by the ext4 filesystem in
+recent Linux kernels.
+.TP
.B resize_inode
Reserve space so the block group descriptor table may grow in the future.
Useful for online resizing using
diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in
index 69da5de..66d9d52 100644
--- a/misc/tune2fs.8.in
+++ b/misc/tune2fs.8.in
@@ -444,7 +444,9 @@ only supports clearing this filesystem feature.
Allow the kernel to initialize bitmaps and inode tables and keep a high
watermark for the unused inodes in a filesystem, to reduce
.BR e2fsck (8)
-time.
+time. This first e2fsck run after enabling this feature will take the
+full time, but subsequent e2fsck runs will take only a fraction of the
+original time, depending on how full the file system is.
.RE
.IP
After setting or clearing
@@ -464,6 +466,12 @@ if necessary. After setting the
feature,
.B e2fsck -D
can be run to convert existing directories to the hashed B-tree format.
+Enabling certain filesystem features may prevent the filesystem from being
+mounted by kernels which do not support those features. In particular the
+.BR uninit_groups
+and
+.BR flex_bg
+features are only supported by the ext4 filesystem.
.TP
.BI \-r " reserved-blocks-count"
Set the number of reserved filesystem blocks.
--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:39:28

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] ext2fs_set_gdt_csum(): Clean up superblock dirty flag handling

From: Andreas Dilger <[email protected]>

Only mark the superblock as dirty if the function actually managed to
change part of the block group descriptor.

Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
lib/ext2fs/csum.c | 28 +++++++++++-----------------
1 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index c35d924..a385d76 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -104,6 +104,8 @@ void ext2fs_set_gdt_csum(ext2_filsys fs)

for (i = 0; i < fs->group_desc_count; i++, bg++) {
int old_csum = bg->bg_checksum;
+ int old_unused = bg->bg_itable_unused;
+ int old_flags = bg->bg_flags;

/* Even if it wasn't zeroed, by the time this function is
* called by e2fsck we have already scanned and corrected
@@ -112,31 +114,21 @@ void ext2fs_set_gdt_csum(ext2_filsys fs)
* zeroing of the inode table if mke2fs didn't do it, to help
* out if we need to do a full itable scan sometime later. */
if (!(bg->bg_flags & (EXT2_BG_INODE_UNINIT |
- EXT2_BG_INODE_ZEROED))) {
+ EXT2_BG_INODE_ZEROED)))
fs->group_desc[i].bg_flags |= EXT2_BG_INODE_ZEROED;
- dirty = 1;
- }

if (bg->bg_free_inodes_count == sb->s_inodes_per_group &&
i > 0 && (i < fs->group_desc_count - 1 || csum_flag)) {
- if (!(bg->bg_flags & EXT2_BG_INODE_UNINIT)) {
+ if (!(bg->bg_flags & EXT2_BG_INODE_UNINIT))
bg->bg_flags |= EXT2_BG_INODE_UNINIT;
- dirty = 1;
- }
- if (csum_flag) {
- int old_unused = bg->bg_itable_unused;
+
+ if (csum_flag)
bg->bg_itable_unused = sb->s_inodes_per_group;
- if (old_unused != bg->bg_itable_unused)
- dirty = 1;
- }
} else if (csum_flag) {
- int old_unused = bg->bg_itable_unused;
bg->bg_flags &= ~EXT2_BG_INODE_UNINIT;
bg->bg_itable_unused = sb->s_inodes_per_group -
find_last_inode_ingrp(fs->inode_map,
sb->s_inodes_per_group,i);
- if (old_unused != bg->bg_itable_unused)
- dirty = 1;
}

/* skip first and last groups, or groups with GDT backups
@@ -148,12 +140,14 @@ void ext2fs_set_gdt_csum(ext2_filsys fs)
blks = ext2fs_super_and_bgd_loc(fs, i, 0, 0, 0, 0);
if (bg->bg_free_blocks_count == blks &&
bg->bg_flags & EXT2_BG_INODE_UNINIT &&
- !(bg->bg_flags & EXT2_BG_BLOCK_UNINIT)) {
+ !(bg->bg_flags & EXT2_BG_BLOCK_UNINIT))
bg->bg_flags |= EXT2_BG_BLOCK_UNINIT;
- dirty = 1;
- }
checksum:
ext2fs_group_desc_csum_set(fs, i);
+ if (old_flags != bg->bg_flags)
+ dirty = 1;
+ if (old_unused != bg->bg_itable_unused)
+ dirty = 1;
if (old_csum != bg->bg_checksum)
dirty = 1;
}
--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:39:18

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] libext2fs: Micro-optimization in inode scan code

From: Andreas Dilger <[email protected]>

Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
lib/ext2fs/inode.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index b4a445d..bd568b3 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -239,9 +239,8 @@ static errcode_t get_next_blockgroup(ext2_inode_scan scan)
scan->inodes_left -=
fs->group_desc[scan->current_group].bg_itable_unused;
scan->blocks_left =
- (EXT2_INODES_PER_GROUP(fs->super) -
- fs->group_desc[scan->current_group].bg_itable_unused +
- fs->blocksize / scan->inode_size - 1) *
+ (scan->inodes_left +
+ (fs->blocksize / scan->inode_size - 1)) *
scan->inode_size / fs->blocksize;
}

--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:39:22

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] ext2fs_set_gdt_csum(): Force the last block group to have a valid block bitmap

From: Andreas Dilger <[email protected]>

Never set the UNINIT_BLOCKS flag for the last group since the kernel
doesn't handle the case graefully if there is a full set of blocks in
each blockgroup marked UNINIT_BLOCKS. The kernel should be fixed up,
but in the meantime this avoids hitting the problem, and is more
consistent with lazy_bg not marking the last group UNINIT.

Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
lib/ext2fs/csum.c | 2 +-
tests/m_uninit/expect.1 | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index a385d76..70deaa9 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -133,7 +133,7 @@ void ext2fs_set_gdt_csum(ext2_filsys fs)

/* skip first and last groups, or groups with GDT backups
* because the resize inode has blocks allocated in them. */
- if (i == 0 || (i == fs->group_desc_count - 1 && !csum_flag) ||
+ if (i == 0 || i == fs->group_desc_count - 1 ||
(ext2fs_bg_has_super(fs, i) && sb->s_reserved_gdt_blocks))
goto checksum;

diff --git a/tests/m_uninit/expect.1 b/tests/m_uninit/expect.1
index c6c32b9..8d19a40 100644
--- a/tests/m_uninit/expect.1
+++ b/tests/m_uninit/expect.1
@@ -158,9 +158,9 @@ Group 14: (Blocks 114689-122880) [Inode not init, Block not init]
7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
Free blocks:
Free inodes:
-Group 15: (Blocks 122881-131071) [Inode not init, Block not init]
+Group 15: (Blocks 122881-131071) [Inode not init]
Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
Inode table at 122883-123138 (+2)
7933 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
- Free blocks:
+ Free blocks: 123139-131071
Free inodes:
--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:39:31

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] debugfs: Add support for "set_block_group <bg_num> checksum calc"

From: Andreas Dilger <[email protected]>

Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
debugfs/set_fields.c | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/debugfs/set_fields.c b/debugfs/set_fields.c
index a58c94e..ee51c45 100644
--- a/debugfs/set_fields.c
+++ b/debugfs/set_fields.c
@@ -42,6 +42,7 @@
static struct ext2_super_block set_sb;
static struct ext2_inode set_inode;
static struct ext2_group_desc set_gd;
+static dgrp_t set_bg;
static ext2_ino_t set_ino;
static int array_idx;

@@ -63,6 +64,7 @@ static errcode_t parse_uuid(struct field_set_info *info, char *arg);
static errcode_t parse_hashalg(struct field_set_info *info, char *arg);
static errcode_t parse_time(struct field_set_info *info, char *arg);
static errcode_t parse_bmap(struct field_set_info *info, char *arg);
+static errcode_t parse_gd_csum(struct field_set_info *info, char *arg);

static struct field_set_info super_fields[] = {
{ "inodes_count", &set_sb.s_inodes_count, 4, parse_uint },
@@ -178,7 +180,7 @@ static struct field_set_info ext2_bg_fields[] = {
{ "flags", &set_gd.bg_flags, 2, parse_uint },
{ "reserved", &set_gd.bg_reserved, 2, parse_uint, FLAG_ARRAY, 2 },
{ "itable_unused", &set_gd.bg_itable_unused, 2, parse_uint },
- { "checksum", &set_gd.bg_checksum, 2, parse_uint },
+ { "checksum", &set_gd.bg_checksum, 2, parse_gd_csum },
{ 0, 0, 0, 0 }
};

@@ -402,6 +404,19 @@ static errcode_t parse_bmap(struct field_set_info *info, char *arg)
return retval;
}

+static errcode_t parse_gd_csum(struct field_set_info *info, char *arg)
+{
+
+ if (strcmp(arg, "calc") == 0) {
+ ext2fs_group_desc_csum_set(current_fs, set_bg);
+ set_gd = current_fs->group_desc[set_bg];
+ printf("Checksum set to 0x%04x\n",
+ current_fs->group_desc[set_bg].bg_checksum);
+ return 0;
+ }
+
+ return parse_uint(info, arg);
+}

static void print_possible_fields(struct field_set_info *fields)
{
@@ -521,7 +536,6 @@ void do_set_block_group_descriptor(int argc, char *argv[])
"\t\"set_block_group_descriptor -l\" will list the names of "
"the fields in a block group descriptor\n\twhich can be set.";
struct field_set_info *ss;
- dgrp_t set_bg;
char *end;

if ((argc == 2) && !strcmp(argv[1], "-l")) {
--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:39:32

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] Fix the copyright notice in lib/ext2fs/tst_csum.c to be GPLv2 only

From: Andreas Dilger <[email protected]>

Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
lib/ext2fs/tst_csum.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/ext2fs/tst_csum.c b/lib/ext2fs/tst_csum.c
index e3fa9be..efeeb0a 100644
--- a/lib/ext2fs/tst_csum.c
+++ b/lib/ext2fs/tst_csum.c
@@ -4,8 +4,8 @@
* Copyright (C) 2006, 2007 by Andreas Dilger <[email protected]>
*
* %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
+ * This file may be redistributed under the terms of the GNU General Public
+ * License, Version 2. See the file COPYING for more details.
* %End-Header%
*/

--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:43:02

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH, E2FSPROGS] Fix trailing whitespace in e2fsck/problem.[ch]

Signed-off-by: "Theodore Ts'o" <[email protected]>
---
e2fsck/problem.c | 246 +++++++++++++++++++++++++++---------------------------
e2fsck/problem.h | 106 ++++++++++++------------
2 files changed, 176 insertions(+), 176 deletions(-)

diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 828be88..d9ae911 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -54,7 +54,7 @@ static const char *prompt[] = {
N_("Allocate"), /* 4 */
N_("Expand"), /* 5 */
N_("Connect to /lost+found"), /* 6 */
- N_("Create"), /* 7 */
+ N_("Create"), /* 7 */
N_("Salvage"), /* 8 */
N_("Truncate"), /* 9 */
N_("Clear inode"), /* 10 */
@@ -104,11 +104,11 @@ static struct e2fsck_problem problem_table[] = {

/* Block bitmap not in group */
{ PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
- PROMPT_RELOCATE, PR_LATCH_RELOC },
+ PROMPT_RELOCATE, PR_LATCH_RELOC },

/* Inode bitmap not in group */
{ PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
- PROMPT_RELOCATE, PR_LATCH_RELOC },
+ PROMPT_RELOCATE, PR_LATCH_RELOC },

/* Inode table not in group */
{ PR_0_ITABLE_NOT_GROUP,
@@ -132,7 +132,7 @@ static struct e2fsck_problem problem_table[] = {
"Either the @S or the partition table is likely to be corrupt!\n"),
PROMPT_ABORT, 0 },

- /* Fragments not supported */
+ /* Fragments not supported */
{ PR_0_NO_FRAGMENTS,
N_("@S @b_size = %b, fragsize = %c.\n"
"This version of e2fsck does not support fragment sizes different\n"
@@ -148,7 +148,7 @@ static struct e2fsck_problem problem_table[] = {
{ PR_0_FIRST_DATA_BLOCK,
N_("@S first_data_@b = %b, should have been %c\n"),
PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
-
+
/* Adding UUID to filesystem */
{ PR_0_ADD_UUID,
N_("@f did not have a UUID; generating one.\n\n"),
@@ -169,7 +169,7 @@ static struct e2fsck_problem problem_table[] = {
PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },

/* Error determing physical device size of filesystem */
- { PR_0_GETSIZE_ERROR,
+ { PR_0_GETSIZE_ERROR,
N_("Error determining size of the physical @v: %m\n"),
PROMPT_NONE, PR_FATAL },

@@ -259,12 +259,12 @@ static struct e2fsck_problem problem_table[] = {
{ PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
N_("@I @b #%B (%b) found in @o @i %i.\n"),
PROMPT_NONE, 0 },
-
+
/* Already cleared block found in orphaned inode */
{ PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
PROMPT_NONE, 0 },
-
+
/* Illegal orphan inode in superblock */
{ PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
N_("@I @o @i %i in @S.\n"),
@@ -382,10 +382,10 @@ static struct e2fsck_problem problem_table[] = {
{ PR_1_PASS_HEADER,
N_("Pass 1: Checking @is, @bs, and sizes\n"),
PROMPT_NONE, 0 },
-
+
/* Root directory is not an inode */
{ PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
- PROMPT_CLEAR, 0 },
+ PROMPT_CLEAR, 0 },

/* Root directory has dtime set */
{ PR_1_ROOT_DTIME,
@@ -441,7 +441,7 @@ static struct e2fsck_problem problem_table[] = {
{ PR_1_BAD_I_SIZE,
N_("@i %i, i_size is %Is, @s %N. "),
PROMPT_FIX, PR_PREEN_OK },
-
+
/* Inode has incorrect i_blocks */
{ PR_1_BAD_I_BLOCKS,
N_("@i %i, i_@bs is %Ib, @s %N. "),
@@ -465,7 +465,7 @@ static struct e2fsck_problem problem_table[] = {
/* Too many bad blocks in inode */
{ PR_1_TOO_MANY_BAD_BLOCKS,
N_("Too many illegal @bs in @i %i.\n"),
- PROMPT_CLEAR_INODE, PR_NO_OK },
+ PROMPT_CLEAR_INODE, PR_NO_OK },

/* Illegal block number in bad block inode */
{ PR_1_BB_ILLEGAL_BLOCK_NUM,
@@ -482,12 +482,12 @@ static struct e2fsck_problem problem_table[] = {
N_("Duplicate or bad @b in use!\n"),
PROMPT_NONE, 0 },

- /* Bad block used as bad block indirect block */
+ /* Bad block used as bad block indirect block */
{ PR_1_BBINODE_BAD_METABLOCK,
N_("Bad @b %b used as bad @b @i indirect @b. "),
PROMPT_CLEAR, PR_LATCH_BBLOCK },

- /* Inconsistency can't be fixed prompt */
+ /* Inconsistency can't be fixed prompt */
{ PR_1_BBINODE_BAD_METABLOCK_PROMPT,
N_("\nThe bad @b @i has probably been corrupted. You probably\n"
"should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
@@ -495,12 +495,12 @@ static struct e2fsck_problem problem_table[] = {
PROMPT_CONTINUE, PR_PREEN_NOMSG },

/* Bad primary block */
- { PR_1_BAD_PRIMARY_BLOCK,
+ { PR_1_BAD_PRIMARY_BLOCK,
N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
-
+
/* Bad primary block prompt */
- { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
+ { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
N_("You can remove this @b from the bad @b list and hope\n"
"that the @b is really OK. But there are no guarantees.\n\n"),
PROMPT_CLEAR, PR_PREEN_NOMSG },
@@ -509,25 +509,25 @@ static struct e2fsck_problem problem_table[] = {
{ PR_1_BAD_PRIMARY_SUPERBLOCK,
N_("The primary @S (%b) is on the bad @b list.\n"),
PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
-
+
/* Bad primary block group descriptors */
{ PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
N_("Block %b in the primary @g descriptors "
"is on the bad @b list\n"),
PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
-
+
/* Bad superblock in group */
{ PR_1_BAD_SUPERBLOCK,
N_("Warning: Group %g's @S (%b) is bad.\n"),
PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
-
+
/* Bad block group descriptors in group */
{ PR_1_BAD_GROUP_DESCRIPTORS,
N_("Warning: Group %g's copy of the @g descriptors has a bad "
"@b (%b).\n"),
PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },

- /* Block claimed for no reason */
+ /* Block claimed for no reason */
{ PR_1_PROGERR_CLAIMED_BLOCK,
N_("Programming error? @b #%b claimed for no reason in "
"process_bad_@b.\n"),
@@ -537,27 +537,27 @@ static struct e2fsck_problem problem_table[] = {
{ PR_1_RELOC_BLOCK_ALLOCATE,
N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
PROMPT_NONE, PR_PREEN_OK },
-
+
/* Error allocating block buffer during relocation process */
{ PR_1_RELOC_MEMORY_ALLOCATE,
N_("@A @b buffer for relocating %s\n"),
PROMPT_NONE, PR_PREEN_OK },
-
- /* Relocating metadata group information from X to Y */
+
+ /* Relocating metadata group information from X to Y */
{ PR_1_RELOC_FROM_TO,
N_("Relocating @g %g's %s from %b to %c...\n"),
PROMPT_NONE, PR_PREEN_OK },
-
+
/* Relocating metatdata group information to X */
{ PR_1_RELOC_TO,
N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
PROMPT_NONE, PR_PREEN_OK },
-
+
/* Block read error during relocation process */
{ PR_1_RELOC_READ_ERR,
N_("Warning: could not read @b %b of %s: %m\n"),
PROMPT_NONE, PR_PREEN_OK },
-
+
/* Block write error during relocation process */
{ PR_1_RELOC_WRITE_ERR,
N_("Warning: could not write @b %b for %s: %m\n"),
@@ -593,25 +593,25 @@ static struct e2fsck_problem problem_table[] = {
N_("Error while iterating over @bs in @i %i: %m\n"),
PROMPT_NONE, PR_FATAL },

- /* Error while storing inode count information */
+ /* Error while storing inode count information */
{ PR_1_ICOUNT_STORE,
N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
PROMPT_NONE, PR_FATAL },

- /* Error while storing directory block information */
+ /* Error while storing directory block information */
{ PR_1_ADD_DBLOCK,
N_("Error storing @d @b information "
"(@i=%i, @b=%b, num=%N): %m\n"),
PROMPT_NONE, PR_FATAL },

- /* Error while reading inode (for clearing) */
+ /* Error while reading inode (for clearing) */
{ PR_1_READ_INODE,
N_("Error reading @i %i: %m\n"),
PROMPT_NONE, PR_FATAL },

/* Suppress messages prompt */
{ PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
-
+
/* Imagic flag set on an inode when filesystem doesn't support it */
{ PR_1_SET_IMAGIC,
N_("@i %i has imagic flag set. "),
@@ -638,11 +638,11 @@ static struct e2fsck_problem problem_table[] = {
N_("@f has feature flag(s) set, but is a revision 0 @f. "),
PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },

- /* Journal inode is not in use, but contains data */
+ /* Journal inode is not in use, but contains data */
{ PR_1_JOURNAL_INODE_NOT_CLEAR,
N_("@j @i is not in use, but contains data. "),
- PROMPT_CLEAR, PR_PREEN_OK },
-
+ PROMPT_CLEAR, PR_PREEN_OK },
+
/* Journal has bad mode */
{ PR_1_JOURNAL_BAD_MODE,
N_("@j is not regular file. "),
@@ -651,14 +651,14 @@ static struct e2fsck_problem problem_table[] = {
/* Deal with inodes that were part of orphan linked list */
{ PR_1_LOW_DTIME,
N_("@i %i was part of the @o @i list. "),
- PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
+ PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },

/* Deal with inodes that were part of corrupted orphan linked
list (latch question) */
{ PR_1_ORPHAN_LIST_REFUGEES,
N_("@is that were part of a corrupted orphan linked list found. "),
- PROMPT_FIX, 0 },
-
+ PROMPT_FIX, 0 },
+
/* Error allocating refcount structure */
{ PR_1_ALLOCATE_REFCOUNT,
N_("@A refcount structure (%N): %m\n"),
@@ -678,13 +678,13 @@ static struct e2fsck_problem problem_table[] = {
{ PR_1_EXTATTR_READ_ABORT,
N_("Error reading @a @b %b (%m). "),
PROMPT_ABORT, 0 },
-
+
/* Extended attribute reference count incorrect */
{ PR_1_EXTATTR_REFCOUNT,
N_("@a @b %b has reference count %B, @s %N. "),
PROMPT_FIX, 0 },
-
- /* Error writing Extended Attribute block while fixing refcount */
+
+ /* Error writing Extended Attribute block while fixing refcount */
{ PR_1_EXTATTR_WRITE,
N_("Error writing @a @b %b (%m). "),
PROMPT_ABORT, 0 },
@@ -692,22 +692,22 @@ static struct e2fsck_problem problem_table[] = {
/* Multiple EA blocks not supported */
{ PR_1_EA_MULTI_BLOCK,
N_("@a @b %b has h_@bs > 1. "),
- PROMPT_CLEAR, 0},
+ PROMPT_CLEAR, 0},

/* Error allocating EA region allocation structure */
{ PR_1_EA_ALLOC_REGION,
N_("@A @a @b %b. "),
PROMPT_ABORT, 0},
-
+
/* Error EA allocation collision */
{ PR_1_EA_ALLOC_COLLISION,
N_("@a @b %b is corrupt (allocation collision). "),
PROMPT_CLEAR, 0},
-
+
/* Bad extended attribute name */
{ PR_1_EA_BAD_NAME,
N_("@a @b %b is corrupt (@n name). "),
- PROMPT_CLEAR, 0},
+ PROMPT_CLEAR, 0},

/* Bad extended attribute value */
{ PR_1_EA_BAD_VALUE,
@@ -719,7 +719,7 @@ static struct e2fsck_problem problem_table[] = {
N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },

/* Directory too big */
- { PR_1_TOOBIG_DIR,
+ { PR_1_TOOBIG_DIR,
N_("@b #%B (%b) causes @d to be too big. "),
PROMPT_CLEAR, PR_LATCH_TOOBIG },

@@ -738,31 +738,31 @@ static struct e2fsck_problem problem_table[] = {
N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
PROMPT_CLEAR_HTREE, PR_PREEN_OK },

- /* INDEX_FL flag set on a non-directory */
+ /* INDEX_FL flag set on a non-directory */
{ PR_1_HTREE_NODIR,
N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
PROMPT_CLEAR_HTREE, PR_PREEN_OK },

- /* Invalid root node in HTREE directory */
+ /* Invalid root node in HTREE directory */
{ PR_1_HTREE_BADROOT,
N_("@h %i has an @n root node.\n"),
PROMPT_CLEAR_HTREE, PR_PREEN_OK },

- /* Unsupported hash version in HTREE directory */
+ /* Unsupported hash version in HTREE directory */
{ PR_1_HTREE_HASHV,
N_("@h %i has an unsupported hash version (%N)\n"),
PROMPT_CLEAR_HTREE, PR_PREEN_OK },

- /* Incompatible flag in HTREE root node */
+ /* Incompatible flag in HTREE root node */
{ PR_1_HTREE_INCOMPAT,
N_("@h %i uses an incompatible htree root node flag.\n"),
PROMPT_CLEAR_HTREE, PR_PREEN_OK },

- /* HTREE too deep */
+ /* HTREE too deep */
{ PR_1_HTREE_DEPTH,
N_("@h %i has a tree depth (%N) which is too big\n"),
PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
+
/* Bad block has indirect block that conflicts with filesystem block */
{ PR_1_BB_FS_BLOCK,
N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
@@ -774,32 +774,32 @@ static struct e2fsck_problem problem_table[] = {
N_("Resize @i (re)creation failed: %m."),
PROMPT_ABORT, 0 },

- /* invalid inode->i_extra_isize */
+ /* invalid inode->i_extra_isize */
{ PR_1_EXTRA_ISIZE,
N_("@i %i has a extra size (%IS) which is @n\n"),
PROMPT_FIX, PR_PREEN_OK },

- /* invalid ea entry->e_name_len */
+ /* invalid ea entry->e_name_len */
{ PR_1_ATTR_NAME_LEN,
N_("@a in @i %i has a namelen (%N) which is @n\n"),
PROMPT_CLEAR, PR_PREEN_OK },

- /* invalid ea entry->e_value_size */
+ /* invalid ea entry->e_value_size */
{ PR_1_ATTR_VALUE_SIZE,
N_("@a in @i %i has a value size (%N) which is @n\n"),
PROMPT_CLEAR, PR_PREEN_OK },

- /* invalid ea entry->e_value_offs */
+ /* invalid ea entry->e_value_offs */
{ PR_1_ATTR_VALUE_OFFSET,
N_("@a in @i %i has a value offset (%N) which is @n\n"),
PROMPT_CLEAR, PR_PREEN_OK },

- /* invalid ea entry->e_value_block */
+ /* invalid ea entry->e_value_block */
{ PR_1_ATTR_VALUE_BLOCK,
N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
PROMPT_CLEAR, PR_PREEN_OK },

- /* invalid ea entry->e_hash */
+ /* invalid ea entry->e_hash */
{ PR_1_ATTR_HASH,
N_("@a in @i %i has a hash (%N) which is @n\n"),
PROMPT_CLEAR, PR_PREEN_OK },
@@ -858,12 +858,12 @@ static struct e2fsck_problem problem_table[] = {
PROMPT_NONE, 0 },

/* Duplicate/bad block(s) header */
- { PR_1B_DUP_BLOCK_HEADER,
+ { PR_1B_DUP_BLOCK_HEADER,
N_("@m @b(s) in @i %i:"),
PROMPT_NONE, 0 },

/* Duplicate/bad block(s) in inode */
- { PR_1B_DUP_BLOCK,
+ { PR_1B_DUP_BLOCK,
" %b",
PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },

@@ -871,7 +871,7 @@ static struct e2fsck_problem problem_table[] = {
{ PR_1B_DUP_BLOCK_END,
"\n",
PROMPT_NONE, PR_PREEN_NOHDR },
-
+
/* Error while scanning inodes */
{ PR_1B_ISCAN_ERROR,
N_("Error while scanning inodes (%i): %m\n"),
@@ -898,29 +898,29 @@ static struct e2fsck_problem problem_table[] = {
N_("Pass 1C: Scanning directories for @is with @m @bs\n"),
PROMPT_NONE, 0 },

-
+
/* Pass 1D: Reconciling multiply-claimed blocks */
{ PR_1D_PASS_HEADER,
N_("Pass 1D: Reconciling @m @bs\n"),
PROMPT_NONE, 0 },
-
+
/* File has duplicate blocks */
{ PR_1D_DUP_FILE,
N_("File %Q (@i #%i, mod time %IM) \n"
" has %B @m @b(s), shared with %N file(s):\n"),
PROMPT_NONE, 0 },
-
- /* List of files sharing duplicate blocks */
+
+ /* List of files sharing duplicate blocks */
{ PR_1D_DUP_FILE_LIST,
N_("\t%Q (@i #%i, mod time %IM)\n"),
PROMPT_NONE, 0 },
-
- /* File sharing blocks with filesystem metadata */
+
+ /* File sharing blocks with filesystem metadata */
{ PR_1D_SHARE_METADATA,
N_("\t<@f metadata>\n"),
PROMPT_NONE, 0 },

- /* Report of how many duplicate/bad inodes */
+ /* Report of how many duplicate/bad inodes */
{ PR_1D_NUM_DUP_INODES,
N_("(There are %N @is containing @m @bs.)\n\n"),
PROMPT_NONE, 0 },
@@ -933,7 +933,7 @@ static struct e2fsck_problem problem_table[] = {
/* Clone duplicate/bad blocks? */
{ PR_1D_CLONE_QUESTION,
"", PROMPT_CLONE, PR_NO_OK },
-
+
/* Delete file? */
{ PR_1D_DELETE_QUESTION,
"", PROMPT_DELETE, 0 },
@@ -948,24 +948,24 @@ static struct e2fsck_problem problem_table[] = {
{ PR_2_PASS_HEADER,
N_("Pass 2: Checking @d structure\n"),
PROMPT_NONE, 0 },
-
+
/* Bad inode number for '.' */
{ PR_2_BAD_INODE_DOT,
N_("@n @i number for '.' in @d @i %i.\n"),
PROMPT_FIX, 0 },

/* Directory entry has bad inode number */
- { PR_2_BAD_INO,
+ { PR_2_BAD_INO,
N_("@E has @n @i #: %Di.\n"),
PROMPT_CLEAR, 0 },

/* Directory entry has deleted or unused inode */
- { PR_2_UNUSED_INODE,
+ { PR_2_UNUSED_INODE,
N_("@E has @D/unused @i %Di. "),
PROMPT_CLEAR, PR_PREEN_OK },

/* Directry entry is link to '.' */
- { PR_2_LINK_DOT,
+ { PR_2_LINK_DOT,
N_("@E @L to '.' "),
PROMPT_CLEAR, 0 },

@@ -975,26 +975,26 @@ static struct e2fsck_problem problem_table[] = {
PROMPT_CLEAR, 0 },

/* Directory entry contains a link to a directory */
- { PR_2_LINK_DIR,
+ { PR_2_LINK_DIR,
N_("@E @L to @d %P (%Di).\n"),
PROMPT_CLEAR, 0 },

/* Directory entry contains a link to the root directry */
- { PR_2_LINK_ROOT,
+ { PR_2_LINK_ROOT,
N_("@E @L to the @r.\n"),
PROMPT_CLEAR, 0 },

/* Directory entry has illegal characters in its name */
- { PR_2_BAD_NAME,
+ { PR_2_BAD_NAME,
N_("@E has illegal characters in its name.\n"),
PROMPT_FIX, 0 },

- /* Missing '.' in directory inode */
+ /* Missing '.' in directory inode */
{ PR_2_MISSING_DOT,
N_("Missing '.' in @d @i %i.\n"),
PROMPT_FIX, 0 },

- /* Missing '..' in directory inode */
+ /* Missing '..' in directory inode */
{ PR_2_MISSING_DOT_DOT,
N_("Missing '..' in @d @i %i.\n"),
PROMPT_FIX, 0 },
@@ -1008,7 +1008,7 @@ static struct e2fsck_problem problem_table[] = {
{ PR_2_2ND_NOT_DOT_DOT,
N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
PROMPT_FIX, 0 },
-
+
/* i_faddr should be zero */
{ PR_2_FADDR_ZERO,
N_("i_faddr @F %IF, @s zero.\n"),
@@ -1040,17 +1040,17 @@ static struct e2fsck_problem problem_table[] = {
PROMPT_CLEAR, 0 },

/* directory corrupted */
- { PR_2_DIR_CORRUPTED,
+ { PR_2_DIR_CORRUPTED,
N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
PROMPT_SALVAGE, 0 },
-
+
/* filename too long */
- { PR_2_FILENAME_LONG,
+ { PR_2_FILENAME_LONG,
N_("@d @i %i, @b %B, offset %N: filename too long\n"),
PROMPT_TRUNCATE, 0 },

/* Directory inode has a missing block (hole) */
- { PR_2_DIRECTORY_HOLE,
+ { PR_2_DIRECTORY_HOLE,
N_("@d @i %i has an unallocated @b #%B. "),
PROMPT_ALLOCATE, 0 },

@@ -1077,7 +1077,7 @@ static struct e2fsck_problem problem_table[] = {
/* Duplicate '.' entry */
{ PR_2_DUP_DOT,
N_("@E is duplicate '.' @e.\n"),
- PROMPT_FIX, 0 },
+ PROMPT_FIX, 0 },

/* Duplicate '..' entry */
{ PR_2_DUP_DOT_DOT,
@@ -1093,7 +1093,7 @@ static struct e2fsck_problem problem_table[] = {
{ PR_2_FINAL_RECLEN,
N_("@E has rec_len of %Dr, @s %N.\n"),
PROMPT_FIX, 0 },
-
+
/* Error allocating icount structure */
{ PR_2_ALLOCATE_ICOUNT,
N_("@A icount structure: %m\n"),
@@ -1173,7 +1173,7 @@ static struct e2fsck_problem problem_table[] = {
{ PR_2_FEATURE_LARGE_FILES,
N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
PROMPT_FIX, 0 },
-
+
/* Node in HTREE directory not referenced */
{ PR_2_HTREE_NOTREF,
N_("@p @h %d: node (%B) not referenced\n"),
@@ -1197,7 +1197,7 @@ static struct e2fsck_problem problem_table[] = {
/* Clear invalid HTREE directory */
{ PR_2_HTREE_CLEAR,
N_("@n @h %d (%q). "), PROMPT_CLEAR_HTREE, 0 },
-
+
/* Bad block in htree interior node */
{ PR_2_HTREE_BADBLK,
N_("@p @h %d (%q): bad @b number %b.\n"),
@@ -1232,22 +1232,22 @@ static struct e2fsck_problem problem_table[] = {
{ PR_2_HTREE_BAD_DEPTH,
N_("@p @h %d: node (%B) has @n depth\n"),
PROMPT_NONE, 0 },
-
+
/* Duplicate directory entry found */
{ PR_2_DUPLICATE_DIRENT,
N_("Duplicate @E found. "),
PROMPT_CLEAR, 0 },
-
+
/* Non-unique filename found */
{ PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
N_("@E has a non-unique filename.\nRename to %s"),
PROMPT_NULL, 0 },
-
+
/* Duplicate directory entry found */
{ PR_2_REPORT_DUP_DIRENT,
N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
PROMPT_NONE, 0 },
-
+
/* i_blocks_hi should be zero */
{ PR_2_BLOCKS_HI_ZERO,
N_("i_blocks_hi @F %N, @s zero.\n"),
@@ -1256,7 +1256,7 @@ static struct e2fsck_problem problem_table[] = {
/* Unexpected HTREE block */
{ PR_2_UNEXPECTED_HTREE_BLOCK,
N_("Unexpected @b in @h %d (%q).\n"), PROMPT_CLEAR_HTREE, 0 },
-
+
/* Inode found in group where _INODE_UNINIT is set */
{ PR_2_INOREF_BG_INO_UNINIT,
N_("@i %i found in @g %g where _INODE_UNINIT is set. "),
@@ -1273,12 +1273,12 @@ static struct e2fsck_problem problem_table[] = {
{ PR_3_PASS_HEADER,
N_("Pass 3: Checking @d connectivity\n"),
PROMPT_NONE, 0 },
-
+
/* Root inode not allocated */
{ PR_3_NO_ROOT_INODE,
N_("@r not allocated. "),
- PROMPT_ALLOCATE, 0 },
-
+ PROMPT_ALLOCATE, 0 },
+
/* No room in lost+found */
{ PR_3_EXPAND_LF_DIR,
N_("No room in @l @d. "),
@@ -1320,20 +1320,20 @@ static struct e2fsck_problem problem_table[] = {
PROMPT_NONE, 0 },

/* Error in ext2fs_new_block while creating /lost+found */
- { PR_3_ERR_LPF_NEW_BLOCK,
+ { PR_3_ERR_LPF_NEW_BLOCK,
N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
PROMPT_NONE, 0 },
-
+
/* Error in ext2fs_new_inode while creating /lost+found */
{ PR_3_ERR_LPF_NEW_INODE,
N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
PROMPT_NONE, 0 },

- /* Error in ext2fs_new_dir_block while creating /lost+found */
+ /* Error in ext2fs_new_dir_block while creating /lost+found */
{ PR_3_ERR_LPF_NEW_DIR_BLOCK,
N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
PROMPT_NONE, 0 },
-
+
/* Error while writing directory block for /lost+found */
{ PR_3_ERR_LPF_WRITE_BLOCK,
N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
@@ -1349,7 +1349,7 @@ static struct e2fsck_problem problem_table[] = {
N_("Couldn't fix parent of @i %i: %m\n\n"),
PROMPT_NONE, 0 },

- /* Couldn't fix parent directory -- couldn't find it */
+ /* Couldn't fix parent directory -- couldn't find it */
{ PR_3_FIX_PARENT_NOFIND,
N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
PROMPT_NONE, 0 },
@@ -1362,22 +1362,22 @@ static struct e2fsck_problem problem_table[] = {
/* Error creating root directory */
{ PR_3_CREATE_ROOT_ERROR,
N_("Error creating root @d (%s): %m\n"),
- PROMPT_NONE, PR_FATAL },
+ PROMPT_NONE, PR_FATAL },

/* Error creating lost and found directory */
{ PR_3_CREATE_LPF_ERROR,
N_("Error creating /@l @d (%s): %m\n"),
- PROMPT_NONE, PR_FATAL },
+ PROMPT_NONE, PR_FATAL },

/* Root inode is not directory; aborting */
{ PR_3_ROOT_NOT_DIR_ABORT,
N_("@r is not a @d; aborting.\n"),
- PROMPT_NONE, PR_FATAL },
+ PROMPT_NONE, PR_FATAL },

/* Cannot proceed without a root inode. */
{ PR_3_NO_ROOT_INODE_ABORT,
N_("Cannot proceed without a @r.\n"),
- PROMPT_NONE, PR_FATAL },
+ PROMPT_NONE, PR_FATAL },

/* Internal error: couldn't find dir_info */
{ PR_3_NO_DIRINFO,
@@ -1415,19 +1415,19 @@ static struct e2fsck_problem problem_table[] = {
{ PR_3A_OPTIMIZE_DIR,
" %d",
PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
-
- /* Rehashing dir end */
+
+ /* Rehashing dir end */
{ PR_3A_OPTIMIZE_DIR_END,
"\n",
PROMPT_NONE, PR_PREEN_NOHDR },

/* Pass 4 errors */
-
+
/* Pass 4: Checking reference counts */
{ PR_4_PASS_HEADER,
N_("Pass 4: Checking reference counts\n"),
PROMPT_NONE, 0 },
-
+
/* Unattached zero-length inode */
{ PR_4_ZERO_LEN_INODE,
N_("@u @z @i %i. "),
@@ -1451,22 +1451,22 @@ static struct e2fsck_problem problem_table[] = {
PROMPT_NONE, 0 },

/* Pass 5 errors */
-
+
/* Pass 5: Checking group summary information */
{ PR_5_PASS_HEADER,
N_("Pass 5: Checking @g summary information\n"),
PROMPT_NONE, 0 },
-
+
/* Padding at end of inode bitmap is not set. */
{ PR_5_INODE_BMAP_PADDING,
N_("Padding at end of @i @B is not set. "),
PROMPT_FIX, PR_PREEN_OK },
-
+
/* Padding at end of block bitmap is not set. */
{ PR_5_BLOCK_BMAP_PADDING,
N_("Padding at end of @b @B is not set. "),
PROMPT_FIX, PR_PREEN_OK },
-
+
/* Block bitmap differences header */
{ PR_5_BLOCK_BITMAP_HEADER,
N_("@b @B differences: "),
@@ -1476,13 +1476,13 @@ static struct e2fsck_problem problem_table[] = {
{ PR_5_BLOCK_UNUSED,
" -%b",
PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
+
/* Block used, but not marked used in bitmap */
{ PR_5_BLOCK_USED,
" +%b",
PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },

- /* Block bitmap differences end */
+ /* Block bitmap differences end */
{ PR_5_BLOCK_BITMAP_END,
"\n",
PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
@@ -1496,13 +1496,13 @@ static struct e2fsck_problem problem_table[] = {
{ PR_5_INODE_UNUSED,
" -%i",
PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
+
/* Inode used, but not marked used in bitmap */
{ PR_5_INODE_USED,
" +%i",
PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },

- /* Inode bitmap differences end */
+ /* Inode bitmap differences end */
{ PR_5_INODE_BITMAP_END,
"\n",
PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
@@ -1541,7 +1541,7 @@ static struct e2fsck_problem problem_table[] = {
/* Internal error: fudging end of bitmap */
{ PR_5_FUDGE_BITMAP_ERROR,
N_("Internal error: fudging end of bitmap (%N)\n"),
- PROMPT_NONE, PR_FATAL },
+ PROMPT_NONE, PR_FATAL },

/* Error copying in replacement inode bitmap */
{ PR_5_COPY_IBITMAP_ERROR,
@@ -1552,12 +1552,12 @@ static struct e2fsck_problem problem_table[] = {
{ PR_5_COPY_BBITMAP_ERROR,
N_("Error copying in replacement @b @B: %m\n"),
PROMPT_NONE, PR_FATAL },
-
+
/* Block range not used, but marked in bitmap */
{ PR_5_BLOCK_RANGE_UNUSED,
" -(%b--%c)",
PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
+
/* Block range used, but not marked used in bitmap */
{ PR_5_BLOCK_RANGE_USED,
" +(%b--%c)",
@@ -1567,7 +1567,7 @@ static struct e2fsck_problem problem_table[] = {
{ PR_5_INODE_RANGE_UNUSED,
" -(%i--%j)",
PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
+
/* Inode range used, but not marked used in bitmap */
{ PR_5_INODE_RANGE_USED,
" +(%i--%j)",
@@ -1637,7 +1637,7 @@ int end_problem_latch(e2fsck_t ctx, int mask)
struct latch_descr *ldesc;
struct problem_context pctx;
int answer = -1;
-
+
ldesc = find_latch(mask);
if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
clear_problem_context(&pctx);
@@ -1677,7 +1677,7 @@ void clear_problem_context(struct problem_context *ctx)
ctx->group = -1;
}

-static void reconfigure_bool(e2fsck_t ctx, struct e2fsck_problem *ptr,
+static void reconfigure_bool(e2fsck_t ctx, struct e2fsck_problem *ptr,
const char *key, int mask, const char *name)
{
int bool;
@@ -1794,11 +1794,11 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
if (!answer && !(ptr->flags & PR_NO_OK))
ext2fs_unmark_valid(fs);
-
+
if (print_answer)
printf("%s.\n", answer ?
_(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
-
+
}

if ((ptr->prompt == PROMPT_ABORT) && answer)
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 7993203..ab5c4df 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -82,12 +82,12 @@ struct problem_context {
/* Adding UUID to filesystem */
#define PR_0_ADD_UUID 0x000009

-/* Relocate hint */
+/* Relocate hint */
#define PR_0_RELOCATE_HINT 0x00000A

/* Miscellaneous superblock corruption */
#define PR_0_MISC_CORRUPT_SUPER 0x00000B
-
+
/* Error determing physical device size of filesystem */
#define PR_0_GETSIZE_ERROR 0x00000C

@@ -135,13 +135,13 @@ struct problem_context {

/* Clearing orphan inode */
#define PR_0_ORPHAN_CLEAR_INODE 0x000020
-
+
/* Illegal block found in orphaned inode */
#define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM 0x000021

/* Already cleared block found in orphaned inode */
#define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK 0x000022
-
+
/* Illegal orphan inode in superblock */
#define PR_0_ORPHAN_ILLEGAL_HEAD_INODE 0x000023

@@ -268,7 +268,7 @@ struct problem_context {

/* Too many bad blocks in inode */
#define PR_1_TOO_MANY_BAD_BLOCKS 0x010011
-
+
/* Illegal block number in bad block inode */
#define PR_1_BB_ILLEGAL_BLOCK_NUM 0x010012

@@ -277,16 +277,16 @@ struct problem_context {

/* Duplicate or bad blocks in use! */
#define PR_1_DUP_BLOCKS_PREENSTOP 0x010014
-
-/* Bad block used as bad block indirect block */
+
+/* Bad block used as bad block indirect block */
#define PR_1_BBINODE_BAD_METABLOCK 0x010015

/* Inconsistency can't be fixed prompt */
#define PR_1_BBINODE_BAD_METABLOCK_PROMPT 0x010016
-
+
/* Bad primary block */
#define PR_1_BAD_PRIMARY_BLOCK 0x010017
-
+
/* Bad primary block prompt */
#define PR_1_BAD_PRIMARY_BLOCK_PROMPT 0x010018

@@ -302,24 +302,24 @@ struct problem_context {
/* Bad block group descriptors in group */
#define PR_1_BAD_GROUP_DESCRIPTORS 0x01001C

-/* Block claimed for no reason */
+/* Block claimed for no reason */
#define PR_1_PROGERR_CLAIMED_BLOCK 0x01001D

/* Error allocating blocks for relocating metadata */
#define PR_1_RELOC_BLOCK_ALLOCATE 0x01001E
-
+
/* Error allocating block buffer during relocation process */
#define PR_1_RELOC_MEMORY_ALLOCATE 0x01001F
-
-/* Relocating metadata group information from X to Y */
+
+/* Relocating metadata group information from X to Y */
#define PR_1_RELOC_FROM_TO 0x010020
-
+
/* Relocating metatdata group information to X */
#define PR_1_RELOC_TO 0x010021
-
+
/* Block read error during relocation process */
#define PR_1_RELOC_READ_ERR 0x010022
-
+
/* Block write error during relocation process */
#define PR_1_RELOC_WRITE_ERR 0x010023

@@ -331,7 +331,7 @@ struct problem_context {

/* Error allocating icount structure */
#define PR_1_ALLOCATE_ICOUNT 0x010026
-
+
/* Error allocating dbcount */
#define PR_1_ALLOCATE_DBCOUNT 0x010027

@@ -341,10 +341,10 @@ struct problem_context {
/* Error while iterating over blocks */
#define PR_1_BLOCK_ITERATE 0x010029

-/* Error while storing inode count information */
+/* Error while storing inode count information */
#define PR_1_ICOUNT_STORE 0x01002A

-/* Error while storing directory block information */
+/* Error while storing directory block information */
#define PR_1_ADD_DBLOCK 0x01002B

/* Error while reading inode (for clearing) */
@@ -382,7 +382,7 @@ struct problem_context {

/* Error allocating refcount structure */
#define PR_1_ALLOCATE_REFCOUNT 0x010038
-
+
/* Error reading Extended Attribute block */
#define PR_1_READ_EA_BLOCK 0x010039

@@ -395,7 +395,7 @@ struct problem_context {
/* Extended attribute reference count incorrect */
#define PR_1_EXTATTR_REFCOUNT 0x01003C

-/* Error writing Extended Attribute block while fixing refcount */
+/* Error writing Extended Attribute block while fixing refcount */
#define PR_1_EXTATTR_WRITE 0x01003D

/* Multiple EA blocks not supported */
@@ -428,19 +428,19 @@ struct problem_context {
/* INDEX_FL flag set on a non-HTREE filesystem */
#define PR_1_HTREE_SET 0x010047

-/* INDEX_FL flag set on a non-directory */
+/* INDEX_FL flag set on a non-directory */
#define PR_1_HTREE_NODIR 0x010048

-/* Invalid root node in HTREE directory */
+/* Invalid root node in HTREE directory */
#define PR_1_HTREE_BADROOT 0x010049

-/* Unsupported hash version in HTREE directory */
+/* Unsupported hash version in HTREE directory */
#define PR_1_HTREE_HASHV 0x01004A

-/* Incompatible flag in HTREE root node */
+/* Incompatible flag in HTREE root node */
#define PR_1_HTREE_INCOMPAT 0x01004B

-/* HTREE too deep */
+/* HTREE too deep */
#define PR_1_HTREE_DEPTH 0x01004C

/* Bad block has indirect block that conflicts with filesystem block */
@@ -449,7 +449,7 @@ struct problem_context {
/* Resize inode failed */
#define PR_1_RESIZE_INODE_CREATE 0x01004E

-/* inode->i_size is too long */
+/* inode->i_size is too long */
#define PR_1_EXTRA_ISIZE 0x01004F

/* attribute name is too long */
@@ -509,7 +509,7 @@ struct problem_context {

/* Duplicate/bad block(s) end */
#define PR_1B_DUP_BLOCK_END 0x011003
-
+
/* Error while scanning inodes */
#define PR_1B_ISCAN_ERROR 0x011004

@@ -533,13 +533,13 @@ struct problem_context {
/* File has duplicate blocks */
#define PR_1D_DUP_FILE 0x013001

-/* List of files sharing duplicate blocks */
+/* List of files sharing duplicate blocks */
#define PR_1D_DUP_FILE_LIST 0x013002

-/* File sharing blocks with filesystem metadata */
+/* File sharing blocks with filesystem metadata */
#define PR_1D_SHARE_METADATA 0x013003

-/* Report of how many duplicate/bad inodes */
+/* Report of how many duplicate/bad inodes */
#define PR_1D_NUM_DUP_INODES 0x013004

/* Duplicated blocks already reassigned or cloned. */
@@ -553,7 +553,7 @@ struct problem_context {

/* Couldn't clone file (error) */
#define PR_1D_CLONE_ERROR 0x013008
-
+
/*
* Pass 2 errors
*/
@@ -585,10 +585,10 @@ struct problem_context {
/* Directory entry has illegal characters in its name */
#define PR_2_BAD_NAME 0x020008

-/* Missing '.' in directory inode */
+/* Missing '.' in directory inode */
#define PR_2_MISSING_DOT 0x020009

-/* Missing '..' in directory inode */
+/* Missing '..' in directory inode */
#define PR_2_MISSING_DOT_DOT 0x02000A

/* First entry in directory inode doesn't contain '.' */
@@ -611,16 +611,16 @@ struct problem_context {

/* i_fsize should be zero */
#define PR_2_FSIZE_ZERO 0x020011
-
+
/* inode has bad mode */
#define PR_2_BAD_MODE 0x020012

/* directory corrupted */
#define PR_2_DIR_CORRUPTED 0x020013
-
+
/* filename too long */
#define PR_2_FILENAME_LONG 0x020014
-
+
/* Directory inode has a missing block (hole) */
#define PR_2_DIRECTORY_HOLE 0x020015

@@ -641,7 +641,7 @@ struct problem_context {

/* Duplicate '..' entry */
#define PR_2_DUP_DOT_DOT 0x02001B
-
+
/* Internal error: couldn't find dir_info */
#define PR_2_NO_DIRINFO 0x02001C

@@ -796,9 +796,9 @@ struct problem_context {
/* Error in ext2fs_new_inode while creating /lost+found */
#define PR_3_ERR_LPF_NEW_INODE 0x03000B

-/* Error in ext2fs_new_dir_block while creating /lost+found */
+/* Error in ext2fs_new_dir_block while creating /lost+found */
#define PR_3_ERR_LPF_NEW_DIR_BLOCK 0x03000C
-
+
/* Error while writing directory block for /lost+found */
#define PR_3_ERR_LPF_WRITE_BLOCK 0x03000D

@@ -808,12 +808,12 @@ struct problem_context {
/* Couldn't fix parent directory -- error */
#define PR_3_FIX_PARENT_ERR 0x03000F

-/* Couldn't fix parent directory -- couldn't find it */
+/* Couldn't fix parent directory -- couldn't find it */
#define PR_3_FIX_PARENT_NOFIND 0x030010
-
+
/* Error allocating inode bitmap */
#define PR_3_ALLOCATE_IBITMAP_ERROR 0x030011
-
+
/* Error creating root directory */
#define PR_3_CREATE_ROOT_ERROR 0x030012

@@ -842,15 +842,15 @@ struct problem_context {
#define PR_3A_OPTIMIZE_ITER 0x031001

/* Error rehash directory */
-#define PR_3A_OPTIMIZE_DIR_ERR 0x031002
+#define PR_3A_OPTIMIZE_DIR_ERR 0x031002

/* Rehashing dir header */
#define PR_3A_OPTIMIZE_DIR_HEADER 0x031003

/* Rehashing directory %d */
#define PR_3A_OPTIMIZE_DIR 0x031004
-
-/* Rehashing dir end */
+
+/* Rehashing dir end */
#define PR_3A_OPTIMIZE_DIR_END 0x031005

/*
@@ -878,7 +878,7 @@ struct problem_context {

/* Pass 5: Checking group summary information */
#define PR_5_PASS_HEADER 0x050000
-
+
/* Padding at end of inode bitmap is not set. */
#define PR_5_INODE_BMAP_PADDING 0x050001

@@ -890,11 +890,11 @@ struct problem_context {

/* Block not used, but marked in bitmap */
#define PR_5_BLOCK_UNUSED 0x050004
-
+
/* Block used, but not marked used in bitmap */
#define PR_5_BLOCK_USED 0x050005

-/* Block bitmap differences end */
+/* Block bitmap differences end */
#define PR_5_BLOCK_BITMAP_END 0x050006

/* Inode bitmap differences header */
@@ -902,11 +902,11 @@ struct problem_context {

/* Inode not used, but marked in bitmap */
#define PR_5_INODE_UNUSED 0x050008
-
+
/* Inode used, but not marked used in bitmap */
#define PR_5_INODE_USED 0x050009

-/* Inode bitmap differences end */
+/* Inode bitmap differences end */
#define PR_5_INODE_BITMAP_END 0x05000A

/* Free inodes count for group wrong */
@@ -938,7 +938,7 @@ struct problem_context {

/* Block range not used, but marked in bitmap */
#define PR_5_BLOCK_RANGE_UNUSED 0x050014
-
+
/* Block range used, but not marked used in bitmap */
#define PR_5_BLOCK_RANGE_USED 0x050015

@@ -972,6 +972,6 @@ void clear_problem_context(struct problem_context *ctx);

/* message.c */
void print_e2fsck_message(e2fsck_t ctx, const char *msg,
- struct problem_context *pctx, int first,
+ struct problem_context *pctx, int first,
int recurse);

--
1.5.4.1.144.gdfee-dirty


2008-03-31 23:47:00

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH, E2FSPROGS] debugfs: Add support for "set_block_group <bg_num> checksum calc"

This patch was done without un-static'ing ext2fs_group_desc_csum(),
but rather by using the already exported ext2fs_group_desc_csum_set()
function. I also printed the calculated checksum so it would be more
clear what was going on.

- Ted


2008-03-31 23:48:53

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH, E2FSPROGS] ext2fs_set_gdt_csum(): Clean up superblock dirty flag handling

There were three different changes all bundled in the
lib/ext2fs/csum.c patches. I separated them out so it was easier to
understand what was going on.

- Ted

2008-03-31 23:59:58

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH, E2FSPROGS] ext2fs_set_gdt_csum(): Force the last block group to have a valid block bitmap

On Mon, Mar 31, 2008 at 07:36:26PM -0400, Theodore Ts'o wrote:
> From: Andreas Dilger <[email protected]>
>
> Never set the UNINIT_BLOCKS flag for the last group since the kernel
> doesn't handle the case graefully if there is a full set of blocks in
> each blockgroup marked UNINIT_BLOCKS. The kernel should be fixed up,
> but in the meantime this avoids hitting the problem, and is more
> consistent with lazy_bg not marking the last group UNINIT.

This is technically not necessary since we will only set UNINIT_BLOCKS
if the number of free blocks is equal to blocks_per_group minus
superblock_overhead. So there was no danger in the existing codepath.
I think you did this because you were enforcing no UNINIT_BLOCKS in
the last group in e2fsck, instead of just checking to make sure the
free blocks equals the return value from ext2fs_super_and_bgd_loc().

- Ted

2008-04-01 00:00:38

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH, E2FSPROGS] Fix trailing whitespace in e2fsck/problem.[ch]

The patch which you sent me had a half-dozen or so random whitespace
fixups in it, but not of them (which numbered around a hundred or so).

Normally I don't try to fix up white spaces until right before a
release, because it causes merge problems. But it's relatively easy
to fix up merge problems with problem.c, so I fixed them all up here.

- Ted

2008-04-01 00:02:39

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH, E2FSPROGS] ext2fs_set_gdt_csum(): Return an error code on errors instead of void

On Mon, Mar 31, 2008 at 07:36:27PM -0400, Theodore Ts'o wrote:
> From: Andreas Dilger <[email protected]>
>
> Change the function signature so that ext2fs_set_gdt_csum() returns an
> error code.
>
> If the inode bitmap hasn't been loaded return EXT2_ET_NO_INODE_BITMAP.

This was a much safer way of handling the case where the inode bitmap
isn't loaded, instead of just forcing bg_itable_uninit to 0.

- Ted