From patchwork Mon Jan 19 06:45:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 5654931 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 439C9C058D for ; Mon, 19 Jan 2015 06:51:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 58110202A1 for ; Mon, 19 Jan 2015 06:51:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7188F2028D for ; Mon, 19 Jan 2015 06:51:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751709AbbASGsl (ORCPT ); Mon, 19 Jan 2015 01:48:41 -0500 Received: from cn.fujitsu.com ([59.151.112.132]:52325 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1751468AbbASGrW (ORCPT ); Mon, 19 Jan 2015 01:47:22 -0500 X-IronPort-AV: E=Sophos;i="5.04,848,1406563200"; d="scan'208";a="56253741" Received: from unknown (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 19 Jan 2015 14:43:53 +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 t0J6kilZ022576 for ; Mon, 19 Jan 2015 14:46:44 +0800 Received: from localhost.localdomain (10.167.226.33) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Mon, 19 Jan 2015 14:47:24 +0800 From: Qu Wenruo To: Subject: [PATCH v2 06/10] btrfs-progs: Add better search generation judgment for btrfs-find-root. Date: Mon, 19 Jan 2015 14:45:08 +0800 Message-ID: <1421649912-14539-7-git-send-email-quwenruo@cn.fujitsu.com> X-Mailer: git-send-email 2.2.2 In-Reply-To: <1421649912-14539-1-git-send-email-quwenruo@cn.fujitsu.com> References: <1421649912-14539-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=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 Before the patch, btrfs-find-root will only consider it find a good root if its generation matches generation in superblock and its level is currently found highest level. But that's not correct in 2 ways. 1) Root with decreased level Since tree level can decrease, like subvolume/file deletion. Which will make the new root have higher generation but lower level. 2) Root not updated in latest transaction. If there is some root not updated in latest transaction, its generation will be smaller than the one in superblock, and btrfs-find-root will not find it. This patch will use different generation for different tree to search, solving the above problems. Currently, it only supports generation/level in superblock. Using tree root level/generation if possible will be introduced later. Signed-off-by: Qu Wenruo --- btrfs-find-root.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/btrfs-find-root.c b/btrfs-find-root.c index bc2b344..45c48c2 100644 --- a/btrfs-find-root.c +++ b/btrfs-find-root.c @@ -278,6 +278,61 @@ static int find_root(struct btrfs_root *root) return ret; } +/* + * Get reliable generation and level for given root. + * + * We have two sources of gen/level: superblock and tree root. + * superblock include the following level: + * Root, chunk, log + * and the following generations: + * Root, chunk, uuid + * Other gen/leven can only be read from its btrfs_tree_root if possible. + * + * Currently we only believe things from superblock. + */ +static void get_root_gen_and_level(u64 objectid, struct btrfs_fs_info *fs_info, + u64 *ret_gen, u8 *ret_level) +{ + struct btrfs_super_block *super = fs_info->super_copy; + u64 gen = (u64)-1; + u8 level = (u8)-1; + + switch (objectid) { + case BTRFS_ROOT_TREE_OBJECTID: + level = btrfs_super_root_level(super); + gen = btrfs_super_generation(super); + break; + case BTRFS_CHUNK_TREE_OBJECTID: + level = btrfs_super_chunk_root_level(super); + gen = btrfs_super_chunk_root_generation(super); + printf("Search for chunk root is not supported yet\n"); + break; + case BTRFS_TREE_LOG_OBJECTID: + level = btrfs_super_log_root_level(super); + gen = btrfs_super_log_root_transid(super); + break; + case BTRFS_UUID_TREE_OBJECTID: + gen = btrfs_super_uuid_tree_generation(super); + break; + } + if (gen != (u64)-1) { + printf("Superblock thinks the generation is %llu\n", gen); + if (ret_gen) + *ret_gen = gen; + } else { + printf("Superblock doesn't contain generation info for root %llu\n", + objectid); + } + if (level != (u8)-1) { + printf("Superblock thinks the level is %u\n", level); + if (ret_level) + *ret_level = level; + } else { + printf("Superblock doesn't contain the level info for root %llu\n", + objectid); + } +} + int main(int argc, char **argv) { struct btrfs_root *root; @@ -316,7 +371,8 @@ int main(int argc, char **argv) } if (search_generation == 0) - search_generation = btrfs_super_generation(root->fs_info->super_copy); + get_root_gen_and_level(search_objectid, root->fs_info, + &search_generation, NULL); csum_size = btrfs_super_csum_size(root->fs_info->super_copy); ret = find_root(root);