aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2016-05-14 14:44:40 -0400
committerFilipe Manana <fdmanana@suse.com>2016-05-30 07:58:24 -0400
commit1a1a8b732c7e958e6eba0680439e814efde2362d (patch)
tree1028ed1d30fbc490a1b40abbea9b35e9f364be1c /fs/btrfs
parent81e87a736c5581e83f52dc054b368993ec7f16d7 (diff)
Btrfs: fix race setting block group back to RW mode during device replace
After it finishes processing a device extent, the device replace code sets back the block group to RW mode and then after that it sets the left cursor to match the logical end address of the block group, so that future writes into extents belonging to the block group go both the source (old) and target (new) devices. However from the moment we turn the block group back to RW mode we have a short time window, that lasts until we update the left cursor's value, where extents can be allocated from the block group and written to, in which case they will not be copied/written to the target (new) device. Fix this by updating the left cursor's value before turning the block group back to RW mode. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Josef Bacik <jbacik@fb.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/scrub.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 19a1eda70361..70427ef66b04 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -3682,6 +3682,11 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
3682 3682
3683 scrub_pause_off(fs_info); 3683 scrub_pause_off(fs_info);
3684 3684
3685 btrfs_dev_replace_lock(&fs_info->dev_replace, 1);
3686 dev_replace->cursor_left = dev_replace->cursor_right;
3687 dev_replace->item_needs_writeback = 1;
3688 btrfs_dev_replace_unlock(&fs_info->dev_replace, 1);
3689
3685 if (ro_set) 3690 if (ro_set)
3686 btrfs_dec_block_group_ro(root, cache); 3691 btrfs_dec_block_group_ro(root, cache);
3687 3692
@@ -3719,11 +3724,6 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
3719 ret = -ENOMEM; 3724 ret = -ENOMEM;
3720 break; 3725 break;
3721 } 3726 }
3722
3723 btrfs_dev_replace_lock(&fs_info->dev_replace, 1);
3724 dev_replace->cursor_left = dev_replace->cursor_right;
3725 dev_replace->item_needs_writeback = 1;
3726 btrfs_dev_replace_unlock(&fs_info->dev_replace, 1);
3727skip: 3727skip:
3728 key.offset = found_key.offset + length; 3728 key.offset = found_key.offset + length;
3729 btrfs_release_path(path); 3729 btrfs_release_path(path);