Commit 882af9f1 authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba
Browse files

btrfs: handle free space tree rebuild in multiple transactions



During free space tree rebuild, we're holding a transaction handle for
the whole rebuild process.

This can lead to blocked task warning, e.g. btrfs-transaction kthread
(which is already created before btrfs_start_pre_rw_mount()) can be
waked up to join and commit the current transaction.

But the free space tree rebuild process may need to go through thousands
block groups, this will block btrfs-transaction kthread for a long time.

Fix the problem by calling btrfs_should_end_transaction() after each
block group, so that we won't hold the transaction handle too long.

And since the free-space-tree rebuild can be split into
multiple transactions, we need to consider the safety when the rebuild
process is interrupted.

Thankfully since we only set the FREE_SPACE_TREE compat_ro flag without
FREE_SPACE_TREE_VALID flag, even if the rebuild is interrupted, on the
next RW mount, we will still go rebuild the free space tree, by deleting
any items we have and re-starting the rebuild from scratch.

Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 6a2b3d7a
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1350,6 +1350,12 @@ int btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
			btrfs_end_transaction(trans);
			return ret;
		}
		if (btrfs_should_end_transaction(trans)) {
			btrfs_end_transaction(trans);
			trans = btrfs_start_transaction(free_space_root, 1);
			if (IS_ERR(trans))
				return PTR_ERR(trans);
		}
		node = rb_next(node);
	}