Unverified Commit 388ff999 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11409 btrfs: do not start relocation until in progress drops are done

parents 154916b7 aafe92c5
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -565,6 +565,9 @@ enum {

	/* Indicate that we can't trust the free space tree for caching yet */
	BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED,

	/* Indicate we have half completed snapshot deletions pending. */
	BTRFS_FS_UNFINISHED_DROPS,
};

/*
@@ -1031,8 +1034,15 @@ enum {
	BTRFS_ROOT_HAS_LOG_TREE,
	/* Qgroup flushing is in progress */
	BTRFS_ROOT_QGROUP_FLUSHING,
	/* This root has a drop operation that was started previously. */
	BTRFS_ROOT_UNFINISHED_DROP,
};

static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info)
{
	clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
}

/*
 * Record swapped tree blocks of a subvolume tree for delayed subtree trace
 * code. For detail check comment in fs/btrfs/qgroup.c.
+10 −0
Original line number Diff line number Diff line
@@ -3444,6 +3444,10 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
	}
	set_bit(BTRFS_FS_OPEN, &fs_info->flags);

	/* Kick the cleaner thread so it'll start deleting snapshots. */
	if (test_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags))
		wake_up_process(fs_info->cleaner_kthread);

	/*
	 * backuproot only affect mount behavior, and if open_ctree succeeded,
	 * no need to keep the flag
@@ -4109,6 +4113,12 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
	 */
	kthread_park(fs_info->cleaner_kthread);

	/*
	 * If we had UNFINISHED_DROPS we could still be processing them, so
	 * clear that bit and wake up relocation so it can stop.
	 */
	btrfs_wake_unfinished_drop(fs_info);

	/* wait for the qgroup rescan worker to stop */
	btrfs_qgroup_wait_for_completion(fs_info, false);

+10 −0
Original line number Diff line number Diff line
@@ -5365,6 +5365,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
	int ret;
	int level;
	bool root_dropped = false;
	bool unfinished_drop = false;

	btrfs_debug(fs_info, "Drop subvolume %llu", root->root_key.objectid);

@@ -5407,6 +5408,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
	 * already dropped.
	 */
	set_bit(BTRFS_ROOT_DELETING, &root->state);
	unfinished_drop = test_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state);

	if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) {
		level = btrfs_header_level(root->node);
		path->nodes[level] = btrfs_lock_root_node(root);
@@ -5583,6 +5586,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
	kfree(wc);
	btrfs_free_path(path);
out:
	/*
	 * We were an unfinished drop root, check to see if there are any
	 * pending, and if not clear and wake up any waiters.
	 */
	if (!err && unfinished_drop)
		btrfs_maybe_wake_unfinished_drop(fs_info);

	/*
	 * So if we need to stop dropping the snapshot for whatever reason we
	 * need to make sure to add it back to the dead root list so that we
+13 −0
Original line number Diff line number Diff line
@@ -3601,6 +3601,19 @@ int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)
	int rw = 0;
	int err = 0;

	/*
	 * This only gets set if we had a half-deleted snapshot on mount.  We
	 * cannot allow relocation to start while we're still trying to clean up
	 * these pending deletions.
	 */
	ret = wait_on_bit(&fs_info->flags, BTRFS_FS_UNFINISHED_DROPS, TASK_INTERRUPTIBLE);
	if (ret)
		return ret;

	/* We may have been woken up by close_ctree, so bail if we're closing. */
	if (btrfs_fs_closing(fs_info))
		return -EINTR;

	bg = btrfs_lookup_block_group(fs_info, group_start);
	if (!bg)
		return -ENOENT;
+15 −0
Original line number Diff line number Diff line
@@ -280,6 +280,21 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)

		WARN_ON(!test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state));
		if (btrfs_root_refs(&root->root_item) == 0) {
			struct btrfs_key drop_key;

			btrfs_disk_key_to_cpu(&drop_key, &root->root_item.drop_progress);
			/*
			 * If we have a non-zero drop_progress then we know we
			 * made it partly through deleting this snapshot, and
			 * thus we need to make sure we block any balance from
			 * happening until this snapshot is completely dropped.
			 */
			if (drop_key.objectid != 0 || drop_key.type != 0 ||
			    drop_key.offset != 0) {
				set_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
				set_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state);
			}

			set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
			btrfs_add_dead_root(root);
		}
Loading