From patchwork Wed Jul 7 04:40:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Ruffell X-Patchwork-Id: 1501571 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GKRZV1Kpzz9t23; Wed, 7 Jul 2021 14:41:06 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1m0zMr-00054n-4x; Wed, 07 Jul 2021 04:41:01 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1m0zMh-00050M-8M for kernel-team@lists.ubuntu.com; Wed, 07 Jul 2021 04:40:51 +0000 Received: from mail-pj1-f69.google.com ([209.85.216.69]) by youngberry.canonical.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1m0zMg-0008Dw-QI for kernel-team@lists.ubuntu.com; Wed, 07 Jul 2021 04:40:51 +0000 Received: by mail-pj1-f69.google.com with SMTP id q9-20020a17090a0649b029016ffc6b9665so3090555pje.1 for ; Tue, 06 Jul 2021 21:40:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kW9ife9INi0ZJ9n8sg7TpTTBDOJc0/Ckjfg2bPNezgQ=; b=gCxFFvzNzVyrIYehIAg7Ro8b+nSDAOWRd3Ey8+JPKwMLLqyRRfME+yNv9Tb9ROz6Dz U7QvxsVgfHf9yYnUaRTX4utrKuSg9orWZIbrVJDWPKdoqiPxA2kn6vYXcZ8jsdFQ/7lI 7740Qdpz+w/2BJvd2E5spVilWIrZqSONfhOTuB2TD68ga3G8LzlpEPy510556WQyimwJ zfWfyvK0UNM8gVUNfk9oatEgNC84zsch0JglN6sqqDxbRCbgQxolFEDFNBWn7TjZ8xiI Nh4+hB3Z6YoFwFrBew5G9a3ByBFZTJpnAupHikGIi6UN3b5DkWjXAMHwKkkfBFrMyQfv Brkw== X-Gm-Message-State: AOAM5324S7t6oJkwTSCZtJ+3R/pmliB7J/+2rqC4MN0Sw69Rmhr0reRW fQVZUqdbl/2Neuphj32hbcu8BVF1ByKA/JpZDkLG+IZi+pD7V3cnRn4JoYE3MQq8M7MD0yi7hsQ 5RL4d8wjRjHiBFCWCMfnaaf/nJDRSHT59CHmMr8LQ1Q== X-Received: by 2002:a63:7152:: with SMTP id b18mr24223644pgn.224.1625632849315; Tue, 06 Jul 2021 21:40:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyoxvTVY4b2dGPlZBCGJuYfafQl/2m37RVNPM6BHXZuK4bUH50EtvFo4gpeVged+1vjvalFxg== X-Received: by 2002:a63:7152:: with SMTP id b18mr24223625pgn.224.1625632848900; Tue, 06 Jul 2021 21:40:48 -0700 (PDT) Received: from desktop.. (125-237-197-94-fibre.sparkbb.co.nz. [125.237.197.94]) by smtp.gmail.com with ESMTPSA id d1sm16861332pfu.6.2021.07.06.21.40.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jul 2021 21:40:48 -0700 (PDT) From: Matthew Ruffell To: kernel-team@lists.ubuntu.com Subject: [SRU][B][PATCH 2/6] Revert "btrfs: Validate child tree block's level and first key" Date: Wed, 7 Jul 2021 16:40:33 +1200 Message-Id: <20210707044037.37992-3-matthew.ruffell@canonical.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210707044037.37992-1-matthew.ruffell@canonical.com> References: <20210707044037.37992-1-matthew.ruffell@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1934709 This reverts commit 50ab1ff51db0c5eb77ffc6f15ef32f07764f86ff. A mistake was made in the backport of "btrfs: Validate child tree block's level and first key" for Bionic. If you look closely, there is a hunk in btree_read_extent_buffer_pages() which implements: @@ -458,13 +504,25 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info, + /* + * This buffer's crc is fine, but its contents are corrupted, so + * there is no reason to read the other copies, they won't be + * any less wrong. + */ + if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags) || + ret == -EUCLEAN) + break; + The actual upstream commit extends the if statement instead: @@ -460,7 +509,8 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info, * there is no reason to read the other copies, they won't be * any less wrong. */ - if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags)) + if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags) || + ret == -EUCLEAN) break; It turns out this if statement and comment block was introduced in v2.6.39-rc1 via the commit commit a826d6dcb32d811b4c81df57a5ef1367516586b0 Author: Josef Bacik Date: Wed Mar 16 13:42:43 2011 -0400 Subject: Btrfs: check items for correctness as we search and that the code had been previously removed in the backport of "btrfs: Always try all copies when reading extent buffers" ubuntu-bionic 03e1b5c9a1c1704e109466b375d09a4721b65ec5 Author: Nikolay Borisov Date: Tue Nov 6 16:40:20 2018 +0200 Subject: btrfs: Always try all copies when reading extent buffers The mistake involved re-adding this if statement back in, when it had clearly been removed for the reasons in the above commit. Leaving the if statement in place can lead to the below kernel oops: BTRFS: error (device dm-14) in balance_level:1962: errno=-117 unknown BTRFS info (device dm-14): forced readonly BTRFS: Transaction aborted (error -117) WARNING: CPU: 7 PID: 10818 at /build/linux-99Rib2/linux-4.15.0/fs/btrfs/tree-log.c:2908 btrfs_sync_log+0xa28/0xbc0 [btrfs] CPU: 7 PID: 10818 Comm: qemu-system-s39 Tainted: G OE 4.15.0-136-generic #140-Ubuntu Hardware name: IBM 3907 LR1 A00 (LPAR) Krnl PSW : 0000000076bc1d64 000000009cc65255 (btrfs_sync_log+0xa28/0xbc0 [btrfs]) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 RI:0 EA:3 Krnl GPRS: 007899a600000000 0000000000000006 0000000000000027 0000000000000007 000003ff801fdd8c 000000000002394c 00000053650a7000 ffffffffffffff8b 000000536b7f6000 00000053ffffff8b 00000053650a3800 0000005385935000 000000532054de01 0000005385935290 000003ff801fdd8c 0000004eebb1fae0 Krnl Code: 000003ff801fdd80: c0200002a032 larl %r2,000003ff80251de4 000003ff801fdd86: c0e5fffb2181 brasl %r14,000003ff80162088 #000003ff801fdd8c: a7f40001 brc 15,000003ff801fdd8e >000003ff801fdd90: e3a0f0a80004 lg %r10,168(%r15) 000003ff801fdd96: b9040057 lgr %r5,%r7 000003ff801fdd9a: a7490b5c lghi %r4,2908 000003ff801fdd9e: b904002a lgr %r2,%r10 000003ff801fdda2: c0300002604f larl %r3,000003ff80249e40 Call Trace: ([<000003ff801fdd8c>] btrfs_sync_log+0xa24/0xbc0 [btrfs]) [<000003ff801c74e2>] btrfs_sync_file+0x3e2/0x550 [btrfs] [<00000000003ce6ce>] do_fsync+0x5e/0x90 [<00000000003ce9ca>] SyS_fdatasync+0x32/0x48 [<00000000008ffe5c>] system_call+0xd8/0x2c8 Last Breaking-Event-Address: [<000003ff801fdd8c>] btrfs_sync_log+0xa24/0xbc0 [btrfs] BTRFS: error (device dm-14) in btrfs_sync_log:2908: errno=-117 unknown BTRFS error (device dm-14): pending csums is 269639680 Correct this by reverting the commit, so we can apply a correct backport in the next patch. Signed-off-by: Matthew Ruffell --- fs/btrfs/backref.c | 6 +-- fs/btrfs/ctree.c | 28 +++--------- fs/btrfs/disk-io.c | 101 +++++------------------------------------ fs/btrfs/disk-io.h | 8 ++-- fs/btrfs/extent-tree.c | 6 +-- fs/btrfs/print-tree.c | 10 ++-- fs/btrfs/qgroup.c | 7 +-- fs/btrfs/ref-verify.c | 7 +-- fs/btrfs/relocation.c | 21 ++------- fs/btrfs/tree-log.c | 28 +++++------- 10 files changed, 45 insertions(+), 177 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 0fc57028bcad..1290f3f78ed7 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -737,8 +737,7 @@ static int add_missing_keys(struct btrfs_fs_info *fs_info, BUG_ON(ref->key_for_search.type); BUG_ON(!ref->wanted_disk_byte); - eb = read_tree_block(fs_info, ref->wanted_disk_byte, 0, - ref->level - 1, NULL); + eb = read_tree_block(fs_info, ref->wanted_disk_byte, 0); if (IS_ERR(eb)) { free_pref(ref); return PTR_ERR(eb); @@ -1293,8 +1292,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, ref->level == 0) { struct extent_buffer *eb; - eb = read_tree_block(fs_info, ref->parent, 0, - ref->level, NULL); + eb = read_tree_block(fs_info, ref->parent, 0); if (IS_ERR(eb)) { ret = PTR_ERR(eb); goto out; diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 3446407451fe..c48f0950ecb8 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1446,7 +1446,6 @@ get_old_root(struct btrfs_root *root, u64 time_seq) struct tree_mod_root *old_root = NULL; u64 old_generation = 0; u64 logical; - int level; eb_root = btrfs_read_lock_root_node(root); tm = __tree_mod_log_oldest_root(fs_info, eb_root, time_seq); @@ -1457,17 +1456,15 @@ get_old_root(struct btrfs_root *root, u64 time_seq) old_root = &tm->old_root; old_generation = tm->generation; logical = old_root->logical; - level = old_root->level; } else { logical = eb_root->start; - level = btrfs_header_level(eb_root); } tm = tree_mod_log_search(fs_info, logical, time_seq); if (old_root && tm && tm->op != MOD_LOG_KEY_REMOVE_WHILE_FREEING) { btrfs_tree_read_unlock(eb_root); free_extent_buffer(eb_root); - old = read_tree_block(fs_info, logical, 0, level, NULL); + old = read_tree_block(fs_info, logical, 0); if (WARN_ON(IS_ERR(old) || !extent_buffer_uptodate(old))) { if (!IS_ERR(old)) free_extent_buffer(old); @@ -1711,7 +1708,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, btrfs_set_lock_blocking(parent); for (i = start_slot; i <= end_slot; i++) { - struct btrfs_key first_key; int close = 1; btrfs_node_key(parent, &disk_key, i); @@ -1721,7 +1717,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, progress_passed = 1; blocknr = btrfs_node_blockptr(parent, i); gen = btrfs_node_ptr_generation(parent, i); - btrfs_node_key_to_cpu(parent, &first_key, i); if (last_block == 0) last_block = blocknr; @@ -1745,9 +1740,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, uptodate = 0; if (!cur || !uptodate) { if (!cur) { - cur = read_tree_block(fs_info, blocknr, gen, - parent_level - 1, - &first_key); + cur = read_tree_block(fs_info, blocknr, gen); if (IS_ERR(cur)) { return PTR_ERR(cur); } else if (!extent_buffer_uptodate(cur)) { @@ -1755,8 +1748,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, return -EIO; } } else if (!uptodate) { - err = btrfs_read_buffer(cur, gen, - parent_level - 1,&first_key); + err = btrfs_read_buffer(cur, gen); if (err) { free_extent_buffer(cur); return err; @@ -1915,17 +1907,14 @@ read_node_slot(struct btrfs_fs_info *fs_info, struct extent_buffer *parent, { int level = btrfs_header_level(parent); struct extent_buffer *eb; - struct btrfs_key first_key; if (slot < 0 || slot >= btrfs_header_nritems(parent)) return ERR_PTR(-ENOENT); BUG_ON(level == 0); - btrfs_node_key_to_cpu(parent, &first_key, slot); eb = read_tree_block(fs_info, btrfs_node_blockptr(parent, slot), - btrfs_node_ptr_generation(parent, slot), - level - 1, &first_key); + btrfs_node_ptr_generation(parent, slot)); if (!IS_ERR(eb) && !extent_buffer_uptodate(eb)) { free_extent_buffer(eb); eb = ERR_PTR(-EIO); @@ -2514,14 +2503,10 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p, u64 gen; struct extent_buffer *b = *eb_ret; struct extent_buffer *tmp; - struct btrfs_key first_key; int ret; - int parent_level; blocknr = btrfs_node_blockptr(b, slot); gen = btrfs_node_ptr_generation(b, slot); - parent_level = btrfs_header_level(b); - btrfs_node_key_to_cpu(b, &first_key, slot); tmp = find_extent_buffer(fs_info, blocknr); if (tmp) { @@ -2540,7 +2525,7 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p, btrfs_set_path_blocking(p); /* now we're allowed to do a blocking uptodate check */ - ret = btrfs_read_buffer(tmp, gen, parent_level - 1, &first_key); + ret = btrfs_read_buffer(tmp, gen); if (!ret) { *eb_ret = tmp; return 0; @@ -2565,8 +2550,7 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p, reada_for_search(fs_info, p, level, slot, key->objectid); ret = -EAGAIN; - tmp = read_tree_block(fs_info, blocknr, gen, parent_level - 1, - &first_key); + tmp = read_tree_block(fs_info, blocknr, gen); if (!IS_ERR(tmp)) { /* * If the read above didn't mark this buffer up to date, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 62ece41660ae..92068a201961 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -437,59 +437,13 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info, return ret; } -static int verify_level_key(struct btrfs_fs_info *fs_info, - struct extent_buffer *eb, int level, - struct btrfs_key *first_key) -{ - int found_level; - struct btrfs_key found_key; - int ret; - - found_level = btrfs_header_level(eb); - if (found_level != level) { -#ifdef CONFIG_BTRFS_DEBUG - WARN_ON(1); - btrfs_err(fs_info, -"tree level mismatch detected, bytenr=%llu level expected=%u has=%u", - eb->start, level, found_level); -#endif - return -EIO; - } - - if (!first_key) - return 0; - - if (found_level) - btrfs_node_key_to_cpu(eb, &found_key, 0); - else - btrfs_item_key_to_cpu(eb, &found_key, 0); - ret = btrfs_comp_cpu_keys(first_key, &found_key); - -#ifdef CONFIG_BTRFS_DEBUG - if (ret) { - WARN_ON(1); - btrfs_err(fs_info, -"tree first key mismatch detected, bytenr=%llu key expected=(%llu, %u, %llu) has=(%llu, %u, %llu)", - eb->start, first_key->objectid, first_key->type, - first_key->offset, found_key.objectid, - found_key.type, found_key.offset); - } -#endif - return ret; -} - /* * helper to read a given tree block, doing retries as required when * the checksums don't match and we have alternate mirrors to try. - * - * @parent_transid: expected transid, skip check if 0 - * @level: expected level, mandatory check - * @first_key: expected key of first slot, skip check if NULL */ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, - u64 parent_transid, int level, - struct btrfs_key *first_key) + u64 parent_transid) { struct extent_io_tree *io_tree; int failed = 0; @@ -504,25 +458,13 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info, ret = read_extent_buffer_pages(io_tree, eb, WAIT_COMPLETE, btree_get_extent, mirror_num); if (!ret) { - if (verify_parent_transid(io_tree, eb, + if (!verify_parent_transid(io_tree, eb, parent_transid, 0)) - ret = -EIO; - else if (verify_level_key(fs_info, eb, level, - first_key)) - ret = -EUCLEAN; - else break; + else + ret = -EIO; } - /* - * This buffer's crc is fine, but its contents are corrupted, so - * there is no reason to read the other copies, they won't be - * any less wrong. - */ - if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags) || - ret == -EUCLEAN) - break; - num_copies = btrfs_num_copies(fs_info, eb->start, eb->len); if (num_copies == 1) @@ -1127,17 +1069,8 @@ void btrfs_wait_tree_block_writeback(struct extent_buffer *buf) buf->start, buf->start + buf->len - 1); } -/* - * Read tree block at logical address @bytenr and do variant basic but critical - * verification. - * - * @parent_transid: expected transid of this tree block, skip check if 0 - * @level: expected level, mandatory check - * @first_key: expected key in slot 0, skip check if NULL - */ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, - u64 parent_transid, int level, - struct btrfs_key *first_key) + u64 parent_transid) { struct extent_buffer *buf = NULL; int ret; @@ -1146,8 +1079,7 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, if (IS_ERR(buf)) return buf; - ret = btree_read_extent_buffer_pages(fs_info, buf, parent_transid, - level, first_key); + ret = btree_read_extent_buffer_pages(fs_info, buf, parent_transid); if (ret) { free_extent_buffer_stale(buf); return ERR_PTR(ret); @@ -1476,7 +1408,6 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root, struct btrfs_path *path; u64 generation; int ret; - int level; path = btrfs_alloc_path(); if (!path) @@ -1499,10 +1430,9 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root, } generation = btrfs_root_generation(&root->root_item); - level = btrfs_root_level(&root->root_item); root->node = read_tree_block(fs_info, btrfs_root_bytenr(&root->root_item), - generation, level, NULL); + generation); if (IS_ERR(root->node)) { ret = PTR_ERR(root->node); goto find_fail; @@ -2333,7 +2263,6 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info, struct btrfs_root *log_tree_root; struct btrfs_super_block *disk_super = fs_info->super_copy; u64 bytenr = btrfs_super_log_root(disk_super); - int level = btrfs_super_log_root_level(disk_super); if (fs_devices->rw_devices == 0) { btrfs_warn(fs_info, "log replay required on RO media"); @@ -2347,8 +2276,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info, __setup_root(log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID); log_tree_root->node = read_tree_block(fs_info, bytenr, - fs_info->generation + 1, - level, NULL); + fs_info->generation + 1); if (IS_ERR(log_tree_root->node)) { btrfs_warn(fs_info, "failed to read log tree"); ret = PTR_ERR(log_tree_root->node); @@ -2465,7 +2393,6 @@ int open_ctree(struct super_block *sb, int backup_index = 0; int max_active; int clear_free_space_tree = 0; - int level; 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); @@ -2800,13 +2727,12 @@ int open_ctree(struct super_block *sb, } generation = btrfs_super_chunk_root_generation(disk_super); - level = btrfs_super_chunk_root_level(disk_super); __setup_root(chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID); chunk_root->node = read_tree_block(fs_info, btrfs_super_chunk_root(disk_super), - generation, level, NULL); + generation); if (IS_ERR(chunk_root->node) || !extent_buffer_uptodate(chunk_root->node)) { btrfs_err(fs_info, "failed to read chunk root"); @@ -2840,11 +2766,10 @@ int open_ctree(struct super_block *sb, retry_root_backup: generation = btrfs_super_generation(disk_super); - level = btrfs_super_root_level(disk_super); tree_root->node = read_tree_block(fs_info, btrfs_super_root(disk_super), - generation, level, NULL); + generation); if (IS_ERR(tree_root->node) || !extent_buffer_uptodate(tree_root->node)) { btrfs_warn(fs_info, "failed to read tree root"); @@ -3986,14 +3911,12 @@ void btrfs_btree_balance_dirty_nodelay(struct btrfs_fs_info *fs_info) __btrfs_btree_balance_dirty(fs_info, 0); } -int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid, int level, - struct btrfs_key *first_key) +int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) { struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root; struct btrfs_fs_info *fs_info = root->fs_info; - return btree_read_extent_buffer_pages(fs_info, buf, parent_transid, - level, first_key); + return btree_read_extent_buffer_pages(fs_info, buf, parent_transid); } static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info) diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index dbd31158e93c..7f7c35d6347a 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -52,9 +52,8 @@ static inline u64 btrfs_sb_offset(int mirror) struct btrfs_device; struct btrfs_fs_devices; -struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, - u64 parent_transid, int level, - struct btrfs_key *first_key); +struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, + u64 bytenr, u64 parent_transid); void readahead_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr); int reada_tree_block_flagged(struct btrfs_fs_info *fs_info, u64 bytenr, int mirror_num, struct extent_buffer **eb); @@ -124,8 +123,7 @@ static inline void btrfs_put_fs_root(struct btrfs_root *root) void btrfs_mark_buffer_dirty(struct extent_buffer *buf); int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, int atomic); -int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid, int level, - struct btrfs_key *first_key); +int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid); u32 btrfs_csum_data(const char *data, u32 seed, size_t len); void btrfs_csum_final(u32 crc, u8 *result); blk_status_t btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index cff3a21c7390..590392fb756b 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -8879,7 +8879,6 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, u64 parent; u32 blocksize; struct btrfs_key key; - struct btrfs_key first_key; struct extent_buffer *next; int level = wc->level; int reada = 0; @@ -8900,8 +8899,6 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, } bytenr = btrfs_node_blockptr(path->nodes[level], path->slots[level]); - btrfs_node_key_to_cpu(path->nodes[level], &first_key, - path->slots[level]); blocksize = fs_info->nodesize; next = find_extent_buffer(fs_info, bytenr); @@ -8966,8 +8963,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, if (!next) { if (reada && level == 1) reada_walk_down(trans, root, wc, path); - next = read_tree_block(fs_info, bytenr, generation, level - 1, - &first_key); + next = read_tree_block(fs_info, bytenr, generation); if (IS_ERR(next)) { return PTR_ERR(next); } else if (!extent_buffer_uptodate(next)) { diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index 531ecc4eefef..f96eb176166d 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c @@ -367,13 +367,9 @@ void btrfs_print_tree(struct extent_buffer *c) btrfs_node_blockptr(c, i)); } for (i = 0; i < nr; i++) { - struct btrfs_key first_key; - struct extent_buffer *next; - - btrfs_node_key_to_cpu(c, &first_key, i); - next = read_tree_block(fs_info, btrfs_node_blockptr(c, i), - btrfs_node_ptr_generation(c, i), - level - 1, &first_key); + struct extent_buffer *next = read_tree_block(fs_info, + btrfs_node_blockptr(c, i), + btrfs_node_ptr_generation(c, i)); if (IS_ERR(next)) { continue; } else if (!extent_buffer_uptodate(next)) { diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index cdfff604724d..4fa3ed39015d 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1609,7 +1609,7 @@ int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans, return 0; if (!extent_buffer_uptodate(root_eb)) { - ret = btrfs_read_buffer(root_eb, root_gen, root_level, NULL); + ret = btrfs_read_buffer(root_eb, root_gen); if (ret) goto out; } @@ -1640,7 +1640,6 @@ int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans, level = root_level; while (level >= 0) { if (path->nodes[level] == NULL) { - struct btrfs_key first_key; int parent_slot; u64 child_gen; u64 child_bytenr; @@ -1653,10 +1652,8 @@ int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans, parent_slot = path->slots[level + 1]; child_bytenr = btrfs_node_blockptr(eb, parent_slot); child_gen = btrfs_node_ptr_generation(eb, parent_slot); - btrfs_node_key_to_cpu(eb, &first_key, parent_slot); - eb = read_tree_block(fs_info, child_bytenr, child_gen, - level, &first_key); + eb = read_tree_block(fs_info, child_bytenr, child_gen); if (IS_ERR(eb)) { ret = PTR_ERR(eb); goto out; diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c index aacfe2e58fa3..c3128d1baa4c 100644 --- a/fs/btrfs/ref-verify.c +++ b/fs/btrfs/ref-verify.c @@ -581,16 +581,11 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, while (level >= 0) { if (level) { - struct btrfs_key first_key; - block_bytenr = btrfs_node_blockptr(path->nodes[level], path->slots[level]); gen = btrfs_node_ptr_generation(path->nodes[level], path->slots[level]); - btrfs_node_key_to_cpu(path->nodes[level], &first_key, - path->slots[level]); - eb = read_tree_block(fs_info, block_bytenr, gen, - level - 1, &first_key); + eb = read_tree_block(fs_info, block_bytenr, gen); if (IS_ERR(eb)) return PTR_ERR(eb); if (!extent_buffer_uptodate(eb)) { diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index aaa33186648b..3a964c4303c7 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -1840,8 +1840,6 @@ int replace_path(struct btrfs_trans_handle *trans, parent = eb; while (1) { - struct btrfs_key first_key; - level = btrfs_header_level(parent); ASSERT(level >= lowest_level); @@ -1855,7 +1853,6 @@ int replace_path(struct btrfs_trans_handle *trans, old_bytenr = btrfs_node_blockptr(parent, slot); blocksize = fs_info->nodesize; old_ptr_gen = btrfs_node_ptr_generation(parent, slot); - btrfs_node_key_to_cpu(parent, &key, slot); if (level <= max_level) { eb = path->nodes[level]; @@ -1880,8 +1877,7 @@ int replace_path(struct btrfs_trans_handle *trans, break; } - eb = read_tree_block(fs_info, old_bytenr, old_ptr_gen, - level - 1, &first_key); + eb = read_tree_block(fs_info, old_bytenr, old_ptr_gen); if (IS_ERR(eb)) { ret = PTR_ERR(eb); break; @@ -2041,8 +2037,6 @@ int walk_down_reloc_tree(struct btrfs_root *root, struct btrfs_path *path, last_snapshot = btrfs_root_last_snapshot(&root->root_item); for (i = *level; i > 0; i--) { - struct btrfs_key first_key; - eb = path->nodes[i]; nritems = btrfs_header_nritems(eb); while (path->slots[i] < nritems) { @@ -2063,9 +2057,7 @@ int walk_down_reloc_tree(struct btrfs_root *root, struct btrfs_path *path, } bytenr = btrfs_node_blockptr(eb, path->slots[i]); - btrfs_node_key_to_cpu(eb, &first_key, path->slots[i]); - eb = read_tree_block(fs_info, bytenr, ptr_gen, i - 1, - &first_key); + eb = read_tree_block(fs_info, bytenr, ptr_gen); if (IS_ERR(eb)) { return PTR_ERR(eb); } else if (!extent_buffer_uptodate(eb)) { @@ -2740,8 +2732,6 @@ static int do_relocation(struct btrfs_trans_handle *trans, path->lowest_level = node->level + 1; rc->backref_cache.path[node->level] = node; list_for_each_entry(edge, &node->upper, list[LOWER]) { - struct btrfs_key first_key; - cond_resched(); upper = edge->node[UPPER]; @@ -2807,9 +2797,7 @@ static int do_relocation(struct btrfs_trans_handle *trans, blocksize = root->fs_info->nodesize; generation = btrfs_node_ptr_generation(upper->eb, slot); - btrfs_node_key_to_cpu(upper->eb, &first_key, slot); - eb = read_tree_block(fs_info, bytenr, generation, - upper->level - 1, &first_key); + eb = read_tree_block(fs_info, bytenr, generation); if (IS_ERR(eb)) { err = PTR_ERR(eb); goto next; @@ -2974,8 +2962,7 @@ static int get_tree_block_key(struct btrfs_fs_info *fs_info, struct extent_buffer *eb; BUG_ON(block->key_ready); - eb = read_tree_block(fs_info, block->bytenr, block->key.offset, - block->level, NULL); + eb = read_tree_block(fs_info, block->bytenr, block->key.offset); if (IS_ERR(eb)) { return PTR_ERR(eb); } else if (!extent_buffer_uptodate(eb)) { diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 8f774adb24f7..b353c93950dc 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -292,7 +292,7 @@ struct walk_control { * inside it */ int (*process_func)(struct btrfs_root *log, struct extent_buffer *eb, - struct walk_control *wc, u64 gen, int level); + struct walk_control *wc, u64 gen); }; /* @@ -300,7 +300,7 @@ struct walk_control { */ static int process_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, - struct walk_control *wc, u64 gen, int level) + struct walk_control *wc, u64 gen) { struct btrfs_fs_info *fs_info = log->fs_info; int ret = 0; @@ -310,7 +310,7 @@ static int process_one_buffer(struct btrfs_root *log, * pin down any logged extents, so we have to read the block. */ if (btrfs_fs_incompat(fs_info, MIXED_GROUPS)) { - ret = btrfs_read_buffer(eb, gen, level, NULL); + ret = btrfs_read_buffer(eb, gen); if (ret) return ret; } @@ -2335,16 +2335,17 @@ static noinline int replay_dir_deletes(struct btrfs_trans_handle *trans, * back refs). */ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, - struct walk_control *wc, u64 gen, int level) + struct walk_control *wc, u64 gen) { int nritems; struct btrfs_path *path; struct btrfs_root *root = wc->replay_dest; struct btrfs_key key; + int level; int i; int ret; - ret = btrfs_read_buffer(eb, gen, level, NULL); + ret = btrfs_read_buffer(eb, gen); if (ret) return ret; @@ -2498,8 +2499,6 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, WARN_ON(*level >= BTRFS_MAX_LEVEL); while (*level > 0) { - struct btrfs_key first_key; - WARN_ON(*level < 0); WARN_ON(*level >= BTRFS_MAX_LEVEL); cur = path->nodes[*level]; @@ -2512,7 +2511,6 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, bytenr = btrfs_node_blockptr(cur, path->slots[*level]); ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); - btrfs_node_key_to_cpu(cur, &first_key, path->slots[*level]); blocksize = fs_info->nodesize; parent = path->nodes[*level]; @@ -2523,8 +2521,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, return PTR_ERR(next); if (*level == 1) { - ret = wc->process_func(root, next, wc, ptr_gen, - *level - 1); + ret = wc->process_func(root, next, wc, ptr_gen); if (ret) { free_extent_buffer(next); return ret; @@ -2532,8 +2529,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, path->slots[*level]++; if (wc->free) { - ret = btrfs_read_buffer(next, ptr_gen, - *level - 1, &first_key); + ret = btrfs_read_buffer(next, ptr_gen); if (ret) { free_extent_buffer(next); return ret; @@ -2563,7 +2559,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, free_extent_buffer(next); continue; } - ret = btrfs_read_buffer(next, ptr_gen, *level - 1, &first_key); + ret = btrfs_read_buffer(next, ptr_gen); if (ret) { free_extent_buffer(next); return ret; @@ -2613,8 +2609,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans, root_owner = btrfs_header_owner(parent); ret = wc->process_func(root, path->nodes[*level], wc, - btrfs_header_generation(path->nodes[*level]), - *level); + btrfs_header_generation(path->nodes[*level])); if (ret) return ret; @@ -2696,8 +2691,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, /* was the root node processed? if not, catch it here */ if (path->nodes[orig_level]) { ret = wc->process_func(log, path->nodes[orig_level], wc, - btrfs_header_generation(path->nodes[orig_level]), - orig_level); + btrfs_header_generation(path->nodes[orig_level])); if (ret) goto out; if (wc->free) {