From patchwork Fri Jan 14 00:51:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 12713263 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28D5CC433F5 for ; Fri, 14 Jan 2022 00:51:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238422AbiANAvo (ORCPT ); Thu, 13 Jan 2022 19:51:44 -0500 Received: from smtp-out1.suse.de ([195.135.220.28]:50798 "EHLO smtp-out1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235723AbiANAvo (ORCPT ); Thu, 13 Jan 2022 19:51:44 -0500 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id E9A9F21905 for ; Fri, 14 Jan 2022 00:51:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1642121502; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4lvBr+pnf9BjsRHPYT2VtP1szJT7WTVh5UMGl31NIFI=; b=nKFyQY6F5WUS02CC77Q8EeplEJuP+ANbHXVDyPJOoxTIMZlcg5iUBsAmfe6v+HX8nEJgaw xzInZ7HmMp/tbOnyTLO1hc3zqGy3Nm8VOIpcj0fE/EiY14rA7oQ2KVfePPpxuSa4iGYWRh 9eAZk2cJp9cmSLw7aVVEOuwu17Fzjrk= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 3A0A61344A for ; Fri, 14 Jan 2022 00:51:42 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ION5AB7J4GFWZAAAMHmgww (envelope-from ) for ; Fri, 14 Jan 2022 00:51:42 +0000 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 1/5] btrfs-progs: backref: properly queue indirect refs Date: Fri, 14 Jan 2022 08:51:19 +0800 Message-Id: <20220114005123.19426-2-wqu@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220114005123.19426-1-wqu@suse.com> References: <20220114005123.19426-1-wqu@suse.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org [BUG] When calling iterate_extent_inodes() on data extents with indirect ref (with inline or keyed EXTENT_DATA_REF_KEY), it will fail to execute the call back function at all. [CAUSE] In function find_parent_nodes(), we only add the target tree block if a backref has @parent populated. For indirect backref like EXTENT_DATA_REF_KEY, we rely on __resolve_indirect_ref() to get the parent leaves. However __resolve_indirect_ref() only grabs backrefs from &prefstate->pending_indirect_refs. Meaning callers should queue any indrect backref to pending_indirect_refs. But unfortunately in __add_prelim_ref() and __add_missing_keys(), none of them properly queue the indirect backrefs to pending_indirect_refs, but directly to pending. Making all indirect backrefs never got resolved, thus no callback function executed [FIX] Fix __add_prelim_ref() and __add_missing_keys() to properly queue indirect backrefs to the correct list. Currently there is no such direct user in btrfs-progs, but later csum tree re-initialization code will rely this to do proper csum re-calculate (to avoid preallocated/nodatasum extents). Signed-off-by: Qu Wenruo --- kernel-shared/backref.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel-shared/backref.c b/kernel-shared/backref.c index 42832c481cae..f1a638ededa8 100644 --- a/kernel-shared/backref.c +++ b/kernel-shared/backref.c @@ -192,7 +192,10 @@ static int __add_prelim_ref(struct pref_state *prefstate, u64 root_id, ref->root_id = root_id; if (key) { ref->key_for_search = *key; - head = &prefstate->pending; + if (parent) + head = &prefstate->pending; + else + head = &prefstate->pending_indirect_refs; } else if (parent) { memset(&ref->key_for_search, 0, sizeof(ref->key_for_search)); head = &prefstate->pending; @@ -467,7 +470,10 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info, else btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0); free_extent_buffer(eb); - list_move(&ref->list, &prefstate->pending); + if (ref->parent) + list_move(&ref->list, &prefstate->pending); + else + list_move(&ref->list, &prefstate->pending_indirect_refs); } return 0; } From patchwork Fri Jan 14 00:51:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 12713264 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF017C433EF for ; Fri, 14 Jan 2022 00:51:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238454AbiANAvp (ORCPT ); Thu, 13 Jan 2022 19:51:45 -0500 Received: from smtp-out2.suse.de ([195.135.220.29]:51586 "EHLO smtp-out2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235723AbiANAvp (ORCPT ); Thu, 13 Jan 2022 19:51:45 -0500 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 24B721F384 for ; Fri, 14 Jan 2022 00:51:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1642121504; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NnoAsqpy5B/KDvYpRTzQdvFi4Cqd5dULWYlVhAgpEJE=; b=CJuKEKbycO7Fk6H4Tsf2zgJ2tjMJqtSkuP/SN+eso8LEX0QegjBDHq2RVFTfl7736Geazu Sm4K1KekiHaHFfdziGjpB/QooGeFx2/IUXjVLD9vuXNQW8cMaWc7oc+PPfl6ts2IAoU4CT +zG64xzHSc0Ho+AJ3g1zvgf9WQDSVcQ= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 606421344A for ; Fri, 14 Jan 2022 00:51:43 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id wJLQCR/J4GFWZAAAMHmgww (envelope-from ) for ; Fri, 14 Jan 2022 00:51:43 +0000 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 2/5] btrfs-progs: check: move csum tree population into mode-common.[ch] Date: Fri, 14 Jan 2022 08:51:20 +0800 Message-Id: <20220114005123.19426-3-wqu@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220114005123.19426-1-wqu@suse.com> References: <20220114005123.19426-1-wqu@suse.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This part has no mode specific operations, just move them into mode-common.[ch]. Signed-off-by: Qu Wenruo --- check/main.c | 244 -------------------------------------------- check/mode-common.c | 244 ++++++++++++++++++++++++++++++++++++++++++++ check/mode-common.h | 1 + 3 files changed, 245 insertions(+), 244 deletions(-) diff --git a/check/main.c b/check/main.c index 540130b8e223..ea2f2d7b16b8 100644 --- a/check/main.c +++ b/check/main.c @@ -9557,250 +9557,6 @@ static int zero_log_tree(struct btrfs_root *root) return ret; } -static int populate_csum(struct btrfs_trans_handle *trans, - struct btrfs_root *csum_root, char *buf, u64 start, - u64 len) -{ - u64 offset = 0; - u64 sectorsize; - int ret = 0; - - while (offset < len) { - sectorsize = gfs_info->sectorsize; - ret = read_extent_data(gfs_info, buf, start + offset, - §orsize, 0); - if (ret) - break; - ret = btrfs_csum_file_block(trans, start + len, start + offset, - buf, sectorsize); - if (ret) - break; - offset += sectorsize; - } - return ret; -} - -static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans, - struct btrfs_root *cur_root) -{ - struct btrfs_root *csum_root; - struct btrfs_path path; - struct btrfs_key key; - struct extent_buffer *node; - struct btrfs_file_extent_item *fi; - char *buf = NULL; - u64 start = 0; - u64 len = 0; - int slot = 0; - int ret = 0; - - buf = malloc(gfs_info->sectorsize); - if (!buf) - return -ENOMEM; - - btrfs_init_path(&path); - key.objectid = 0; - key.offset = 0; - key.type = 0; - ret = btrfs_search_slot(NULL, cur_root, &key, &path, 0, 0); - if (ret < 0) - goto out; - /* Iterate all regular file extents and fill its csum */ - while (1) { - btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]); - - if (key.type != BTRFS_EXTENT_DATA_KEY) - goto next; - node = path.nodes[0]; - slot = path.slots[0]; - fi = btrfs_item_ptr(node, slot, struct btrfs_file_extent_item); - if (btrfs_file_extent_type(node, fi) != BTRFS_FILE_EXTENT_REG) - goto next; - start = btrfs_file_extent_disk_bytenr(node, fi); - len = btrfs_file_extent_disk_num_bytes(node, fi); - - csum_root = btrfs_csum_root(gfs_info, start); - ret = populate_csum(trans, csum_root, buf, start, len); - if (ret == -EEXIST) - ret = 0; - if (ret < 0) - goto out; -next: - /* - * TODO: if next leaf is corrupted, jump to nearest next valid - * leaf. - */ - ret = btrfs_next_item(cur_root, &path); - if (ret < 0) - goto out; - if (ret > 0) { - ret = 0; - goto out; - } - } - -out: - btrfs_release_path(&path); - free(buf); - return ret; -} - -static int fill_csum_tree_from_fs(struct btrfs_trans_handle *trans) -{ - struct btrfs_path path; - struct btrfs_root *tree_root = gfs_info->tree_root; - struct btrfs_root *cur_root; - struct extent_buffer *node; - struct btrfs_key key; - int slot = 0; - int ret = 0; - - btrfs_init_path(&path); - key.objectid = BTRFS_FS_TREE_OBJECTID; - key.offset = 0; - key.type = BTRFS_ROOT_ITEM_KEY; - ret = btrfs_search_slot(NULL, tree_root, &key, &path, 0, 0); - if (ret < 0) - goto out; - if (ret > 0) { - ret = -ENOENT; - goto out; - } - - while (1) { - node = path.nodes[0]; - slot = path.slots[0]; - btrfs_item_key_to_cpu(node, &key, slot); - if (key.objectid > BTRFS_LAST_FREE_OBJECTID) - goto out; - if (key.type != BTRFS_ROOT_ITEM_KEY) - goto next; - if (!is_fstree(key.objectid)) - goto next; - key.offset = (u64)-1; - - cur_root = btrfs_read_fs_root(gfs_info, &key); - if (IS_ERR(cur_root) || !cur_root) { - fprintf(stderr, "Fail to read fs/subvol tree: %lld\n", - key.objectid); - goto out; - } - ret = fill_csum_tree_from_one_fs_root(trans, cur_root); - if (ret < 0) - goto out; -next: - ret = btrfs_next_item(tree_root, &path); - if (ret > 0) { - ret = 0; - goto out; - } - if (ret < 0) - goto out; - } - -out: - btrfs_release_path(&path); - return ret; -} - -static int fill_csum_tree_from_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *extent_root) -{ - struct btrfs_root *csum_root; - struct btrfs_path path; - struct btrfs_extent_item *ei; - struct extent_buffer *leaf; - char *buf; - struct btrfs_key key; - int ret; - - btrfs_init_path(&path); - key.objectid = 0; - key.type = BTRFS_EXTENT_ITEM_KEY; - key.offset = 0; - ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0); - if (ret < 0) { - btrfs_release_path(&path); - return ret; - } - - buf = malloc(gfs_info->sectorsize); - if (!buf) { - btrfs_release_path(&path); - return -ENOMEM; - } - - while (1) { - if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) { - ret = btrfs_next_leaf(extent_root, &path); - if (ret < 0) - break; - if (ret) { - ret = 0; - break; - } - } - leaf = path.nodes[0]; - - btrfs_item_key_to_cpu(leaf, &key, path.slots[0]); - if (key.type != BTRFS_EXTENT_ITEM_KEY) { - path.slots[0]++; - continue; - } - - ei = btrfs_item_ptr(leaf, path.slots[0], - struct btrfs_extent_item); - if (!(btrfs_extent_flags(leaf, ei) & - BTRFS_EXTENT_FLAG_DATA)) { - path.slots[0]++; - continue; - } - - csum_root = btrfs_csum_root(gfs_info, key.objectid); - ret = populate_csum(trans, csum_root, buf, key.objectid, - key.offset); - if (ret) - break; - path.slots[0]++; - } - - btrfs_release_path(&path); - free(buf); - return ret; -} - -/* - * Recalculate the csum and put it into the csum tree. - * - * Extent tree init will wipe out all the extent info, so in that case, we - * can't depend on extent tree, but use fs tree. If search_fs_tree is set, we - * will use fs/subvol trees to init the csum tree. - */ -static int fill_csum_tree(struct btrfs_trans_handle *trans, - int search_fs_tree) -{ - struct btrfs_root *root; - struct rb_node *n; - int ret; - - if (search_fs_tree) - return fill_csum_tree_from_fs(trans); - - root = btrfs_extent_root(gfs_info, 0); - while (1) { - ret = fill_csum_tree_from_extent(trans, root); - if (ret) - break; - n = rb_next(&root->rb_node); - if (!n) - break; - root = rb_entry(n, struct btrfs_root, rb_node); - if (root->root_key.objectid != BTRFS_EXTENT_TREE_OBJECTID) - break; - } - return ret; -} - static void free_roots_info_cache(void) { if (!roots_info_cache) diff --git a/check/mode-common.c b/check/mode-common.c index 62a9837bde5e..1608dbdafa4c 100644 --- a/check/mode-common.c +++ b/check/mode-common.c @@ -1191,3 +1191,247 @@ error: btrfs_abort_transaction(trans, ret); return ret; } + +static int populate_csum(struct btrfs_trans_handle *trans, + struct btrfs_root *csum_root, char *buf, u64 start, + u64 len) +{ + u64 offset = 0; + u64 sectorsize; + int ret = 0; + + while (offset < len) { + sectorsize = gfs_info->sectorsize; + ret = read_extent_data(gfs_info, buf, start + offset, + §orsize, 0); + if (ret) + break; + ret = btrfs_csum_file_block(trans, start + len, start + offset, + buf, sectorsize); + if (ret) + break; + offset += sectorsize; + } + return ret; +} + +static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans, + struct btrfs_root *cur_root) +{ + struct btrfs_root *csum_root; + struct btrfs_path path; + struct btrfs_key key; + struct extent_buffer *node; + struct btrfs_file_extent_item *fi; + char *buf = NULL; + u64 start = 0; + u64 len = 0; + int slot = 0; + int ret = 0; + + buf = malloc(gfs_info->sectorsize); + if (!buf) + return -ENOMEM; + + btrfs_init_path(&path); + key.objectid = 0; + key.offset = 0; + key.type = 0; + ret = btrfs_search_slot(NULL, cur_root, &key, &path, 0, 0); + if (ret < 0) + goto out; + /* Iterate all regular file extents and fill its csum */ + while (1) { + btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]); + + if (key.type != BTRFS_EXTENT_DATA_KEY) + goto next; + node = path.nodes[0]; + slot = path.slots[0]; + fi = btrfs_item_ptr(node, slot, struct btrfs_file_extent_item); + if (btrfs_file_extent_type(node, fi) != BTRFS_FILE_EXTENT_REG) + goto next; + start = btrfs_file_extent_disk_bytenr(node, fi); + len = btrfs_file_extent_disk_num_bytes(node, fi); + + csum_root = btrfs_csum_root(gfs_info, start); + ret = populate_csum(trans, csum_root, buf, start, len); + if (ret == -EEXIST) + ret = 0; + if (ret < 0) + goto out; +next: + /* + * TODO: if next leaf is corrupted, jump to nearest next valid + * leaf. + */ + ret = btrfs_next_item(cur_root, &path); + if (ret < 0) + goto out; + if (ret > 0) { + ret = 0; + goto out; + } + } + +out: + btrfs_release_path(&path); + free(buf); + return ret; +} + +static int fill_csum_tree_from_fs(struct btrfs_trans_handle *trans) +{ + struct btrfs_path path; + struct btrfs_root *tree_root = gfs_info->tree_root; + struct btrfs_root *cur_root; + struct extent_buffer *node; + struct btrfs_key key; + int slot = 0; + int ret = 0; + + btrfs_init_path(&path); + key.objectid = BTRFS_FS_TREE_OBJECTID; + key.offset = 0; + key.type = BTRFS_ROOT_ITEM_KEY; + ret = btrfs_search_slot(NULL, tree_root, &key, &path, 0, 0); + if (ret < 0) + goto out; + if (ret > 0) { + ret = -ENOENT; + goto out; + } + + while (1) { + node = path.nodes[0]; + slot = path.slots[0]; + btrfs_item_key_to_cpu(node, &key, slot); + if (key.objectid > BTRFS_LAST_FREE_OBJECTID) + goto out; + if (key.type != BTRFS_ROOT_ITEM_KEY) + goto next; + if (!is_fstree(key.objectid)) + goto next; + key.offset = (u64)-1; + + cur_root = btrfs_read_fs_root(gfs_info, &key); + if (IS_ERR(cur_root) || !cur_root) { + fprintf(stderr, "Fail to read fs/subvol tree: %lld\n", + key.objectid); + goto out; + } + ret = fill_csum_tree_from_one_fs_root(trans, cur_root); + if (ret < 0) + goto out; +next: + ret = btrfs_next_item(tree_root, &path); + if (ret > 0) { + ret = 0; + goto out; + } + if (ret < 0) + goto out; + } + +out: + btrfs_release_path(&path); + return ret; +} + +static int fill_csum_tree_from_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *extent_root) +{ + struct btrfs_root *csum_root; + struct btrfs_path path; + struct btrfs_extent_item *ei; + struct extent_buffer *leaf; + char *buf; + struct btrfs_key key; + int ret; + + btrfs_init_path(&path); + key.objectid = 0; + key.type = BTRFS_EXTENT_ITEM_KEY; + key.offset = 0; + ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0); + if (ret < 0) { + btrfs_release_path(&path); + return ret; + } + + buf = malloc(gfs_info->sectorsize); + if (!buf) { + btrfs_release_path(&path); + return -ENOMEM; + } + + while (1) { + if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) { + ret = btrfs_next_leaf(extent_root, &path); + if (ret < 0) + break; + if (ret) { + ret = 0; + break; + } + } + leaf = path.nodes[0]; + + btrfs_item_key_to_cpu(leaf, &key, path.slots[0]); + if (key.type != BTRFS_EXTENT_ITEM_KEY) { + path.slots[0]++; + continue; + } + + ei = btrfs_item_ptr(leaf, path.slots[0], + struct btrfs_extent_item); + if (!(btrfs_extent_flags(leaf, ei) & + BTRFS_EXTENT_FLAG_DATA)) { + path.slots[0]++; + continue; + } + + csum_root = btrfs_csum_root(gfs_info, key.objectid); + ret = populate_csum(trans, csum_root, buf, key.objectid, + key.offset); + if (ret) + break; + path.slots[0]++; + } + + btrfs_release_path(&path); + free(buf); + return ret; +} + +/* + * Recalculate the csum and put it into the csum tree. + * + * @search_fs_tree: How to get the data extent item. + * If true, iterate all fs roots to get all + * extent data (which can be slow). + * Otherwise, search extent tree for extent data. + */ +int fill_csum_tree(struct btrfs_trans_handle *trans, bool search_fs_tree) +{ + struct btrfs_root *root; + struct rb_node *n; + int ret; + + if (search_fs_tree) + return fill_csum_tree_from_fs(trans); + + root = btrfs_extent_root(gfs_info, 0); + while (1) { + ret = fill_csum_tree_from_extent(trans, root); + if (ret) + break; + n = rb_next(&root->rb_node); + if (!n) + break; + root = rb_entry(n, struct btrfs_root, rb_node); + if (root->root_key.objectid != BTRFS_EXTENT_TREE_OBJECTID) + break; + } + return ret; +} diff --git a/check/mode-common.h b/check/mode-common.h index 8cd135b9bfc2..b894c2be4f97 100644 --- a/check/mode-common.h +++ b/check/mode-common.h @@ -199,4 +199,5 @@ static inline void btrfs_check_subpage_eb_alignment(struct btrfs_fs_info *info, int repair_dev_item_bytes_used(struct btrfs_fs_info *fs_info, u64 devid, u64 bytes_used_expected); +int fill_csum_tree(struct btrfs_trans_handle *trans, bool search_fs_tree); #endif From patchwork Fri Jan 14 00:51:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 12713265 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 192EFC433FE for ; Fri, 14 Jan 2022 00:51:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238554AbiANAvr (ORCPT ); Thu, 13 Jan 2022 19:51:47 -0500 Received: from smtp-out2.suse.de ([195.135.220.29]:51592 "EHLO smtp-out2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238464AbiANAvq (ORCPT ); Thu, 13 Jan 2022 19:51:46 -0500 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 3EB491F3BC for ; Fri, 14 Jan 2022 00:51:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1642121505; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RzTsx4BmsGOR5jiYD2tQwk5GPbjzgAP6ZZo8t4izrHo=; b=Q6nM/R2elPspiZLgv8T15qU1PXgEkIiZEiNysjzetpHhvZzl/q/senCE0D5gQbFI5BmDwo jaScy5D9EpsZWmFgqXTFGEgj5y3p3S0Cb4uoZFNJNZpsGAn6+1ivy/kDT7xTVqPSRIhX+E 3RwwRnO3UrdFT6JWhjXafWP4rTYB+Fc= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 85BF61344A for ; Fri, 14 Jan 2022 00:51:44 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id mMrzEiDJ4GFWZAAAMHmgww (envelope-from ) for ; Fri, 14 Jan 2022 00:51:44 +0000 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 3/5] btrfs-progs: check: don't calculate csum for preallocated file extents Date: Fri, 14 Jan 2022 08:51:21 +0800 Message-Id: <20220114005123.19426-4-wqu@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220114005123.19426-1-wqu@suse.com> References: <20220114005123.19426-1-wqu@suse.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org [BUG] If a btrfs filesystem has preallocated file extents, `btrfs check --init-csum-tree` will create csum item for preallocated extents, and cause error: # mkfs.btrfs -f test.img # mount test.img /mnt/btrfs # fallocate -l 32K /mnt/btrfs/file # umount /mnt/btrfs # btrfs check --init-csum-tree --force test.img ... [4/7] checking fs roots root 5 inode 257 errors 800, odd csum item ERROR: errors found in fs roots found 376832 bytes used, error(s) found And the csum tree is not empty, containing csum for the preallocated extent: $ btrfs ins dump-tree -t csum test.img btrfs-progs v5.15.1 checksum tree key (CSUM_TREE ROOT_ITEM 0) leaf 30408704 items 1 free space 16226 generation 9 owner CSUM_TREE leaf 30408704 flags 0x1(WRITTEN) backref revision 1 fs uuid ecc79835-5611-4609-b985-e4ccd6f15b54 chunk uuid b1c75553-5b82-4aa6-bbbe-e7f50643b1a8 item 0 key (EXTENT_CSUM EXTENT_CSUM 13631488) itemoff 16251 itemsize 32 range start 13631488 end 13664256 length 32768 [CAUSE] For `--init-csum-tree` alone, we will use extent tree to iterate each data extent, and calcluate csum for them. But extent items alone can not tell us if the file extent belongs to a NODATASUM inode, nor if it's preallocated. Thus we create csums for those data extents, and cause the problem. [FIX] However the fix is not that simple, we can not just generate csum for non-preallocated range. As the following case we still need csum for the un-referred part: xfs_io -f -c "pwrite 0 8K" -c "sync" -c "punch 0 4K" So here we have to go another direction by: - Always generate csum for the whole data extent This is the same as the old code - Iterate the file extents, and delete csum for preallocated range or NODATASUM inodes Issue: #430 Signed-off-by: Qu Wenruo --- check/mode-common.c | 106 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/check/mode-common.c b/check/mode-common.c index 1608dbdafa4c..4c6dca2d5973 100644 --- a/check/mode-common.c +++ b/check/mode-common.c @@ -22,6 +22,7 @@ #include "common/utils.h" #include "kernel-shared/disk-io.h" #include "kernel-shared/volumes.h" +#include "kernel-shared/backref.h" #include "common/repair.h" #include "check/mode-common.h" @@ -1338,6 +1339,92 @@ out: return ret; } +static int remove_csum_for_file_extent(u64 ino, u64 offset, u64 rootid, void *ctx) +{ + struct btrfs_trans_handle *trans = (struct btrfs_trans_handle *)ctx; + struct btrfs_fs_info *fs_info = trans->fs_info; + struct btrfs_file_extent_item *fi; + struct btrfs_inode_item *ii; + struct btrfs_path path = {}; + struct btrfs_key key; + struct btrfs_root *root; + bool nocsum = false; + u8 type; + u64 disk_bytenr; + u64 disk_len; + int ret = 0; + + key.objectid = rootid; + key.type = BTRFS_ROOT_ITEM_KEY; + key.offset = (u64)-1; + root = btrfs_read_fs_root(fs_info, &key); + if (IS_ERR(root)) { + ret = PTR_ERR(root); + goto out; + } + + /* Check if the inode has NODATASUM flag */ + key.objectid = ino; + key.type = BTRFS_INODE_ITEM_KEY; + key.offset = 0; + ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); + if (ret > 0) + ret = -ENOENT; + if (ret < 0) + goto out; + + ii = btrfs_item_ptr(path.nodes[0], path.slots[0], + struct btrfs_inode_item); + if (btrfs_inode_flags(path.nodes[0], ii) & BTRFS_INODE_NODATASUM) + nocsum = true; + + btrfs_release_path(&path); + + /* Check the file extent item and delete csum if needed */ + key.objectid = ino; + key.type = BTRFS_EXTENT_DATA_KEY; + key.offset = offset; + ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); + if (ret > 0) + ret = -ENOENT; + if (ret < 0) + goto out; + fi = btrfs_item_ptr(path.nodes[0], path.slots[0], + struct btrfs_file_extent_item); + type = btrfs_file_extent_type(path.nodes[0], fi); + + if (btrfs_file_extent_disk_bytenr(path.nodes[0], fi) == 0) + goto out; + + /* Compressed extent should have csum, skip it */ + if (btrfs_file_extent_compression(path.nodes[0], fi) != + BTRFS_COMPRESS_NONE) + goto out; + /* + * We only want to delete the csum range if the inode has NODATASUM + * flag or it's a preallocated extent. + */ + if (!(nocsum || type == BTRFS_FILE_EXTENT_PREALLOC)) + goto out; + + /* If NODATASUM, we need to remove all csum for the extent */ + if (nocsum) { + disk_bytenr = btrfs_file_extent_disk_bytenr(path.nodes[0], fi); + disk_len = btrfs_file_extent_disk_num_bytes(path.nodes[0], fi); + } else { + disk_bytenr = btrfs_file_extent_disk_bytenr(path.nodes[0], fi) + + btrfs_file_extent_offset(path.nodes[0], fi); + disk_len = btrfs_file_extent_num_bytes(path.nodes[0], fi); + } + btrfs_release_path(&path); + + /* Now delete the csum for the preallocated or nodatasum range */ + ret = btrfs_del_csums(trans, disk_bytenr, disk_len); +out: + btrfs_release_path(&path); + return ret; +} + static int fill_csum_tree_from_extent(struct btrfs_trans_handle *trans, struct btrfs_root *extent_root) { @@ -1390,10 +1477,27 @@ static int fill_csum_tree_from_extent(struct btrfs_trans_handle *trans, path.slots[0]++; continue; } - + /* + * Generate the datasum unconditionally first. + * + * This will generate csum for preallocated extents, but that + * will be later deleted. + * + * This is to address cases like this: + * fallocate 0 8K + * pwrite 0 4k + * sync + * punch 0 4k + * + * Above case we will have csum for [0, 4K) and that's valid. + */ csum_root = btrfs_csum_root(gfs_info, key.objectid); ret = populate_csum(trans, csum_root, buf, key.objectid, key.offset); + if (ret < 0) + break; + ret = iterate_extent_inodes(trans->fs_info, key.objectid, 0, 0, + remove_csum_for_file_extent, trans); if (ret) break; path.slots[0]++; From patchwork Fri Jan 14 00:51:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 12713266 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B56CFC4332F for ; Fri, 14 Jan 2022 00:51:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238555AbiANAvs (ORCPT ); Thu, 13 Jan 2022 19:51:48 -0500 Received: from smtp-out2.suse.de ([195.135.220.29]:51598 "EHLO smtp-out2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235723AbiANAvr (ORCPT ); Thu, 13 Jan 2022 19:51:47 -0500 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 62E061F384 for ; Fri, 14 Jan 2022 00:51:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1642121506; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tbYmUjM+NclaFMHxFgEKGuy7CRrIwiERoceN54Inqko=; b=AJe/0mOap7O+rSN+zq347+5pO1C2Pq28Tq77Z0j87HoFgwyLXdLYaAW0X1ilnjXQtx0CLn 2kNwlTD6Lxik70TUYgzqb2ALcig19bs9SNNxUkcuxifOpbD4IoT+BC9SAoXGlk2P7/67Bw vOUAfIRmM5CFm/zelxPwh/mU4+nUEBY= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id AA4571344A for ; Fri, 14 Jan 2022 00:51:45 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id qBnhGyHJ4GFWZAAAMHmgww (envelope-from ) for ; Fri, 14 Jan 2022 00:51:45 +0000 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 4/5] btrfs-progs: check: handle csum generation properly for `--init-csum-tree --init-extent-tree` Date: Fri, 14 Jan 2022 08:51:22 +0800 Message-Id: <20220114005123.19426-5-wqu@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220114005123.19426-1-wqu@suse.com> References: <20220114005123.19426-1-wqu@suse.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org When using `--init-csum-tree` with `--init-extent-tree`, csum tree population will be done by iterating all file extent items. This allow us to skip preallocated extents, but it still has the folllwing problems: - Inodes with NODATASUM - Hole file extents - Written preallocated extents We will generate csum for the whole extent, while other part may still be unwritten. Make it to follow the same behavior of recently introduced fill_csum_for_file_extent(), so we can generate correct csum. Signed-off-by: Qu Wenruo --- check/mode-common.c | 53 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/check/mode-common.c b/check/mode-common.c index 4c6dca2d5973..e487f2f0bb8e 100644 --- a/check/mode-common.c +++ b/check/mode-common.c @@ -1225,6 +1225,7 @@ static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans, struct extent_buffer *node; struct btrfs_file_extent_item *fi; char *buf = NULL; + u64 skip_ino = 0; u64 start = 0; u64 len = 0; int slot = 0; @@ -1243,24 +1244,68 @@ static int fill_csum_tree_from_one_fs_root(struct btrfs_trans_handle *trans, goto out; /* Iterate all regular file extents and fill its csum */ while (1) { + u8 type; + btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]); - if (key.type != BTRFS_EXTENT_DATA_KEY) + if (key.type != BTRFS_EXTENT_DATA_KEY && + key.type != BTRFS_INODE_ITEM_KEY) + goto next; + + /* This item belongs to an inode with NODATASUM, skip it */ + if (key.objectid == skip_ino) goto next; + + if (key.type == BTRFS_INODE_ITEM_KEY) { + struct btrfs_inode_item *ii; + + ii = btrfs_item_ptr(path.nodes[0], path.slots[0], + struct btrfs_inode_item); + /* Check if the inode has NODATASUM flag */ + if (btrfs_inode_flags(path.nodes[0], ii) & + BTRFS_INODE_NODATASUM) + skip_ino = key.objectid; + goto next; + } node = path.nodes[0]; slot = path.slots[0]; fi = btrfs_item_ptr(node, slot, struct btrfs_file_extent_item); - if (btrfs_file_extent_type(node, fi) != BTRFS_FILE_EXTENT_REG) + type = btrfs_file_extent_type(node, fi); + + /* Skip inline extents */ + if (type == BTRFS_FILE_EXTENT_INLINE) goto next; - start = btrfs_file_extent_disk_bytenr(node, fi); - len = btrfs_file_extent_disk_num_bytes(node, fi); + start = btrfs_file_extent_disk_bytenr(node, fi); + /* Skip holes */ + if (start == 0) + goto next; + /* + * Always generate the csum for the whole preallocated/regular + * first, then remove the csum for preallocated range. + * + * This is to handle holes on regular extents like: + * xfs_io -f -c "pwrite 0 8k" -c "sync" -c "punch 0 4k". + * + * This behavior will cost extra IO/CPU time, but there is + * not other way to ensure the correctness. + */ csum_root = btrfs_csum_root(gfs_info, start); + len = btrfs_file_extent_disk_num_bytes(node, fi); ret = populate_csum(trans, csum_root, buf, start, len); if (ret == -EEXIST) ret = 0; if (ret < 0) goto out; + + /* Delete the csum for the preallocated range */ + if (type == BTRFS_FILE_EXTENT_PREALLOC) { + start += btrfs_file_extent_offset(node, fi); + len = btrfs_file_extent_num_bytes(node, fi); + ret = btrfs_del_csums(trans, start, len); + if (ret < 0) + goto out; + } next: /* * TODO: if next leaf is corrupted, jump to nearest next valid From patchwork Fri Jan 14 00:51:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 12713267 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D3000C433EF for ; Fri, 14 Jan 2022 00:51:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238557AbiANAvt (ORCPT ); Thu, 13 Jan 2022 19:51:49 -0500 Received: from smtp-out1.suse.de ([195.135.220.28]:50830 "EHLO smtp-out1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238556AbiANAvs (ORCPT ); Thu, 13 Jan 2022 19:51:48 -0500 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 87E8D218FC for ; Fri, 14 Jan 2022 00:51:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1642121507; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7pOz1rcOUZQnL2crfuM1r+IGadqeCzPten/QZhYarPg=; b=G8wURoWbPLAucm+YCShFs8faEIx0h7IR07aRWjO/w9bfwO3JKbf38EqZ3ip1YwEIWz+d14 5/IWg8m2wKUafQ+U272EoIbAOthNRp/QPvHG5LDWuVI5tKzzz8BUs9P/3O9i2Om8clnUF7 p09jLiXCsTubcqLgeuEyT7bHkDT4yWg= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id CF2CD1344A for ; Fri, 14 Jan 2022 00:51:46 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id AIbcJCLJ4GFWZAAAMHmgww (envelope-from ) for ; Fri, 14 Jan 2022 00:51:46 +0000 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH v2 5/5] btrfs-progs: fsck-tests: add test case for init-csum-tree Date: Fri, 14 Jan 2022 08:51:23 +0800 Message-Id: <20220114005123.19426-6-wqu@suse.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220114005123.19426-1-wqu@suse.com> References: <20220114005123.19426-1-wqu@suse.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This new test script will create a fs with the following situations: - Preallocated extents (no data csum) - Nodatasum inodes (no data csum) - Partially written preallocated extents (no data csum for part of the extent) - Regular data extents (with data csum) - Regular data extents then hole punched (with data csum) - Preallocated data, then written, then hole punched (with data csum) - Compressed extents (with data csum) And make sure after --init-csum-tree (with or without --init-extent-tree) the result fs can still pass fsck. Signed-off-by: Qu Wenruo --- tests/fsck-tests/052-init-csum-tree/test.sh | 72 +++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100755 tests/fsck-tests/052-init-csum-tree/test.sh diff --git a/tests/fsck-tests/052-init-csum-tree/test.sh b/tests/fsck-tests/052-init-csum-tree/test.sh new file mode 100755 index 000000000000..34ca50e5c85f --- /dev/null +++ b/tests/fsck-tests/052-init-csum-tree/test.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# +# Verify that `btrfs check --init-csum-tree` can handle various nodatasum +# cases. + +source "$TEST_TOP/common" + +check_prereq btrfs +check_global_prereq fallocate +check_global_prereq dd +setup_root_helper +prepare_test_dev + +run_check_mkfs_test_dev + +# Create an inode with nodatasum and some content +run_check_mount_test_dev -o nodatasum + +run_check $SUDO_HELPER dd if=/dev/urandom of="$TEST_MNT/nodatasum_file" \ + bs=16k count=1 status=noxfer > /dev/null 2>&1 + +# Revert to default datasum +run_check $SUDO_HELPER mount -o remount,datasum "$TEST_MNT" + +# Then create an inode with datasum, but all preallocated extents +run_check fallocate -l 32k "$TEST_MNT/prealloc1" + +# Create preallocated extent but partially written +run_check fallocate -l 32k "$TEST_MNT/prealloc2" +run_check $SUDO_HELPER dd if=/dev/urandom of="$TEST_MNT/prealloc2" \ + bs=16k count=1 conv=notrunc status=noxfer> /dev/null 2>&1 + +# Then some regular files +run_check $SUDO_HELPER dd if=/dev/urandom of="$TEST_MNT/regular" \ + bs=16k count=1 status=noxfer > /dev/null 2>&1 + +# And some regular files with holes +run_check $SUDO_HELPER dd if=/dev/urandom of="$TEST_MNT/regular_with_holes" \ + bs=16k count=1 status=noxfer > /dev/null 2>&1 +run_check $SUDO_HELPER fallocate -p -o 4096 -l 4096 "$TEST_MNT/regular_with_holes" + +# And the most complex one, preallocated, written, then hole +run_check $SUDO_HELPER fallocate -l 8192 "$TEST_MNT/complex" +run_check $SUDO_HELPER dd if=/dev/urandom of="$TEST_MNT/compex" \ + bs=4k count=1 conv=notrunc status=noxfer > /dev/null 2>&1 +sync +run_check $SUDO_HELPER fallocate -p -l 4096 "$TEST_MNT/regular_with_holes" + +# Create some compressed file +run_check $SUDO_HELPER mount -o remount,compress "$TEST_MNT" +run_check $SUDO_HELPER dd if=/dev/zero of="$TEST_MNT/compressed" \ + bs=16k count=4 conv=notrunc status=noxfer> /dev/null 2>&1 + +# And create a snapshot, every data extent is at least shared twice +run_check $SUDO_HELPER "$TOP/btrfs" subvolume snapshot "$TEST_MNT" \ + "$TEST_MNT/snapshot" +run_check_umount_test_dev + +# --init-csum-tree should not fail +run_check $SUDO_HELPER "$TOP/btrfs" check --force \ + --init-csum-tree "$TEST_DEV" + +# No error should be found +run_check $SUDO_HELPER "$TOP/btrfs" check "$TEST_DEV" +btrfs ins dump-tree "$TEST_DEV" > /tmp/dump + +# --init-csum-tree with --init-extent-tree should not fail +#run_check $SUDO_HELPER "$TOP/btrfs" check --force \ +# --init-csum-tree --init-extent-tree "$TEST_DEV" + +# No error should be found +#run_check $SUDO_HELPER "$TOP/btrfs" check "$TEST_DEV"