From patchwork Fri Sep 23 00:24:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 9347233 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 78D9B60B16 for ; Fri, 23 Sep 2016 00:24:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6E05A2AD1F for ; Fri, 23 Sep 2016 00:24:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 62AC52AD21; Fri, 23 Sep 2016 00:24:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DC3842AD20 for ; Fri, 23 Sep 2016 00:24:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965222AbcIWAYh (ORCPT ); Thu, 22 Sep 2016 20:24:37 -0400 Received: from mail-pa0-f49.google.com ([209.85.220.49]:34304 "EHLO mail-pa0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964996AbcIWAYd (ORCPT ); Thu, 22 Sep 2016 20:24:33 -0400 Received: by mail-pa0-f49.google.com with SMTP id wk8so34098491pab.1 for ; Thu, 22 Sep 2016 17:24:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=o78Cj01f00BClRvKJYqXjR3Qj+wY8BfehW2DpAk5eeA=; b=fO6Ehq+wo/wy7WzC8SKSzT3Kei4fGsoWevTBeCShV5h0ps0eopTFKQlebBy0IV8O7O gOtiCPIyFYXJYxcwW9uz3de1Fl+1WzXVChoEqrac55u8/2RtFWDyjBkTaQW3FbvFeSxi ufZLPMbNi+JjGrYMqCqH5Lha2dE671rPTcg80mLB0oLkqIbkNofJHBW4SD7ezaR6MiKc HnG1Jp2HJWt6DXhYhceYhh4f29fcTX2CS2Po8Cse2VRytRK8rGa6DlYzaSQ5NiKutlQe XScO81iGMBSnpBJ4VreODB7AnK4nOiXRC8Dws5HCJYVEt7cdnBTTR/vgx2pLj3GWEoG9 86Iw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=o78Cj01f00BClRvKJYqXjR3Qj+wY8BfehW2DpAk5eeA=; b=fYbUJvBWqT9etVMPhta/+DkJR/OIwTyEmDA/n4RxycBW5d458IvR63H4VGpfcpW3qd /IJHiUGPe6NBgwFyojMx7lVSldaxqaGyiL0HGZUW258VSq7CrWXt3kUfZq2XT8rOp6oh UaoGIt8u5LrUEGQkQqVxjLVjN07u9HKca2EX8NLhJ8qbu58l7RI7TFe7NeavbDX8IMzv 4B0/UBwaAlNohqWQiLJYxwcJWF8Ou0mcpk8PdmSgkMStAy1h6urozGh4mbPiANppBdRE 3XZUTADwi4z61NnoMuxrhVkF+zBvTXZi+jbwGDyri6BAlWwDg/qnDIdn1UoIKvcSI9TQ iYMA== X-Gm-Message-State: AE9vXwNnEGQVMF50SKv6m7z6eh/wdyt8MNvbwaWSdmfy37cdlUBCmP4dVZHt56pXfFyvBhBg X-Received: by 10.66.134.51 with SMTP id ph19mr8009330pab.30.1474590272651; Thu, 22 Sep 2016 17:24:32 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:200::6:58ae]) by smtp.gmail.com with ESMTPSA id i8sm6586299paw.25.2016.09.22.17.24.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Sep 2016 17:24:32 -0700 (PDT) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com, Chandan Rajendra , Anatoly Pugachev Subject: [PATCH v2 3/6] Btrfs: catch invalid free space trees Date: Thu, 22 Sep 2016 17:24:22 -0700 Message-Id: <1381db7b5de30b8ea0d2e87aff26bfdb83b030e7.1474580472.git.osandov@fb.com> X-Mailer: git-send-email 2.10.0 In-Reply-To: <218563982dbe4387c60909eeb0add6914a20f813.1474580472.git.osandov@fb.com> References: <218563982dbe4387c60909eeb0add6914a20f813.1474580472.git.osandov@fb.com> In-Reply-To: References: Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval There are two separate issues that can lead to corrupted free space trees. 1. The free space tree bitmaps had an endianness issue on big-endian systems which is fixed by an earlier patch in this series. 2. btrfs-progs before v4.7.3 modified filesystems without updating the free space tree. To catch both of these issues at once, we need to force the free space tree to be rebuilt. To do so, add a FREE_SPACE_TREE_VALID compat_ro bit. If the bit isn't set, we know that it was either produced by a broken big-endian kernel or may have been corrupted by btrfs-progs. This also provides us with a way to add rudimentary read-write support for the free space tree to btrfs-progs: it can just clear this bit and have the kernel rebuild the free space tree. Cc: stable@vger.kernel.org # 4.5+ Signed-off-by: Omar Sandoval Tested-by: Holger Hoffstätte --- fs/btrfs/ctree.h | 3 ++- fs/btrfs/disk-io.c | 9 +++++++++ fs/btrfs/free-space-tree.c | 2 ++ include/uapi/linux/btrfs.h | 10 +++++++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 33fe035..791e47c 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -251,7 +251,8 @@ struct btrfs_super_block { #define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL #define BTRFS_FEATURE_COMPAT_RO_SUPP \ - (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE) + (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | \ + BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID) #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index c0bfc6c..3dede6d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2566,6 +2566,7 @@ int open_ctree(struct super_block *sb, int num_backups_tried = 0; int backup_index = 0; int max_active; + int clear_free_space_tree = 0; tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL); chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL); @@ -3131,6 +3132,14 @@ retry_root_backup: if (btrfs_test_opt(fs_info, CLEAR_CACHE) && btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { + clear_free_space_tree = 1; + } else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) && + !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) { + btrfs_warn(fs_info, "free space tree is invalid"); + clear_free_space_tree = 1; + } + + if (clear_free_space_tree) { btrfs_info(fs_info, "clearing free space tree"); ret = btrfs_clear_free_space_tree(fs_info); if (ret) { diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c index 8fd85bf..ea605ff 100644 --- a/fs/btrfs/free-space-tree.c +++ b/fs/btrfs/free-space-tree.c @@ -1182,6 +1182,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info) } btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE); + btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID); fs_info->creating_free_space_tree = 0; ret = btrfs_commit_transaction(trans, tree_root); @@ -1250,6 +1251,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) return PTR_ERR(trans); btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE); + btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID); fs_info->free_space_root = NULL; ret = clear_free_space_tree(trans, free_space_root); diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index ac5eacd..549ecf4 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -239,7 +239,15 @@ struct btrfs_ioctl_fs_info_args { * Used by: * struct btrfs_ioctl_feature_flags */ -#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0) +#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0) +/* + * Older kernels on big-endian systems produced broken free space tree bitmaps, + * and btrfs-progs also used to corrupt the free space tree. If this bit is + * clear, then the free space tree cannot be trusted. btrfs-progs can also + * intentionally clear this bit to ask the kernel to rebuild the free space + * tree. + */ +#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID (1ULL << 1) #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)