This patch adds basic flex_bg support to the e2fsprogs-interim branch.

Signed-off-by: Jose R. Santos <jrs@us.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 0b17c48..581e8fe 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -584,8 +584,11 @@
 	for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
 		pctx.group = i;
 
-		first_block = ext2fs_group_first_block(fs, i);
-		last_block = ext2fs_group_last_block(fs, i);
+		if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+					       EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
+			first_block = ext2fs_group_first_block(fs, i);
+			last_block = ext2fs_group_last_block(fs, i);
+		}
 
 		if ((gd->bg_block_bitmap < first_block) ||
 		    (gd->bg_block_bitmap > last_block)) {
diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c
index f111ddd..a9791b4 100644
--- a/lib/e2p/feature.c
+++ b/lib/e2p/feature.c
@@ -67,6 +67,8 @@
 			"extent" },
 	{	E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_64BIT,
 			"64bit" },
+	{       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG,
+			"flex_bg"},
 	{       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP,
 			"mmp" },
 	{	0, 0, 0 },
diff --git a/lib/ext2fs/check_desc.c b/lib/ext2fs/check_desc.c
index 146f9e5..900b179 100644
--- a/lib/ext2fs/check_desc.c
+++ b/lib/ext2fs/check_desc.c
@@ -33,13 +33,16 @@
 {
 	dgrp_t i;
 	blk_t first_block = fs->super->s_first_data_block;
-	blk_t last_block;
+	blk_t last_block = fs->super->s_blocks_count-1;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
 	for (i = 0; i < fs->group_desc_count; i++) {
-		first_block = ext2fs_group_first_block(fs, i);
-		last_block = ext2fs_group_last_block(fs, i);
+		if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+					       EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
+			first_block = ext2fs_group_first_block(fs, i);
+			last_block = ext2fs_group_last_block(fs, i);
+		}
 
 		/*
 		 * Check to make sure block bitmap for group is
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 9218e42..412b49b 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -661,6 +661,7 @@
 #define EXT3_FEATURE_INCOMPAT_EXTENTS		0x0040
 #define EXT4_FEATURE_INCOMPAT_64BIT		0x0080
 #define EXT4_FEATURE_INCOMPAT_MMP		0x0100
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG		0x0200
 
 
 #define EXT2_FEATURE_COMPAT_SUPP	0
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 1d86fa1..b34aff1 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -482,14 +482,16 @@
 					 EXT2_FEATURE_INCOMPAT_META_BG|\
 					 EXT3_FEATURE_INCOMPAT_EXTENTS|\
 					 EXT3_FEATURE_INCOMPAT_RECOVER|\
-					 EXT4_FEATURE_INCOMPAT_MMP)
+					 EXT4_FEATURE_INCOMPAT_MMP|\
+					 EXT4_FEATURE_INCOMPAT_FLEX_BG)
 #else
 #define EXT2_LIB_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE|\
 					 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
 					 EXT2_FEATURE_INCOMPAT_META_BG|\
 					 EXT3_FEATURE_INCOMPAT_EXTENTS|\
 					 EXT3_FEATURE_INCOMPAT_RECOVER|\
-					 EXT4_FEATURE_INCOMPAT_MMP)
+					 EXT4_FEATURE_INCOMPAT_MMP|\
+					 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|\
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 8210c3b..0184af7 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -922,7 +922,8 @@
 	EXT2_FEATURE_INCOMPAT_FILETYPE|		/* Incompat */
 		EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
 		EXT2_FEATURE_INCOMPAT_META_BG|
-		EXT4_FEATURE_INCOMPAT_MMP,
+		EXT4_FEATURE_INCOMPAT_MMP|
+		EXT4_FEATURE_INCOMPAT_FLEX_BG,
 	EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|	/* R/O compat */
 		EXT4_FEATURE_RO_COMPAT_GDT_CSUM
 };
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index fad4812..d37ceb1 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -303,6 +303,7 @@
 {
 	int sparse, old_sparse, filetype, old_filetype;
 	int journal, old_journal, dxdir, old_dxdir, uninit;
+	int flex_bg, old_flex_bg;
 	int mmp, old_mmp;
 	struct ext2_super_block *sb= fs->super;
 	int dir_nlink, old_dir_nlink;
@@ -319,6 +320,8 @@
 		EXT4_FEATURE_RO_COMPAT_DIR_NLINK;
 	old_filetype = sb->s_feature_incompat &
 		EXT2_FEATURE_INCOMPAT_FILETYPE;
+	old_flex_bg = sb->s_feature_incompat &
+		EXT4_FEATURE_INCOMPAT_FLEX_BG;
 	old_journal = sb->s_feature_compat &
 		EXT3_FEATURE_COMPAT_HAS_JOURNAL;
 	old_dxdir = sb->s_feature_compat &
@@ -339,6 +342,8 @@
 		EXT4_FEATURE_RO_COMPAT_DIR_NLINK;
 	filetype = sb->s_feature_incompat &
 		EXT2_FEATURE_INCOMPAT_FILETYPE;
+	flex_bg = sb->s_feature_incompat &
+		EXT4_FEATURE_INCOMPAT_FLEX_BG;
 	journal = sb->s_feature_compat &
 		EXT3_FEATURE_COMPAT_HAS_JOURNAL;
 	dxdir = sb->s_feature_compat &
@@ -407,6 +412,14 @@
 			 "update interval has been set to %d seconds.\n"),
 		       sb->s_mmp_update_interval);
 	}
+	if (!flex_bg && old_flex_bg) {
+		if (ext2fs_check_desc(fs)) {
+			fputs(_("Clearing the flex_bg flag would "
+				"cause the the filesystem to be\n"
+				"inconsistent.\n"), stderr);
+			exit(1);
+		}
+	}
 
 	if (old_mmp && !mmp) {
 		blk_t mmp_block;