From patchwork Wed Dec 20 04:57:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Su Yue X-Patchwork-Id: 10124977 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 4ABEB60390 for ; Wed, 20 Dec 2017 04:53:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 42EF028E2D for ; Wed, 20 Dec 2017 04:53:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 37EB4291FC; Wed, 20 Dec 2017 04:53:54 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI 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 D705528E2D for ; Wed, 20 Dec 2017 04:53:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754495AbdLTExw (ORCPT ); Tue, 19 Dec 2017 23:53:52 -0500 Received: from mail.cn.fujitsu.com ([183.91.158.132]:17266 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754429AbdLTExo (ORCPT ); Tue, 19 Dec 2017 23:53:44 -0500 X-IronPort-AV: E=Sophos;i="5.43,368,1503331200"; d="scan'208";a="31879393" Received: from localhost (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 20 Dec 2017 12:53:41 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (unknown [10.167.33.83]) by cn.fujitsu.com (Postfix) with ESMTP id 1008D48AE9E3; Wed, 20 Dec 2017 12:53:41 +0800 (CST) Received: from archlinux.g08.fujitsu.local (10.167.226.31) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.361.1; Wed, 20 Dec 2017 12:53:39 +0800 From: Su Yue To: CC: , Subject: [PATCH v2 06/17] btrfs-progs: lowmem check: introduce force_cow_in_new_chunk() Date: Wed, 20 Dec 2017 12:57:20 +0800 Message-ID: <20171220045731.19343-7-suy.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171220045731.19343-1-suy.fnst@cn.fujitsu.com> References: <20171220045731.19343-1-suy.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.31] X-yoursite-MailScanner-ID: 1008D48AE9E3.A726C X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: suy.fnst@cn.fujitsu.com 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 Introduce create_chunk_and_block_block_group() to allocate new chunk and corresponding block group. The new function force_cow_in_new_chunk() first allocates new chunk and records its start. Then it modifies all metadata block groups cached and full. Finally it marks the new block group uncached and unfree. In the next CoW, extents states will be updated automatically by cache_block_group(). Suggested-by: Qu Wenruo Signed-off-by: Su Yue --- cmds-check.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/cmds-check.c b/cmds-check.c index d98d4bda7357..311c8a9f45e8 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -10911,6 +10911,86 @@ out: return ret; } +static int create_chunk_and_block_group(struct btrfs_fs_info *fs_info, + u64 flags, u64 *start, u64 *nbytes) +{ + struct btrfs_trans_handle *trans; + struct btrfs_root *root = fs_info->extent_root; + int ret; + + if ((flags & BTRFS_BLOCK_GROUP_TYPE_MASK) == 0) + return -EINVAL; + + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + error("error starting transaction %s", strerror(-ret)); + return ret; + } + ret = btrfs_alloc_chunk(trans, fs_info, start, nbytes, flags); + if (ret) { + error("fail to allocate new chunk %s", strerror(-ret)); + goto out; + } + ret = btrfs_make_block_group(trans, fs_info, 0, flags, + BTRFS_FIRST_CHUNK_TREE_OBJECTID, *start, *nbytes); + if (ret) { + error("fail to make block group for chunk %llu %llu %s", + *start, *nbytes, strerror(-ret)); + goto out; + } +out: + btrfs_commit_transaction(trans, root); + return ret; +} + +static int force_cow_in_new_chunk(struct btrfs_fs_info *fs_info) +{ + struct btrfs_block_group_cache *bg; + u64 start; + u64 nbytes; + u64 alloc_profile; + u64 flags; + int ret; + + alloc_profile = (fs_info->avail_metadata_alloc_bits & + fs_info->metadata_alloc_profile); + flags = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; + if (btrfs_fs_incompat(fs_info, MIXED_GROUPS)) + flags |= BTRFS_BLOCK_GROUP_DATA; + + ret = create_chunk_and_block_group(fs_info, flags, &start, &nbytes); + if (!ret) + printf("Create new chunk %llu %llu\n", start, nbytes); + else + goto err; + + flags = BTRFS_BLOCK_GROUP_METADATA; + /* Mark all metadata block groups cached and full in free space*/ + ret = modify_block_groups_cache(fs_info, flags, 1); + if (ret) + goto clear_bg_cache; + + bg = btrfs_lookup_block_group(fs_info, start); + if (!bg) { + ret = -ENOENT; + error("fail to look up block group %llu %llu", start, nbytes); + goto clear_bg_cache; + } + + /* Clear block group cache just allocated */ + ret = modify_block_group_cache(fs_info, bg, 0); + if (ret) + goto clear_bg_cache; + + return 0; + +clear_bg_cache: + modify_block_groups_cache(fs_info, flags, 0); +err: + return ret; +} + static int check_extent_refs(struct btrfs_root *root, struct cache_tree *extent_cache) {