summaryrefslogtreecommitdiff
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 648bb09fc416..6b8e810a35ce 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -3587,7 +3587,7 @@ int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset, bool v
/* step one, relocate all the extents inside this chunk */
btrfs_scrub_pause(fs_info);
- ret = btrfs_relocate_block_group(fs_info, chunk_offset, true);
+ ret = btrfs_relocate_block_group(fs_info, chunk_offset, verbose);
btrfs_scrub_continue(fs_info);
if (ret) {
/*
@@ -4277,20 +4277,29 @@ static int balance_remap_chunks(struct btrfs_fs_info *fs_info, struct btrfs_path
end:
while (!list_empty(chunks)) {
bool is_unused;
+ struct btrfs_block_group *bg;
rci = list_first_entry(chunks, struct remap_chunk_info, list);
- spin_lock(&rci->bg->lock);
- is_unused = !btrfs_is_block_group_used(rci->bg);
- spin_unlock(&rci->bg->lock);
+ bg = rci->bg;
+ if (bg) {
+ /*
+ * This is a bit racy and the 'used' status can change
+ * but this is not a problem as later functions will
+ * verify it again.
+ */
+ spin_lock(&bg->lock);
+ is_unused = !btrfs_is_block_group_used(bg);
+ spin_unlock(&bg->lock);
- if (is_unused)
- btrfs_mark_bg_unused(rci->bg);
+ if (is_unused)
+ btrfs_mark_bg_unused(bg);
- if (rci->made_ro)
- btrfs_dec_block_group_ro(rci->bg);
+ if (rci->made_ro)
+ btrfs_dec_block_group_ro(bg);
- btrfs_put_block_group(rci->bg);
+ btrfs_put_block_group(bg);
+ }
list_del(&rci->list);
kfree(rci);
@@ -8090,8 +8099,9 @@ int btrfs_run_dev_stats(struct btrfs_trans_handle *trans)
smp_rmb();
ret = update_dev_stat_item(trans, device);
- if (!ret)
- atomic_sub(stats_cnt, &device->dev_stats_ccnt);
+ if (ret)
+ break;
+ atomic_sub(stats_cnt, &device->dev_stats_ccnt);
}
mutex_unlock(&fs_devices->device_list_mutex);