mke2fs,tune2fs: Enable huge_file, dir_nlink, and extra_isize features

Also change mke2fs.conf to enable huge_file,dir_nlink,extra_isize, and
uninit_bg by default for ext4 filesystems, and enable extra_isize in
the library as well.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index ebad54e..04a95a2 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -535,6 +535,7 @@
 					 EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
 					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
+					 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
 					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
 
 /*
@@ -542,7 +543,7 @@
  * to ext2fs_openfs()
  */
 #define EXT2_LIB_SOFTSUPP_INCOMPAT	(0)
-#define EXT2_LIB_SOFTSUPP_RO_COMPAT	(EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
+#define EXT2_LIB_SOFTSUPP_RO_COMPAT	(0)
 
 /*
  * function prototypes
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 960f67b..7ee3dee 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -839,6 +839,9 @@
 		EXT4_FEATURE_INCOMPAT_FLEX_BG,
 	/* R/O compat */
 	EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
+		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
+		EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
+		EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
 		EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|
 		EXT4_FEATURE_RO_COMPAT_GDT_CSUM
 };
diff --git a/misc/mke2fs.conf b/misc/mke2fs.conf
index 2eb4352..3795b1e 100644
--- a/misc/mke2fs.conf
+++ b/misc/mke2fs.conf
@@ -9,11 +9,11 @@
 		features = has_journal
 	}
 	ext4 = {
-		features = has_journal,extents,flex_bg
+		features = has_journal,extents,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize
 		inode_size = 256
 	}
 	ext4dev = {
-		features = has_journal,extents,flex_bg
+		features = has_journal,extents,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize
 		inode_size = 256
 		options = test_fs=1
 	}
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index b7d6250..8eb7451 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -57,16 +57,6 @@
 #include "../version.h"
 #include "nls-enable.h"
 
-/* 
- * Tune2fs supports these features in addition to the standard features.
- */
-#define EXT2_TUNE2FS_INCOMPAT	(EXT3_FEATURE_INCOMPAT_EXTENTS)
-#define EXT2_TUNE2FS_RO_COMPAT	(EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
-				 EXT4_FEATURE_RO_COMPAT_GDT_CSUM|	\
-				 EXT4_FEATURE_RO_COMPAT_DIR_NLINK|	\
-				 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
-
-
 const char * program_name = "tune2fs";
 char * device_name;
 char * new_label, *new_last_mounted, *new_UUID;
@@ -131,6 +121,9 @@
 		EXT4_FEATURE_INCOMPAT_FLEX_BG,
 	/* R/O compat */
 	EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
+		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
+		EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
+		EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
 		EXT4_FEATURE_RO_COMPAT_GDT_CSUM |
 		EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
 };
@@ -145,6 +138,9 @@
 		EXT4_FEATURE_INCOMPAT_FLEX_BG,
 	/* R/O compat */
 	EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
+		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
+		EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
+		EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
 		EXT4_FEATURE_RO_COMPAT_GDT_CSUM
 };
 
@@ -369,7 +365,7 @@
 	if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
 		if ((mount_flags & EXT2_MF_MOUNTED) &&
 		    !(mount_flags & EXT2_MF_READONLY)) {
-			fputs(_("The has_journal flag may only be "
+			fputs(_("The has_journal feature may only be "
 				"cleared when the filesystem is\n"
 				"unmounted or mounted "
 				"read-only.\n"), stderr);
@@ -418,6 +414,18 @@
 		}
 	}
 
+	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
+			    EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
+		if ((mount_flags & EXT2_MF_MOUNTED) &&
+		    !(mount_flags & EXT2_MF_READONLY)) {
+			fputs(_("The huge_file feature may only be "
+				"cleared when the filesystem is\n"
+				"unmounted or mounted "
+				"read-only.\n"), stderr);
+			exit(1);
+		}
+	}
+
 	if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
 	    (sb->s_feature_compat || sb->s_feature_ro_compat ||
 	     sb->s_feature_incompat))
@@ -427,6 +435,8 @@
 			    EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
 	    FEATURE_CHANGED(E2P_FEATURE_RO_INCOMPAT,
 			    EXT4_FEATURE_RO_COMPAT_GDT_CSUM) ||
+	    FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
+			EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
 	    FEATURE_CHANGED(E2P_FEATURE_INCOMPAT,
 			    EXT2_FEATURE_INCOMPAT_FILETYPE) ||
 	    FEATURE_CHANGED(E2P_FEATURE_COMPAT,
@@ -435,6 +445,8 @@
 			EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
 		sb->s_state &= ~EXT2_VALID_FS;
 		printf("\n%s\n", _(please_fsck));
+		if (mount_flags & EXT2_MF_READONLY)
+			printf(_("(and reboot afterwards!)\n"));
 	}
 
 	if ((old_features[E2P_FEATURE_COMPAT] != sb->s_feature_compat) ||
@@ -535,7 +547,7 @@
 			argv[1]);
 		exit(1);
 	}
-	open_flag = EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_JOURNAL_DEV_OK;
+	open_flag = EXT2_FLAG_JOURNAL_DEV_OK;
 	if (argc == 3) {
 		open_flag |= EXT2_FLAG_RW;
 		L_flag = 1;
@@ -581,7 +593,7 @@
 	struct group * gr;
 	struct passwd * pw;
 
-	open_flag = EXT2_FLAG_SOFTSUPP_FEATURES;
+	open_flag = 0;
 
 	printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
 	while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:E:I:J:L:M:O:T:U:")) != EOF)
@@ -841,12 +853,6 @@
 	exit(0);
 }
 
-/*
- * Note!  If any extended options are incompatible with the
- * intersection of the SOFTSUPP features and those features explicitly
- * enabled for tune2fs, there needs to be an explicit test for them
- * here.
- */
 static void parse_extended_opts(ext2_filsys fs, const char *opts)
 {
 	char	*buf, *token, *next, *p, *arg;
@@ -1443,13 +1449,7 @@
 	}
 	sb = fs->super;
 	fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
-	if ((sb->s_feature_incompat & !EXT2_TUNE2FS_INCOMPAT) ||
-	    (sb->s_feature_ro_compat & !EXT2_TUNE2FS_RO_COMPAT)) {
-		fprintf(stderr, 
-			_("Filesystem %s has unsupported features enabled.\n"),
-			device_name);
-		exit(1);
-	}
+
 	if (print_label) {
 		/* For e2label emulation */
 		printf("%.*s\n", (int) sizeof(sb->s_volume_name),
@@ -1457,6 +1457,7 @@
 		remove_error_table(&et_ext2_error_table);
 		exit(0);
 	}
+
 	retval = ext2fs_check_if_mounted(device_name, &mount_flags);
 	if (retval) {
 		com_err("ext2fs_check_if_mount", retval,