From patchwork Tue Oct 28 06:42:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 5170711 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D6C43C11AC for ; Tue, 28 Oct 2014 06:42:52 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E00F72024D for ; Tue, 28 Oct 2014 06:42:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D6C2420131 for ; Tue, 28 Oct 2014 06:42:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760020AbaJ1Gml (ORCPT ); Tue, 28 Oct 2014 02:42:41 -0400 Received: from cn.fujitsu.com ([59.151.112.132]:8534 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1756631AbaJ1Gmk (ORCPT ); Tue, 28 Oct 2014 02:42:40 -0400 X-IronPort-AV: E=Sophos;i="5.04,801,1406563200"; d="scan'208";a="42455220" Received: from localhost (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 28 Oct 2014 14:39:03 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (localhost.localdomain [127.0.0.1]) by edo.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id s9S6g4VD026595 for ; Tue, 28 Oct 2014 14:42:04 +0800 Received: from adam-work.localdomain (10.167.226.33) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Tue, 28 Oct 2014 14:42:15 +0800 From: Qu Wenruo To: Subject: [PATCH 2/2] btrfs-progs: corrupt-block: Add node corruption without transaction. Date: Tue, 28 Oct 2014 14:42:08 +0800 Message-ID: <1414478528-4665-2-git-send-email-quwenruo@cn.fujitsu.com> X-Mailer: git-send-email 2.1.2 In-Reply-To: <1414478528-4665-1-git-send-email-quwenruo@cn.fujitsu.com> References: <1414478528-4665-1-git-send-email-quwenruo@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.33] Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 Just like leaf corruption without using transaction, this patch will corrupt node, doing much more damage to the filesystem, for later leaf/node repair patches. Signed-off-by: Qu Wenruo --- btrfs-corrupt-block.c | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c index 80eec5b..94c3f12 100644 --- a/btrfs-corrupt-block.c +++ b/btrfs-corrupt-block.c @@ -112,7 +112,8 @@ static void print_usage(void) "to corrupt and a root+key for the item)\n"); fprintf(stderr, "\t-D Corrupt a dir item, must specify key and field\n"); fprintf(stderr, "\t-g Randomly corrupt a leaf in the given tree without changing the csum\n"); - fprintf(stderr, "\t\t can combine with -l to corrupt a given leaf\n"); + fprintf(stderr, "\t-G Randomly corrupt a node in the given tree without changing the csum\n"); + fprintf(stderr, "\t\t '-g/G'can combine with -l to corrupt a given leaf/node\n"); exit(1); } @@ -977,7 +978,8 @@ out: } -struct extent_buffer *find_random_leaf(struct btrfs_root *root, u64 tree_num) +struct extent_buffer *find_random_eb(struct btrfs_root *root, u64 tree_num, + int leaf) { struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_root *tree_root = fs_info->tree_root; @@ -985,6 +987,7 @@ struct extent_buffer *find_random_leaf(struct btrfs_root *root, u64 tree_num) struct btrfs_key key; struct btrfs_key found_key; struct btrfs_path *path = NULL; + int target_level = -1; int ret = 0; path = btrfs_alloc_path(); @@ -1026,10 +1029,22 @@ struct extent_buffer *find_random_leaf(struct btrfs_root *root, u64 tree_num) goto out; } } + if (!leaf) { + if (btrfs_header_level(eb) == 0) { + fprintf(stderr, "There is no node for the tree %llu\n", + tree_num); + ret = -ENOENT; + goto out; + } + target_level = 1 + rand() % btrfs_header_level(eb); + } while (btrfs_header_level(eb) > 0) { struct extent_buffer *next; int slot = rand() % btrfs_header_nritems(eb); + if (!leaf && btrfs_header_level(eb) == target_level) + goto found; + next = read_tree_block(tree_root, btrfs_node_blockptr(eb, slot), tree_root->nodesize, 0); @@ -1040,6 +1055,7 @@ struct extent_buffer *find_random_leaf(struct btrfs_root *root, u64 tree_num) free_extent_buffer(eb); eb = next; } +found: btrfs_free_path(path); return eb; out: @@ -1087,6 +1103,7 @@ int main(int ac, char **av) int chunk_tree = 0; int corrupt_item = 0; int corrupt_di = 0; + int corrupt_leaf_notrans = 1; u64 metadata_block = 0; u64 inode = 0; u64 file_extent = (u64)-1; @@ -1099,7 +1116,7 @@ int main(int ac, char **av) while(1) { int c; - c = getopt_long(ac, av, "l:c:b:eEkuUi:f:x:m:K:IDg:", long_options, + c = getopt_long(ac, av, "l:c:b:eEkuUi:f:x:m:K:IDg:G:", long_options, &option_index); if (c < 0) break; @@ -1157,6 +1174,11 @@ int main(int ac, char **av) corrupt_item = 1; break; case 'g': + corrupt_leaf_notrans = 1; + tree_num = arg_strtou64(optarg); + break; + case 'G': + corrupt_leaf_notrans = 0; tree_num = arg_strtou64(optarg); break; default: @@ -1179,13 +1201,15 @@ int main(int ac, char **av) } if (tree_num) { if (logical == (u64)-1) { - eb = find_random_leaf(root, tree_num); + eb = find_random_eb(root, tree_num, + corrupt_leaf_notrans); if (IS_ERR(eb) || eb == NULL) { if (eb == NULL) ret = -ENOENT; else ret = PTR_ERR(eb); - fprintf(stderr, "Fail to find a leaf of given tree\n"); + fprintf(stderr, "Fail to find a %s of given tree\n", + corrupt_leaf_notrans ? "leaf" : "node"); goto out_close; } } else { @@ -1195,18 +1219,21 @@ int main(int ac, char **av) ret = -ENOENT; else ret = PTR_ERR(eb); - fprintf(stderr, "Fail to read the given leaf at bytenr: %llu\n", + fprintf(stderr, "Fail to read the given %s at bytenr: %llu\n", + corrupt_leaf_notrans ? "leaf" : "node", logical); goto out_close; } } ret = corrupt_eb_notrans(root, eb, bytes); if (ret < 0) - fprintf(stderr, "fail to corrupt leaf at %llu: %s\n", + fprintf(stderr, "fail to corrupt %s at %llu: %s\n", + corrupt_leaf_notrans ? "leaf" : "node", eb->start, strerror(-ret)); else - printf("Corrupted %llu bytes of the leaf at logical: %llu\n", - bytes, eb->start); + printf("Corrupted %llu bytes of the %s at logical: %llu\n", + bytes, corrupt_leaf_notrans ? "leaf" : "node", + eb->start); free_extent_buffer(eb); goto out_close; }