diff options
Diffstat (limited to 'fs/btrfs/relocation.c')
-rw-r--r-- | fs/btrfs/relocation.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index b1ef27cc673b..5e0a3dc79a45 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -1368,7 +1368,7 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans, | |||
1368 | int ret; | 1368 | int ret; |
1369 | 1369 | ||
1370 | if (!root->reloc_root) | 1370 | if (!root->reloc_root) |
1371 | return 0; | 1371 | goto out; |
1372 | 1372 | ||
1373 | reloc_root = root->reloc_root; | 1373 | reloc_root = root->reloc_root; |
1374 | root_item = &reloc_root->root_item; | 1374 | root_item = &reloc_root->root_item; |
@@ -1390,6 +1390,8 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans, | |||
1390 | ret = btrfs_update_root(trans, root->fs_info->tree_root, | 1390 | ret = btrfs_update_root(trans, root->fs_info->tree_root, |
1391 | &reloc_root->root_key, root_item); | 1391 | &reloc_root->root_key, root_item); |
1392 | BUG_ON(ret); | 1392 | BUG_ON(ret); |
1393 | |||
1394 | out: | ||
1393 | return 0; | 1395 | return 0; |
1394 | } | 1396 | } |
1395 | 1397 | ||
@@ -2142,10 +2144,11 @@ int prepare_to_merge(struct reloc_control *rc, int err) | |||
2142 | u64 num_bytes = 0; | 2144 | u64 num_bytes = 0; |
2143 | int ret; | 2145 | int ret; |
2144 | 2146 | ||
2145 | spin_lock(&root->fs_info->trans_lock); | 2147 | mutex_lock(&root->fs_info->reloc_mutex); |
2146 | rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2; | 2148 | rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2; |
2147 | rc->merging_rsv_size += rc->nodes_relocated * 2; | 2149 | rc->merging_rsv_size += rc->nodes_relocated * 2; |
2148 | spin_unlock(&root->fs_info->trans_lock); | 2150 | mutex_unlock(&root->fs_info->reloc_mutex); |
2151 | |||
2149 | again: | 2152 | again: |
2150 | if (!err) { | 2153 | if (!err) { |
2151 | num_bytes = rc->merging_rsv_size; | 2154 | num_bytes = rc->merging_rsv_size; |
@@ -2214,9 +2217,16 @@ int merge_reloc_roots(struct reloc_control *rc) | |||
2214 | int ret; | 2217 | int ret; |
2215 | again: | 2218 | again: |
2216 | root = rc->extent_root; | 2219 | root = rc->extent_root; |
2217 | spin_lock(&root->fs_info->trans_lock); | 2220 | |
2221 | /* | ||
2222 | * this serializes us with btrfs_record_root_in_transaction, | ||
2223 | * we have to make sure nobody is in the middle of | ||
2224 | * adding their roots to the list while we are | ||
2225 | * doing this splice | ||
2226 | */ | ||
2227 | mutex_lock(&root->fs_info->reloc_mutex); | ||
2218 | list_splice_init(&rc->reloc_roots, &reloc_roots); | 2228 | list_splice_init(&rc->reloc_roots, &reloc_roots); |
2219 | spin_unlock(&root->fs_info->trans_lock); | 2229 | mutex_unlock(&root->fs_info->reloc_mutex); |
2220 | 2230 | ||
2221 | while (!list_empty(&reloc_roots)) { | 2231 | while (!list_empty(&reloc_roots)) { |
2222 | found = 1; | 2232 | found = 1; |
@@ -3590,17 +3600,19 @@ next: | |||
3590 | static void set_reloc_control(struct reloc_control *rc) | 3600 | static void set_reloc_control(struct reloc_control *rc) |
3591 | { | 3601 | { |
3592 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; | 3602 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; |
3593 | spin_lock(&fs_info->trans_lock); | 3603 | |
3604 | mutex_lock(&fs_info->reloc_mutex); | ||
3594 | fs_info->reloc_ctl = rc; | 3605 | fs_info->reloc_ctl = rc; |
3595 | spin_unlock(&fs_info->trans_lock); | 3606 | mutex_unlock(&fs_info->reloc_mutex); |
3596 | } | 3607 | } |
3597 | 3608 | ||
3598 | static void unset_reloc_control(struct reloc_control *rc) | 3609 | static void unset_reloc_control(struct reloc_control *rc) |
3599 | { | 3610 | { |
3600 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; | 3611 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; |
3601 | spin_lock(&fs_info->trans_lock); | 3612 | |
3613 | mutex_lock(&fs_info->reloc_mutex); | ||
3602 | fs_info->reloc_ctl = NULL; | 3614 | fs_info->reloc_ctl = NULL; |
3603 | spin_unlock(&fs_info->trans_lock); | 3615 | mutex_unlock(&fs_info->reloc_mutex); |
3604 | } | 3616 | } |
3605 | 3617 | ||
3606 | static int check_extent_flags(u64 flags) | 3618 | static int check_extent_flags(u64 flags) |