Patchwork [08/37] tune2fs: Add inode checksum support

login
register
mail settings
Submitter Darrick J. Wong
Date Sept. 1, 2011, 12:36 a.m.
Message ID <20110901003602.1176.24747.stgit@elm3c44.beaverton.ibm.com>
Download mbox | patch
Permalink /patch/112756/
State Changes Requested
Headers show

Comments

Darrick J. Wong - Sept. 1, 2011, 12:36 a.m.
This patch adds to tune2fs the ability to toggle the metadata checksum rocompat
feature flag, which will rewrite the inode table with checksums.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
---
 misc/tune2fs.c |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 75 insertions(+), 2 deletions(-)



--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index 82833ad..283ad1d 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -82,6 +82,7 @@  static int stride_set, stripe_width_set;
 static char *extended_cmd;
 static unsigned long new_inode_size;
 static char *ext_mount_opts;
+static int rewrite_checksums;
 
 int journal_size, journal_flags;
 char *journal_device;
@@ -131,7 +132,8 @@  static __u32 ok_features[3] = {
 		EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
 		EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
 		EXT4_FEATURE_RO_COMPAT_GDT_CSUM |
-		EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
+		EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER |
+		EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
 };
 
 static __u32 clear_ok_features[3] = {
@@ -147,7 +149,8 @@  static __u32 clear_ok_features[3] = {
 		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
 		EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
 		EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
-		EXT4_FEATURE_RO_COMPAT_GDT_CSUM
+		EXT4_FEATURE_RO_COMPAT_GDT_CSUM |
+		EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
 };
 
 /*
@@ -330,6 +333,16 @@  static void update_mntopts(ext2_filsys fs, char *mntopts)
 	ext2fs_mark_super_dirty(fs);
 }
 
+static int check_fsck_needed(ext2_filsys fs)
+{
+	if (fs->super->s_state & EXT2_VALID_FS)
+		return 0;
+	printf("\n%s\n", _(please_fsck));
+	if (mount_flags & EXT2_MF_READONLY)
+		printf(_("(and reboot afterwards!)\n"));
+	return 1;
+}
+
 static void request_fsck_afterwards(ext2_filsys fs)
 {
 	static int requested = 0;
@@ -343,6 +356,49 @@  static void request_fsck_afterwards(ext2_filsys fs)
 }
 
 /*
+ * Forcibly set checksums in all inodes.
+ */
+static void rewrite_inodes(ext2_filsys fs)
+{
+	struct ext2_inode_large inode;
+	ext2_inode_scan	scan;
+	errcode_t	retval;
+	ext2_ino_t	ino;
+
+	if (fs->super->s_creator_os != EXT2_OS_LINUX)
+		return;
+
+	retval = ext2fs_open_inode_scan(fs, 0, &scan);
+	if (retval) {
+		com_err("set_csum", retval, "While opening inode scan");
+		exit(1);
+	}
+
+	do {
+		retval = ext2fs_get_next_inode(scan, &ino, &inode);
+		if (retval) {
+			com_err("set_csum", retval, "while getting next inode");
+			exit(1);
+		}
+		if (!ino)
+			break;
+		retval = ext2fs_write_inode(fs, ino, &inode);
+		if (retval) {
+			com_err("set_csum", retval, "while writing inode");
+			exit(1);
+		}
+	} while (ino);
+	ext2fs_close_inode_scan(scan);
+}
+
+static void rewrite_metadata_checksums(ext2_filsys fs)
+{
+	fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+	rewrite_inodes(fs);
+	fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
+}
+
+/*
  * Update the feature set as provided by the user.
  */
 static void update_feature_set(ext2_filsys fs, char *features)
@@ -448,6 +504,20 @@  static void update_feature_set(ext2_filsys fs, char *features)
 	}
 
 	if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
+		       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+		if (check_fsck_needed(fs))
+			exit(1);
+		rewrite_checksums = 1;
+	}
+
+	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
+			EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
+		if (check_fsck_needed(fs))
+			exit(1);
+		rewrite_checksums = 1;
+	}
+
+	if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
 		       EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
 		for (i = 0; i < fs->group_desc_count; i++) {
 			gd = ext2fs_group_desc(fs, fs->group_desc, i);
@@ -1824,7 +1894,10 @@  retry_open:
 			fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
 		}
 		ext2fs_mark_super_dirty(fs);
+		rewrite_checksums = 1;
 	}
+	if (rewrite_checksums)
+		rewrite_metadata_checksums(fs);
 	if (I_flag) {
 		if (mount_flags & EXT2_MF_MOUNTED) {
 			fputs(_("The inode size may only be "