From patchwork Tue Oct 15 15:42:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 11190715 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8217A18A6 for ; Tue, 15 Oct 2019 15:42:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6BADD2086A for ; Tue, 15 Oct 2019 15:42:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729515AbfJOPma (ORCPT ); Tue, 15 Oct 2019 11:42:30 -0400 Received: from mx2.suse.de ([195.135.220.15]:44288 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727786AbfJOPma (ORCPT ); Tue, 15 Oct 2019 11:42:30 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 9620DB51F; Tue, 15 Oct 2019 15:42:28 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 1/8] btrfs: Cleanup and simplify find_newest_super_backup Date: Tue, 15 Oct 2019 18:42:17 +0300 Message-Id: <20191015154224.21537-2-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191015154224.21537-1-nborisov@suse.com> References: <20191015154224.21537-1-nborisov@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Backup roots are always written in a circular manner. By definition we can only ever have 1 backup root whose generation equals to that of the superblock. Hence, the 'if' in the for loop will trigger at most once. This is sufficient to return the newest backup root. Furthermore thew newest_gen parameter is always set to the generation of the superblock. This value can be obtained from the fs_info. This patch removes the unnecessary code dealing with the wraparound case and makes 'newest_gen' a local variable. --- fs/btrfs/disk-io.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index de5696023391..8b1f6385023d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1761,18 +1761,18 @@ static int transaction_kthread(void *arg) } /* - * this will find the highest generation in the array of + * This will find the highest generation in the array of * root backups. The index of the highest array is returned, - * or -1 if we can't find anything. + * or -EINVAL if we can't find anything. * * We check to make sure the array is valid by comparing the * generation of the latest root in the array with the generation * in the super block. If they don't match we pitch it. */ -static int find_newest_super_backup(struct btrfs_fs_info *info, u64 newest_gen) +static int find_newest_super_backup(struct btrfs_fs_info *info) { + u64 newest_gen = btrfs_super_generation(info->super_copy); u64 cur; - int newest_index = -1; struct btrfs_root_backup *root_backup; int i; @@ -1780,17 +1780,10 @@ static int find_newest_super_backup(struct btrfs_fs_info *info, u64 newest_gen) root_backup = info->super_copy->super_roots + i; cur = btrfs_backup_tree_root_gen(root_backup); if (cur == newest_gen) - newest_index = i; + return i; } - /* check to see if we actually wrapped around */ - if (newest_index == BTRFS_NUM_BACKUP_ROOTS - 1) { - root_backup = info->super_copy->super_roots; - cur = btrfs_backup_tree_root_gen(root_backup); - if (cur == newest_gen) - newest_index = 0; - } - return newest_index; + return -EINVAL; } @@ -1802,11 +1795,11 @@ static int find_newest_super_backup(struct btrfs_fs_info *info, u64 newest_gen) static void find_oldest_super_backup(struct btrfs_fs_info *info, u64 newest_gen) { - int newest_index = -1; + int newest_index; - newest_index = find_newest_super_backup(info, newest_gen); + newest_index = find_newest_super_backup(info); /* if there was garbage in there, just move along */ - if (newest_index == -1) { + if (newest_index == -EINVAL) { info->backup_root_index = 0; } else { info->backup_root_index = (newest_index + 1) % BTRFS_NUM_BACKUP_ROOTS; @@ -1923,9 +1916,7 @@ static noinline int next_root_backup(struct btrfs_fs_info *info, int newest = *backup_index; if (*num_backups_tried == 0) { - u64 gen = btrfs_super_generation(super); - - newest = find_newest_super_backup(info, gen); + newest = find_newest_super_backup(info); if (newest == -1) return -1; From patchwork Tue Oct 15 15:42:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 11190717 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 177B5912 for ; Tue, 15 Oct 2019 15:42:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 01482205F4 for ; Tue, 15 Oct 2019 15:42:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729870AbfJOPmc (ORCPT ); Tue, 15 Oct 2019 11:42:32 -0400 Received: from mx2.suse.de ([195.135.220.15]:44300 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726422AbfJOPma (ORCPT ); Tue, 15 Oct 2019 11:42:30 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id F3959B520; Tue, 15 Oct 2019 15:42:28 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 2/8] btrfs: Remove newest_gen argument from find_oldest_super_backup Date: Tue, 15 Oct 2019 18:42:18 +0300 Message-Id: <20191015154224.21537-3-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191015154224.21537-1-nborisov@suse.com> References: <20191015154224.21537-1-nborisov@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org It's no longer needed following cleanups around find_newest_backup_root --- fs/btrfs/disk-io.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8b1f6385023d..d51f76abde45 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1792,8 +1792,7 @@ static int find_newest_super_backup(struct btrfs_fs_info *info) * in the backup array. This will set the backup_root_index * field in the fs_info struct */ -static void find_oldest_super_backup(struct btrfs_fs_info *info, - u64 newest_gen) +static void find_oldest_super_backup(struct btrfs_fs_info *info) { int newest_index; @@ -2831,8 +2830,7 @@ int __cold open_ctree(struct super_block *sb, * run through our array of backup supers and setup * our ring pointer to the oldest one */ - generation = btrfs_super_generation(disk_super); - find_oldest_super_backup(fs_info, generation); + find_oldest_super_backup(fs_info); /* * In the long term, we'll store the compression type in the super From patchwork Tue Oct 15 15:42:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 11190721 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 10DD315AB for ; Tue, 15 Oct 2019 15:42:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E3AC02086A for ; Tue, 15 Oct 2019 15:42:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730124AbfJOPmd (ORCPT ); Tue, 15 Oct 2019 11:42:33 -0400 Received: from mx2.suse.de ([195.135.220.15]:44306 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728991AbfJOPmb (ORCPT ); Tue, 15 Oct 2019 11:42:31 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 5C721B517; Tue, 15 Oct 2019 15:42:29 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 3/8] btrfs: Add read_backup_root Date: Tue, 15 Oct 2019 18:42:19 +0300 Message-Id: <20191015154224.21537-4-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191015154224.21537-1-nborisov@suse.com> References: <20191015154224.21537-1-nborisov@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This function will replace next_root_backup with a much saner/cleaner interface. --- fs/btrfs/disk-io.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index d51f76abde45..9ed3b40aa10d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1899,6 +1899,50 @@ static void backup_super_roots(struct btrfs_fs_info *info) sizeof(*root_backup) * BTRFS_NUM_BACKUP_ROOTS); } +/* + * read_backup_root - Reads a backup root based on the passed priority. Prio 0 + * is the newest, prio 1/2/3 are 2nd newest/3rd newest/4th (oldest) backup roots + * + * fs_info - filesystem whose backup roots need to be read + * priority - priority of backup root required + * + * Returns backup root index on success and -EINVAL otherwise. + */ +static int read_backup_root(struct btrfs_fs_info *fs_info, u8 priority) +{ + int backup_index = find_newest_super_backup(fs_info); + struct btrfs_super_block *super = fs_info->super_copy; + struct btrfs_root_backup *root_backup; + + if (priority < BTRFS_NUM_BACKUP_ROOTS && backup_index >= 0) { + if (priority == 0) + return backup_index; + + backup_index = (backup_index + BTRFS_NUM_BACKUP_ROOTS - priority) % + BTRFS_NUM_BACKUP_ROOTS; + } else { + return -EINVAL; + } + + root_backup = super->super_roots + backup_index; + + btrfs_set_super_generation(super, + btrfs_backup_tree_root_gen(root_backup)); + btrfs_set_super_root(super, btrfs_backup_tree_root(root_backup)); + btrfs_set_super_root_level(super, + btrfs_backup_tree_root_level(root_backup)); + btrfs_set_super_bytes_used(super, btrfs_backup_bytes_used(root_backup)); + + /* + * fixme: the total bytes and num_devices need to match or we should + * need a fsck + */ + btrfs_set_super_total_bytes(super, btrfs_backup_total_bytes(root_backup)); + btrfs_set_super_num_devices(super, btrfs_backup_num_devices(root_backup)); + + return backup_index; +} + /* * this copies info out of the root backup array and back into * the in-memory super block. It is meant to help iterate through From patchwork Tue Oct 15 15:42:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 11190719 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 58EE5912 for ; Tue, 15 Oct 2019 15:42:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 42315205F4 for ; Tue, 15 Oct 2019 15:42:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730237AbfJOPmd (ORCPT ); Tue, 15 Oct 2019 11:42:33 -0400 Received: from mx2.suse.de ([195.135.220.15]:44312 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729578AbfJOPmb (ORCPT ); Tue, 15 Oct 2019 11:42:31 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id BA350B51A; Tue, 15 Oct 2019 15:42:29 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 4/8] btrfs: Factor out tree roots initialization during mount Date: Tue, 15 Oct 2019 18:42:20 +0300 Message-Id: <20191015154224.21537-5-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191015154224.21537-1-nborisov@suse.com> References: <20191015154224.21537-1-nborisov@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org The code responsible for reading and initilizing tree roots is scattered in open_ctree among 2 labels, emulating a loop. This is rather confusing to reason about. Instead, factor the code in a new function, init_tree_roots which implements the same logical flow. There are a couple of notable differences, namely: * Instead of using next_backup_root it's using the newly introduced read_backup_root. * If read_backup_root returns an error init_tree_roots propagates the error and there is no special handling of that case e.g. the code jumps straight to 'fail_tree_roots' label. The old code, however, was (erroneously) jumping to 'fail_block_groups' label if next_backup_root did fail, this was unnecessary since the tree roots init logic doesn't modify the state of block groups. --- fs/btrfs/disk-io.c | 140 +++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 57 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 9ed3b40aa10d..a82e3acca765 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2581,6 +2581,87 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info, return ret; } +int __cold init_tree_roots(struct btrfs_fs_info *fs_info) +{ + struct btrfs_super_block *sb = fs_info->super_copy; + struct btrfs_root *tree_root = fs_info->tree_root; + bool handle_error = false; + int ret = 0; + int i; + + for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) { + u64 generation; + int level; + + if (handle_error) { + if (!IS_ERR(tree_root->node)) + free_extent_buffer(tree_root->node); + tree_root->node = NULL; + + if (!btrfs_test_opt(fs_info, USEBACKUPROOT)) + break; + + free_root_pointers(fs_info, 0); + + /* don't use the log in recovery mode, it won't be valid */ + btrfs_set_super_log_root(sb, 0); + + /* we can't trust the free space cache either */ + btrfs_set_opt(fs_info->mount_opt, CLEAR_CACHE); + + ret = read_backup_root(fs_info, i); + if (ret < 0) + return ret; + } + generation = btrfs_super_generation(sb); + level = btrfs_super_root_level(sb); + tree_root->node = read_tree_block(fs_info, btrfs_super_root(sb), + generation, level, NULL); + if (IS_ERR(tree_root->node) || + !extent_buffer_uptodate(tree_root->node)) { + handle_error = true; + + if (IS_ERR(tree_root->node)) + ret = PTR_ERR(tree_root->node); + else if (!extent_buffer_uptodate(tree_root->node)) + ret = -EUCLEAN; + + btrfs_warn(fs_info, "failed to read tree root"); + continue; + } + + btrfs_set_root_node(&tree_root->root_item, tree_root->node); + tree_root->commit_root = btrfs_root_node(tree_root); + btrfs_set_root_refs(&tree_root->root_item, 1); + + mutex_lock(&tree_root->objectid_mutex); + ret = btrfs_find_highest_objectid(tree_root, + &tree_root->highest_objectid); + if (ret < 0) { + mutex_unlock(&tree_root->objectid_mutex); + handle_error = true; + continue; + } + + ASSERT(tree_root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID); + mutex_unlock(&tree_root->objectid_mutex); + + ret = btrfs_read_roots(fs_info); + if (ret < 0) { + handle_error = true; + continue; + } + + /* All successful */ + fs_info->generation = generation; + fs_info->last_trans_committed = generation; + break; + + } + + return ret; +} + int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices, char *options) @@ -2599,8 +2680,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_root *chunk_root; int ret; int err = -EINVAL; - int num_backups_tried = 0; - int backup_index = 0; int clear_free_space_tree = 0; int level; @@ -3022,44 +3101,9 @@ int __cold open_ctree(struct super_block *sb, goto fail_tree_roots; } -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); - if (IS_ERR(tree_root->node) || - !extent_buffer_uptodate(tree_root->node)) { - btrfs_warn(fs_info, "failed to read tree root"); - if (!IS_ERR(tree_root->node)) - free_extent_buffer(tree_root->node); - tree_root->node = NULL; - goto recovery_tree_root; - } - - btrfs_set_root_node(&tree_root->root_item, tree_root->node); - tree_root->commit_root = btrfs_root_node(tree_root); - btrfs_set_root_refs(&tree_root->root_item, 1); - - mutex_lock(&tree_root->objectid_mutex); - ret = btrfs_find_highest_objectid(tree_root, - &tree_root->highest_objectid); - if (ret) { - mutex_unlock(&tree_root->objectid_mutex); - goto recovery_tree_root; - } - - ASSERT(tree_root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID); - - mutex_unlock(&tree_root->objectid_mutex); - - ret = btrfs_read_roots(fs_info); + ret = init_tree_roots(fs_info); if (ret) - goto recovery_tree_root; - - fs_info->generation = generation; - fs_info->last_trans_committed = generation; + goto fail_tree_roots; ret = btrfs_verify_dev_extents(fs_info); if (ret) { @@ -3354,24 +3398,6 @@ int __cold open_ctree(struct super_block *sb, btrfs_free_stripe_hash_table(fs_info); btrfs_close_devices(fs_info->fs_devices); return err; - -recovery_tree_root: - if (!btrfs_test_opt(fs_info, USEBACKUPROOT)) - goto fail_tree_roots; - - free_root_pointers(fs_info, false); - - /* don't use the log in recovery mode, it won't be valid */ - btrfs_set_super_log_root(disk_super, 0); - - /* we can't trust the free space cache either */ - btrfs_set_opt(fs_info->mount_opt, CLEAR_CACHE); - - ret = next_root_backup(fs_info, fs_info->super_copy, - &num_backups_tried, &backup_index); - if (ret == -1) - goto fail_block_groups; - goto retry_root_backup; } ALLOW_ERROR_INJECTION(open_ctree, ERRNO); From patchwork Tue Oct 15 15:42:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 11190727 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D7F0715AB for ; Tue, 15 Oct 2019 15:42:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C0FBC2086A for ; Tue, 15 Oct 2019 15:42:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730845AbfJOPmh (ORCPT ); Tue, 15 Oct 2019 11:42:37 -0400 Received: from mx2.suse.de ([195.135.220.15]:44318 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727786AbfJOPmb (ORCPT ); Tue, 15 Oct 2019 11:42:31 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 23229B521; Tue, 15 Oct 2019 15:42:30 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 5/8] btrfs: Don't use objectid_mutex during mount Date: Tue, 15 Oct 2019 18:42:21 +0300 Message-Id: <20191015154224.21537-6-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191015154224.21537-1-nborisov@suse.com> References: <20191015154224.21537-1-nborisov@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Since the filesystem is not well formed and no trees are loaded it's pointless holding the objectid_mutex. Just remove its usage. --- fs/btrfs/disk-io.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index a82e3acca765..418619dfb76c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2634,17 +2634,18 @@ int __cold init_tree_roots(struct btrfs_fs_info *fs_info) tree_root->commit_root = btrfs_root_node(tree_root); btrfs_set_root_refs(&tree_root->root_item, 1); - mutex_lock(&tree_root->objectid_mutex); + /* + * No need to hold btrfs_root::objectid_mutex since the fs + * hasn't been fully initialised and we are the only user + */ ret = btrfs_find_highest_objectid(tree_root, &tree_root->highest_objectid); if (ret < 0) { - mutex_unlock(&tree_root->objectid_mutex); handle_error = true; continue; } ASSERT(tree_root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID); - mutex_unlock(&tree_root->objectid_mutex); ret = btrfs_read_roots(fs_info); if (ret < 0) { From patchwork Tue Oct 15 15:42:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 11190729 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7B76C17E6 for ; Tue, 15 Oct 2019 15:42:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 58D26205F4 for ; Tue, 15 Oct 2019 15:42:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731060AbfJOPmi (ORCPT ); Tue, 15 Oct 2019 11:42:38 -0400 Received: from mx2.suse.de ([195.135.220.15]:44324 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729592AbfJOPmc (ORCPT ); Tue, 15 Oct 2019 11:42:32 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 82ACFB522; Tue, 15 Oct 2019 15:42:30 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 6/8] btrfs: Remove unused next_root_backup function Date: Tue, 15 Oct 2019 18:42:22 +0300 Message-Id: <20191015154224.21537-7-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191015154224.21537-1-nborisov@suse.com> References: <20191015154224.21537-1-nborisov@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This function is no longer used so just remove it --- fs/btrfs/disk-io.c | 50 ---------------------------------------------- 1 file changed, 50 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 418619dfb76c..bcb21a35d30c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1943,56 +1943,6 @@ static int read_backup_root(struct btrfs_fs_info *fs_info, u8 priority) return backup_index; } -/* - * this copies info out of the root backup array and back into - * the in-memory super block. It is meant to help iterate through - * the array, so you send it the number of backups you've already - * tried and the last backup index you used. - * - * this returns -1 when it has tried all the backups - */ -static noinline int next_root_backup(struct btrfs_fs_info *info, - struct btrfs_super_block *super, - int *num_backups_tried, int *backup_index) -{ - struct btrfs_root_backup *root_backup; - int newest = *backup_index; - - if (*num_backups_tried == 0) { - newest = find_newest_super_backup(info); - if (newest == -1) - return -1; - - *backup_index = newest; - *num_backups_tried = 1; - } else if (*num_backups_tried == BTRFS_NUM_BACKUP_ROOTS) { - /* we've tried all the backups, all done */ - return -1; - } else { - /* jump to the next oldest backup */ - newest = (*backup_index + BTRFS_NUM_BACKUP_ROOTS - 1) % - BTRFS_NUM_BACKUP_ROOTS; - *backup_index = newest; - *num_backups_tried += 1; - } - root_backup = super->super_roots + newest; - - btrfs_set_super_generation(super, - btrfs_backup_tree_root_gen(root_backup)); - btrfs_set_super_root(super, btrfs_backup_tree_root(root_backup)); - btrfs_set_super_root_level(super, - btrfs_backup_tree_root_level(root_backup)); - btrfs_set_super_bytes_used(super, btrfs_backup_bytes_used(root_backup)); - - /* - * fixme: the total bytes and num_devices need to match or we should - * need a fsck - */ - btrfs_set_super_total_bytes(super, btrfs_backup_total_bytes(root_backup)); - btrfs_set_super_num_devices(super, btrfs_backup_num_devices(root_backup)); - return 0; -} - /* helper to cleanup workers */ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info) { From patchwork Tue Oct 15 15:42:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 11190723 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E52C115AB for ; Tue, 15 Oct 2019 15:42:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C5A582086A for ; Tue, 15 Oct 2019 15:42:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730422AbfJOPmf (ORCPT ); Tue, 15 Oct 2019 11:42:35 -0400 Received: from mx2.suse.de ([195.135.220.15]:44330 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727429AbfJOPmc (ORCPT ); Tue, 15 Oct 2019 11:42:32 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id DF861B523; Tue, 15 Oct 2019 15:42:30 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 7/8] btrfs: Rename find_oldest_super_backup to init_backup_root_slot Date: Tue, 15 Oct 2019 18:42:23 +0300 Message-Id: <20191015154224.21537-8-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191015154224.21537-1-nborisov@suse.com> References: <20191015154224.21537-1-nborisov@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org The old name name was an awful misnomer because it didn't really find the oldest super backup per se but rather its slot. For example if we have: slot0: gen - 2 slot1: gen - 1 slot2: gen slot3: empty init_backup_root_slot will return slot3 and not slot0. The new name is more appropriate since the function doesn't care whether there is a valid backup in the returned slot or not. --- fs/btrfs/disk-io.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index bcb21a35d30c..ac899fdb1414 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1786,13 +1786,11 @@ static int find_newest_super_backup(struct btrfs_fs_info *info) return -EINVAL; } - /* - * find the oldest backup so we know where to store new entries - * in the backup array. This will set the backup_root_index - * field in the fs_info struct + * Initialize backup_root_index with the next available slot, where subsequent + * transaction commit will store the back up root */ -static void find_oldest_super_backup(struct btrfs_fs_info *info) +static void init_backup_root_slot(struct btrfs_fs_info *info) { int newest_index; @@ -2904,7 +2902,7 @@ int __cold open_ctree(struct super_block *sb, * run through our array of backup supers and setup * our ring pointer to the oldest one */ - find_oldest_super_backup(fs_info); + init_backup_root_slot(fs_info); /* * In the long term, we'll store the compression type in the super From patchwork Tue Oct 15 15:42:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 11190725 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D7EED912 for ; Tue, 15 Oct 2019 15:42:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C23482086A for ; Tue, 15 Oct 2019 15:42:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730668AbfJOPmg (ORCPT ); Tue, 15 Oct 2019 11:42:36 -0400 Received: from mx2.suse.de ([195.135.220.15]:44312 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729876AbfJOPme (ORCPT ); Tue, 15 Oct 2019 11:42:34 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 47DFCB526; Tue, 15 Oct 2019 15:42:31 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 8/8] btrfs: Streamline btrfs_fs_info::backup_root_index semantics Date: Tue, 15 Oct 2019 18:42:24 +0300 Message-Id: <20191015154224.21537-9-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191015154224.21537-1-nborisov@suse.com> References: <20191015154224.21537-1-nborisov@suse.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org The backup_root_index member stores the index at which the backup root should be saved upon next transaction commit. However, there is a small deviation from this behavior in the form of a check in backup_super_roots which checks if current root generation equals to the generation of the previous root. This can trigger in the following scenario: slot0: gen-2 slot1: gen-1 slot2: gen slot3: unused Now suppose slot3 (which is also the root specified in the super block) is corrupted hence init_tree_roots chooses to use the backup root at slot2, meaning read_backup_root will read slot2 and assign the superblock generation to gen-1. Despite this backup_root_index will point at slot3 because its init happens in init_backup_root_slot, long before any parsing of the backup roots occur. Then on next transaction start, gen-1 will be incremented by 1 making the root's generation equal gen. Subsequently, on transaction commit the following check triggers: if (btrfs_backup_tree_root_gen(root_backup) == btrfs_header_generation(info->tree_root->node)) This causes the 'next_backup', which is the index at which the backup is going to be written to, to set to last_backup, which will be slot2. All of this is a very confusing way of expressing the following invariant: Always write a backup root at the index following the last used backup root. This commit streamlines this logic by setting backup_root_index to the next index after the one used for mount. --- fs/btrfs/disk-io.c | 48 +++++++++------------------------------------- 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index ac899fdb1414..e266949529fb 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1786,23 +1786,6 @@ static int find_newest_super_backup(struct btrfs_fs_info *info) return -EINVAL; } -/* - * Initialize backup_root_index with the next available slot, where subsequent - * transaction commit will store the back up root - */ -static void init_backup_root_slot(struct btrfs_fs_info *info) -{ - int newest_index; - - newest_index = find_newest_super_backup(info); - /* if there was garbage in there, just move along */ - if (newest_index == -EINVAL) { - info->backup_root_index = 0; - } else { - info->backup_root_index = (newest_index + 1) % BTRFS_NUM_BACKUP_ROOTS; - } -} - /* * copy all the root pointers into the super backup array. * this will bump the backup pointer by one when it is @@ -1810,22 +1793,8 @@ static void init_backup_root_slot(struct btrfs_fs_info *info) */ static void backup_super_roots(struct btrfs_fs_info *info) { - int next_backup; + int next_backup = info->backup_root_index; struct btrfs_root_backup *root_backup; - int last_backup; - - next_backup = info->backup_root_index; - last_backup = (next_backup + BTRFS_NUM_BACKUP_ROOTS - 1) % - BTRFS_NUM_BACKUP_ROOTS; - - /* - * just overwrite the last backup if we're at the same generation - * this happens only at umount - */ - root_backup = info->super_for_commit->super_roots + last_backup; - if (btrfs_backup_tree_root_gen(root_backup) == - btrfs_header_generation(info->tree_root->node)) - next_backup = last_backup; root_backup = info->super_for_commit->super_roots + next_backup; @@ -2531,6 +2500,7 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info, int __cold init_tree_roots(struct btrfs_fs_info *fs_info) { + int backup_index = find_newest_super_backup(fs_info); struct btrfs_super_block *sb = fs_info->super_copy; struct btrfs_root *tree_root = fs_info->tree_root; bool handle_error = false; @@ -2557,7 +2527,7 @@ int __cold init_tree_roots(struct btrfs_fs_info *fs_info) /* we can't trust the free space cache either */ btrfs_set_opt(fs_info->mount_opt, CLEAR_CACHE); - ret = read_backup_root(fs_info, i); + ret = backup_index = read_backup_root(fs_info, i); if (ret < 0) return ret; } @@ -2604,6 +2574,12 @@ int __cold init_tree_roots(struct btrfs_fs_info *fs_info) /* All successful */ fs_info->generation = generation; fs_info->last_trans_committed = generation; + + /* Always begin writing backup roots after one being used */ + if (backup_index < 0) + fs_info->backup_root_index = 0; + else + fs_info->backup_root_index = (backup_index + 1) % BTRFS_NUM_BACKUP_ROOTS; break; } @@ -2898,12 +2874,6 @@ int __cold open_ctree(struct super_block *sb, if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_ERROR) set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state); - /* - * run through our array of backup supers and setup - * our ring pointer to the oldest one - */ - init_backup_root_slot(fs_info); - /* * In the long term, we'll store the compression type in the super * block, and it'll be used for per file compression control.