From patchwork Sun Nov 13 19:35:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 9424919 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 37A3C60233 for ; Sun, 13 Nov 2016 19:43:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 214CB288A4 for ; Sun, 13 Nov 2016 19:43:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 12928287AC; Sun, 13 Nov 2016 19:43:00 +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.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, 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 804BA287AC for ; Sun, 13 Nov 2016 19:42:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934841AbcKMTm4 (ORCPT ); Sun, 13 Nov 2016 14:42:56 -0500 Received: from mail-pg0-f41.google.com ([74.125.83.41]:34727 "EHLO mail-pg0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934302AbcKMTmz (ORCPT ); Sun, 13 Nov 2016 14:42:55 -0500 Received: by mail-pg0-f41.google.com with SMTP id x23so41515358pgx.1 for ; Sun, 13 Nov 2016 11:42:55 -0800 (PST) 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=AA2yiYMeIx836zeF+Fuxg1BgkW5flmTUXMEYnPptToA=; b=qFjHBzaWUPl645D4drYcOE0Zg4RYKioZPbbZOUhID+uy/pts6I533Tcm0s238nSNf3 QUHVFv3J7UUTbfUjzUeUdauJQXHnwkL/HQ0fzMIVSI4m2x3HOQYpxbvUjXt30VjQrJaJ yVm9Tox0qLWmBH3P15XZx5FTmztF/eLWOS/x9ys2WyJsPfNusEKUC4PJ2UW6y01VTNcC wamveQ4pIGI0LWcc+Qoi8n3K/ZAW4m/oLFTyVdI0lx6M+MutYZMcgMlUrmfFSMlBbI26 fBfy4Oavo97H3EIIgtLV7+bf/qvdD3vKiZCDN9GPx+677wVGqUSrgrbAe8NYRpLyYVYG KCjw== 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=AA2yiYMeIx836zeF+Fuxg1BgkW5flmTUXMEYnPptToA=; b=FDWYCFD4RzyQAMCgQQjprsoFYOE04kt/EIUe7V7uukSOAYv3qZGR32H5cYONsk21/o NRAyAYQboOrId0XZY4IAvc1VItAfe7XzREHWmUUvy2+rJiuYOAEAOjdqMHbVL65nGr5E NqMowTg7JgFrVAHPLmYtlqrsbViStifqn9/DdxW0mWSPnNgOr1CKc0YZtJwar1sgmu7q LEF84YdPwu9oKfKFrf91c/H8AGm+XQjaedF4RVo7+ElbAkSaPP6DM/ZpLqz9oqXDbIhS sQfqmUd8ZGY/FNAAnRdo89zuhpf7wOTUdWgnw2Wq8jf8qGpX4utRqfnlWOMAS2OsJUpp Iz8A== X-Gm-Message-State: ABUngvcSDiDwA5UomYcRamnhfjYns40fBZ7mbJPGnVBHM01W0zpJ5PPxs6zsCTW+JrnFHsS2 X-Received: by 10.98.94.7 with SMTP id s7mr28543403pfb.37.1479065736166; Sun, 13 Nov 2016 11:35:36 -0800 (PST) Received: from localhost.localdomain ([2601:602:8801:8110:1a5e:fff:fea7:e0ef]) by smtp.gmail.com with ESMTPSA id v76sm8289029pfk.77.2016.11.13.11.35.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 13 Nov 2016 11:35:35 -0800 (PST) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: kernel-team@fb.com Subject: [PATCH 4/6] btrfs-progs: add btrfs_clear_free_space_tree() from the kernel Date: Sun, 13 Nov 2016 11:35:22 -0800 Message-Id: <7e976947939c42bec9756dd02b705d3b2bc387fc.1479064970.git.osandov@fb.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: References: 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 Signed-off-by: Omar Sandoval Reviewed-by: Qu Wenruo --- ctree.h | 6 ++++ extent-tree.c | 10 +++++++ free-space-tree.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ free-space-tree.h | 1 + root-tree.c | 22 ++++++++++++++ 5 files changed, 126 insertions(+) diff --git a/ctree.h b/ctree.h index d67b852..90193ad 100644 --- a/ctree.h +++ b/ctree.h @@ -2504,6 +2504,10 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, int record_parent); int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, int record_parent); +void btrfs_free_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct extent_buffer *buf, + u64 parent, int last_ref); int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 num_bytes, u64 parent, @@ -2664,6 +2668,8 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_root_item *item); +int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_key *key); int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_root_item *item); diff --git a/extent-tree.c b/extent-tree.c index 3b1577e..d445723 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -2467,6 +2467,16 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct return err; } + +void btrfs_free_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct extent_buffer *buf, + u64 parent, int last_ref) +{ + btrfs_free_extent(trans, root, buf->start, buf->len, parent, + root->root_key.objectid, btrfs_header_level(buf), 0); +} + /* * remove an extent from the root, returns 0 on success */ diff --git a/free-space-tree.c b/free-space-tree.c index 3c7a246..d972f26 100644 --- a/free-space-tree.c +++ b/free-space-tree.c @@ -20,6 +20,7 @@ #include "disk-io.h" #include "free-space-cache.h" #include "free-space-tree.h" +#include "transaction.h" static struct btrfs_free_space_info * search_free_space_info(struct btrfs_trans_handle *trans, @@ -67,6 +68,92 @@ static int free_space_test_bit(struct btrfs_block_group_cache *block_group, return !!extent_buffer_test_bit(leaf, ptr, i); } +static int clear_free_space_tree(struct btrfs_trans_handle *trans, + struct btrfs_root *root) +{ + struct btrfs_path *path; + struct btrfs_key key; + int nr; + int ret; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + key.objectid = 0; + key.type = 0; + key.offset = 0; + + while (1) { + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); + if (ret < 0) + goto out; + + nr = btrfs_header_nritems(path->nodes[0]); + if (!nr) + break; + + path->slots[0] = 0; + ret = btrfs_del_items(trans, root, path, 0, nr); + if (ret) + goto out; + + btrfs_release_path(path); + } + + ret = 0; +out: + btrfs_free_path(path); + return ret; +} + +int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) +{ + struct btrfs_trans_handle *trans; + struct btrfs_root *tree_root = fs_info->tree_root; + struct btrfs_root *free_space_root = fs_info->free_space_root; + int ret; + u64 features; + + trans = btrfs_start_transaction(tree_root, 0); + if (IS_ERR(trans)) + return PTR_ERR(trans); + + + features = btrfs_super_compat_ro_flags(fs_info->super_copy); + features &= ~(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID | + BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE); + btrfs_set_super_compat_ro_flags(fs_info->super_copy, features); + fs_info->free_space_root = NULL; + + ret = clear_free_space_tree(trans, free_space_root); + if (ret) + goto abort; + + ret = btrfs_del_root(trans, tree_root, &free_space_root->root_key); + if (ret) + goto abort; + + list_del(&free_space_root->dirty_list); + + clean_tree_block(trans, tree_root, free_space_root->node); + btrfs_free_tree_block(trans, free_space_root, free_space_root->node, + 0, 1); + + free_extent_buffer(free_space_root->node); + free_extent_buffer(free_space_root->commit_root); + kfree(free_space_root); + + ret = btrfs_commit_transaction(trans, tree_root); + if (ret) + return ret; + + return 0; + +abort: + return ret; +} + static int load_free_space_bitmaps(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *block_group, struct btrfs_path *path, diff --git a/free-space-tree.h b/free-space-tree.h index 7529a46..4845f13 100644 --- a/free-space-tree.h +++ b/free-space-tree.h @@ -19,6 +19,7 @@ #ifndef __BTRFS_FREE_SPACE_TREE_H__ #define __BTRFS_FREE_SPACE_TREE_H__ +int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info); int load_free_space_tree(struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *block_group); diff --git a/root-tree.c b/root-tree.c index cca424e..c660447 100644 --- a/root-tree.c +++ b/root-tree.c @@ -143,6 +143,28 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root return ret; } +/* drop the root item for 'key' from 'root' */ +int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_key *key) +{ + struct btrfs_path *path; + int ret; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + ret = btrfs_search_slot(trans, root, key, path, -1, 1); + if (ret < 0) + goto out; + + BUG_ON(ret != 0); + + ret = btrfs_del_item(trans, root, path); +out: + btrfs_free_path(path); + return ret; +} + /* * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY * or BTRFS_ROOT_BACKREF_KEY.