aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2016-05-14 11:32:35 -0400
committerFilipe Manana <fdmanana@suse.com>2016-05-30 07:58:23 -0400
commit81e87a736c5581e83f52dc054b368993ec7f16d7 (patch)
tree35fdb32b543fa5e2d3a50d51875e9c2ade2a99a4 /fs
parentf0e9b7d6401959816599191d1d9db90b6fd750db (diff)
Btrfs: fix unprotected assignment of the left cursor for device replace
We were assigning new values to fields of the device replace object without holding the respective lock after processing each device extent. This is important for the left cursor field which can be accessed by a concurrent task running __btrfs_map_block (which, correctly, takes the device replace lock). So change these fields while holding the device replace lock. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Josef Bacik <jbacik@fb.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/scrub.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 1611572d47bd..19a1eda70361 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -3642,9 +3642,11 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
3642 break; 3642 break;
3643 } 3643 }
3644 3644
3645 btrfs_dev_replace_lock(&fs_info->dev_replace, 1);
3645 dev_replace->cursor_right = found_key.offset + length; 3646 dev_replace->cursor_right = found_key.offset + length;
3646 dev_replace->cursor_left = found_key.offset; 3647 dev_replace->cursor_left = found_key.offset;
3647 dev_replace->item_needs_writeback = 1; 3648 dev_replace->item_needs_writeback = 1;
3649 btrfs_dev_replace_unlock(&fs_info->dev_replace, 1);
3648 ret = scrub_chunk(sctx, scrub_dev, chunk_offset, length, 3650 ret = scrub_chunk(sctx, scrub_dev, chunk_offset, length,
3649 found_key.offset, cache, is_dev_replace); 3651 found_key.offset, cache, is_dev_replace);
3650 3652
@@ -3718,8 +3720,10 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
3718 break; 3720 break;
3719 } 3721 }
3720 3722
3723 btrfs_dev_replace_lock(&fs_info->dev_replace, 1);
3721 dev_replace->cursor_left = dev_replace->cursor_right; 3724 dev_replace->cursor_left = dev_replace->cursor_right;
3722 dev_replace->item_needs_writeback = 1; 3725 dev_replace->item_needs_writeback = 1;
3726 btrfs_dev_replace_unlock(&fs_info->dev_replace, 1);
3723skip: 3727skip:
3724 key.offset = found_key.offset + length; 3728 key.offset = found_key.offset + length;
3725 btrfs_release_path(path); 3729 btrfs_release_path(path);