From patchwork Tue Feb 25 11:48:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Shilong X-Patchwork-Id: 3716021 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CA5BF9F2F7 for ; Tue, 25 Feb 2014 11:51:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E8231201CD for ; Tue, 25 Feb 2014 11:51:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C39CD201C7 for ; Tue, 25 Feb 2014 11:51:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752869AbaBYLu6 (ORCPT ); Tue, 25 Feb 2014 06:50:58 -0500 Received: from cn.fujitsu.com ([222.73.24.84]:39303 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1750999AbaBYLu4 (ORCPT ); Tue, 25 Feb 2014 06:50:56 -0500 X-IronPort-AV: E=Sophos;i="4.97,539,1389715200"; d="scan'208";a="9600712" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 25 Feb 2014 19:46:59 +0800 Received: from fnstmail02.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id s1PBon6q016049 for ; Tue, 25 Feb 2014 19:50:50 +0800 Received: from wangs.fnst.cn.fujitsu.com ([10.167.226.104]) by fnstmail02.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.3) with ESMTP id 2014022519482983-208059 ; Tue, 25 Feb 2014 19:48:29 +0800 From: Wang Shilong To: linux-btrfs@vger.kernel.org Subject: [PATCH 1/2] Btrfs-progs: fsck: avoid overwritting existed space when initting csum tree Date: Tue, 25 Feb 2014 19:48:56 +0800 Message-Id: <1393328937-26171-1-git-send-email-wangsl.fnst@cn.fujitsu.com> X-Mailer: git-send-email 1.9.0 X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2014/02/25 19:48:29, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2014/02/25 19:48:30, Serialize complete at 2014/02/25 19:48:30 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Steps to reproduce: # mkfs.btrfs -f /dev/sda9 # btrfs check /dev/sda9 --init-extent-tree --init-csum-tree # btrfs check /dev/sda9 During reinitting extent tree, we will pin all metadata blocks to avoid overwritting existing metadata space. However, those space will be unpinned after committing transaction. If we try to reinit csum tree after reiniting extent tree, we may overwrite existing space. Fix this problem by making reinit extent tree and csum tree in same transaction. Signed-off-by: Wang Shilong --- cmds-check.c | 74 ++++++++++++++++++++++++++---------------------------------- 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/cmds-check.c b/cmds-check.c index 253569f..4cdeac8 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -6179,9 +6179,9 @@ out: return ret; } -static int reinit_extent_tree(struct btrfs_fs_info *fs_info) +static int reinit_extent_tree(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info) { - struct btrfs_trans_handle *trans; u64 start = 0; int ret; @@ -6200,12 +6200,6 @@ static int reinit_extent_tree(struct btrfs_fs_info *fs_info) return -EINVAL; } - trans = btrfs_start_transaction(fs_info->extent_root, 1); - if (IS_ERR(trans)) { - fprintf(stderr, "Error starting transaction\n"); - return PTR_ERR(trans); - } - /* * first we need to walk all of the trees except the extent tree and pin * down the bytes that are in use so we don't overwrite any existing @@ -6268,11 +6262,7 @@ static int reinit_extent_tree(struct btrfs_fs_info *fs_info) btrfs_extent_post_op(trans, fs_info->extent_root); } - /* - * Ok now we commit and run the normal fsck, which will add extent - * entries for all of the items it finds. - */ - return btrfs_commit_transaction(trans, fs_info->extent_root); + return 0; } static int recow_extent_buffer(struct btrfs_root *root, struct extent_buffer *eb) @@ -6475,47 +6465,47 @@ int cmd_check(int argc, char **argv) goto close_out; } - if (init_extent_tree) { - printf("Creating a new extent tree\n"); - ret = reinit_extent_tree(info); - if (ret) - goto close_out; - } - if (!extent_buffer_uptodate(info->extent_root->node)) { - fprintf(stderr, "Critical roots corrupted, unable to fsck the FS\n"); - ret = -EIO; - goto close_out; - } - - fprintf(stderr, "checking extents\n"); - if (init_csum_tree) { + if (init_extent_tree || init_csum_tree) { struct btrfs_trans_handle *trans; - fprintf(stderr, "Reinit crc root\n"); - trans = btrfs_start_transaction(info->csum_root, 1); + trans = btrfs_start_transaction(info->extent_root, 0); if (IS_ERR(trans)) { fprintf(stderr, "Error starting transaction\n"); ret = PTR_ERR(trans); goto close_out; } - ret = btrfs_fsck_reinit_root(trans, info->csum_root, 0); - if (ret) { - fprintf(stderr, "crc root initialization failed\n"); - ret = -EIO; - goto close_out; + if (init_extent_tree) { + printf("Creating a new extent tree\n"); + ret = reinit_extent_tree(trans, info); + if (ret) + goto close_out; } - ret = btrfs_commit_transaction(trans, info->csum_root); - if (ret) - exit(1); - - ret = check_chunks_and_extents(root); + if (init_csum_tree) { + fprintf(stderr, "Reinit crc root\n"); + ret = btrfs_fsck_reinit_root(trans, info->csum_root, 0); + if (ret) { + fprintf(stderr, "crc root initialization failed\n"); + ret = -EIO; + goto close_out; + } + } + /* + * Ok now we commit and run the normal fsck, which will add + * extent entries for all of the items it finds. + */ + ret = btrfs_commit_transaction(trans, info->extent_root); if (ret) - fprintf(stderr, - "Errors found in extent allocation tree or chunk allocation\n"); - goto out; + goto close_out; + } + if (!extent_buffer_uptodate(info->extent_root->node)) { + fprintf(stderr, "Critical roots corrupted, unable to fsck the FS\n"); + ret = -EIO; + goto close_out; } + + fprintf(stderr, "checking extents\n"); ret = check_chunks_and_extents(root); if (ret) fprintf(stderr, "Errors found in extent allocation tree or chunk allocation\n");