Commit 44a6c343 authored by David Sterba's avatar David Sterba
Browse files

btrfs: return errors from unpin_extent_range()



Handle the lookup failure of the block group to unpin, this is a logic
error as the block group must exist at this point. If not, something else
must have freed it, like clean_pinned_extents() would do without locking
the unused_bg_unpin_mutex.

Push the errors to the callers, proper handling will be done in followup
patches.

Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent c03c89f8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1429,7 +1429,7 @@ static bool clean_pinned_extents(struct btrfs_trans_handle *trans,
	 * group in pinned_extents before we were able to clear the whole block
	 * group range from pinned_extents. This means that task can lookup for
	 * the block group after we unpinned it from pinned_extents and removed
	 * it, leading to a BUG_ON() at unpin_extent_range().
	 * it, leading to an error at unpin_extent_range().
	 */
	mutex_lock(&fs_info->unused_bg_unpin_mutex);
	if (prev_trans) {
+15 −4
Original line number Diff line number Diff line
@@ -2777,6 +2777,7 @@ static int unpin_extent_range(struct btrfs_fs_info *fs_info,
	u64 total_unpinned = 0;
	u64 empty_cluster = 0;
	bool readonly;
	int ret = 0;

	while (start <= end) {
		readonly = false;
@@ -2786,7 +2787,11 @@ static int unpin_extent_range(struct btrfs_fs_info *fs_info,
				btrfs_put_block_group(cache);
			total_unpinned = 0;
			cache = btrfs_lookup_block_group(fs_info, start);
			BUG_ON(!cache); /* Logic error */
			if (cache == NULL) {
				/* Logic error, something removed the block group. */
				ret = -EUCLEAN;
				goto out;
			}

			cluster = fetch_cluster_info(fs_info,
						     cache->space_info,
@@ -2855,7 +2860,8 @@ static int unpin_extent_range(struct btrfs_fs_info *fs_info,

	if (cache)
		btrfs_put_block_group(cache);
	return 0;
out:
	return ret;
}

int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
@@ -2885,7 +2891,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
						   end + 1 - start, NULL);

		clear_extent_dirty(unpin, start, end, &cached_state);
		unpin_extent_range(fs_info, start, end, true);
		ret = unpin_extent_range(fs_info, start, end, true);
		BUG_ON(ret);
		mutex_unlock(&fs_info->unused_bg_unpin_mutex);
		free_extent_state(cached_state);
		cond_resched();
@@ -6167,7 +6174,11 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info,
				   u64 start, u64 end)
{
	return unpin_extent_range(fs_info, start, end, false);
	int ret;

	ret = unpin_extent_range(fs_info, start, end, false);
	BUG_ON(ret);
	return ret;
}

/*