From patchwork Tue Mar 6 23:58:05 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 145065 X-Patchwork-Delegate: tytso@mit.edu Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id D82D2B6EF1 for ; Wed, 7 Mar 2012 10:58:17 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932718Ab2CFX6P (ORCPT ); Tue, 6 Mar 2012 18:58:15 -0500 Received: from e39.co.us.ibm.com ([32.97.110.160]:34557 "EHLO e39.co.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932720Ab2CFX6O (ORCPT ); Tue, 6 Mar 2012 18:58:14 -0500 Received: from /spool/local by e39.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 6 Mar 2012 16:58:14 -0700 Received: from d01dlp03.pok.ibm.com (9.56.224.17) by e39.co.us.ibm.com (192.168.1.139) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 6 Mar 2012 16:58:12 -0700 Received: from d01relay01.pok.ibm.com (d01relay01.pok.ibm.com [9.56.227.233]) by d01dlp03.pok.ibm.com (Postfix) with ESMTP id 08452C90058 for ; Tue, 6 Mar 2012 18:58:11 -0500 (EST) Received: from d01av03.pok.ibm.com (d01av03.pok.ibm.com [9.56.224.217]) by d01relay01.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q26NwBQX207284 for ; Tue, 6 Mar 2012 18:58:11 -0500 Received: from d01av03.pok.ibm.com (loopback [127.0.0.1]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q26Nw9OT010378 for ; Tue, 6 Mar 2012 20:58:11 -0300 Received: from elm3b70.beaverton.ibm.com (elm3b70.beaverton.ibm.com [9.47.67.70]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q26Nw8lw010343; Tue, 6 Mar 2012 20:58:08 -0300 Subject: [PATCH 07/54] tune2fs: Add inode checksum support To: Andreas Dilger , Theodore Tso , "Darrick J. Wong" From: "Darrick J. Wong" Cc: Sunil Mushran , Amir Goldstein , Andi Kleen , Mingming Cao , Joel Becker , linux-ext4@vger.kernel.org, Coly Li Date: Tue, 06 Mar 2012 15:58:05 -0800 Message-ID: <20120306235805.11945.49889.stgit@elm3b70.beaverton.ibm.com> In-Reply-To: <20120306235720.11945.30629.stgit@elm3b70.beaverton.ibm.com> References: <20120306235720.11945.30629.stgit@elm3b70.beaverton.ibm.com> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12030623-4242-0000-0000-000000FA226F Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org This patch adds to tune2fs the ability to toggle the metadata checksum rocompat feature flag, which will rewrite the inode table with checksums. Disallow changing the UUID while the fs is mounted, because rewriting the metadata objects is racy. Signed-off-by: Darrick J. Wong --- misc/tune2fs.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 106 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 diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 74a0489..cb1aff3 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -91,6 +91,7 @@ static char *extended_cmd; static unsigned long new_inode_size; static char *ext_mount_opts; static int usrquota, grpquota; +static int rewrite_checksums; int journal_size, journal_flags; char *journal_device; @@ -142,7 +143,8 @@ static __u32 ok_features[3] = { EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE| EXT4_FEATURE_RO_COMPAT_GDT_CSUM | EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER | - EXT4_FEATURE_RO_COMPAT_QUOTA + EXT4_FEATURE_RO_COMPAT_QUOTA | + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM }; static __u32 clear_ok_features[3] = { @@ -160,7 +162,8 @@ static __u32 clear_ok_features[3] = { EXT4_FEATURE_RO_COMPAT_DIR_NLINK| EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE| EXT4_FEATURE_RO_COMPAT_GDT_CSUM | - EXT4_FEATURE_RO_COMPAT_QUOTA + EXT4_FEATURE_RO_COMPAT_QUOTA | + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM }; /* @@ -351,6 +354,16 @@ static int update_mntopts(ext2_filsys fs, char *mntopts) return 0; } +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; @@ -364,6 +377,60 @@ static void request_fsck_afterwards(ext2_filsys fs) } /* + * Forcibly set checksums in all inodes. + */ +static void rewrite_inodes(ext2_filsys fs) +{ + int length = EXT2_INODE_SIZE(fs->super); + struct ext2_inode *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); + } + + retval = ext2fs_get_mem(length, &inode); + if (retval) { + com_err("set_csum", retval, "while allocating memory"); + exit(1); + } + + do { + retval = ext2fs_get_next_inode_full(scan, &ino, inode, length); + if (retval) { + com_err("set_csum", retval, "while getting next inode"); + exit(1); + } + if (!ino) + break; + + retval = ext2fs_write_inode_full(fs, ino, inode, length); + if (retval) { + com_err("set_csum", retval, "while writing inode"); + exit(1); + } + } while (ino); + + ext2fs_free_mem(&inode); + ext2fs_close_inode_scan(scan); +} + +static void rewrite_metadata_checksums(ext2_filsys fs) +{ + fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS; + ext2fs_init_csum_seed(fs); + rewrite_inodes(fs); + fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS; +} + +/* * Update the feature set as provided by the user. */ static int update_feature_set(ext2_filsys fs, char *features) @@ -536,6 +603,20 @@ mmp_error: } 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); @@ -2128,6 +2209,23 @@ retry_open: int set_csum = 0; dgrp_t i; + if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { + /* + * Changing the UUID requires rewriting all metadata, + * which can race with a mounted fs. Don't allow that. + */ + if (mount_flags & EXT2_MF_MOUNTED) { + fputs(_("The UUID may only be " + "changed when the filesystem is " + "unmounted.\n"), stderr); + exit(1); + } + + if (check_fsck_needed(fs)) + exit(1); + } + if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { /* @@ -2153,13 +2251,19 @@ retry_open: rc = 1; goto closefs; } + ext2fs_init_csum_seed(fs); if (set_csum) { for (i = 0; i < fs->group_desc_count; i++) ext2fs_group_desc_csum_set(fs, i); fs->flags &= ~EXT2_FLAG_SUPER_ONLY; } ext2fs_mark_super_dirty(fs); + if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) + 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 "