mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 08:46:46 +00:00
btrfs: fix racy access to discard_ctl data
Because only one discard worker may be running at any given point, it could have been safe to modify ->prev_discard, etc. without synchronization, if not for @override flag in btrfs_discard_schedule_work() and delayed_work_pending() returning false while workfn is running. That may lead to torn reads of u64 for some architectures, but that's not a big problem as only slightly affects the discard rate. Suggested-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
ea9ed87c73
commit
1ea2872fc6
1 changed files with 3 additions and 7 deletions
|
@ -477,13 +477,6 @@ static void btrfs_discard_workfn(struct work_struct *work)
|
||||||
discard_ctl->discard_extent_bytes += trimmed;
|
discard_ctl->discard_extent_bytes += trimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Updated without locks as this is inside the workfn and nothing else
|
|
||||||
* is reading the values
|
|
||||||
*/
|
|
||||||
discard_ctl->prev_discard = trimmed;
|
|
||||||
discard_ctl->prev_discard_time = ktime_get_ns();
|
|
||||||
|
|
||||||
/* Determine next steps for a block_group */
|
/* Determine next steps for a block_group */
|
||||||
if (block_group->discard_cursor >= btrfs_block_group_end(block_group)) {
|
if (block_group->discard_cursor >= btrfs_block_group_end(block_group)) {
|
||||||
if (discard_state == BTRFS_DISCARD_BITMAPS) {
|
if (discard_state == BTRFS_DISCARD_BITMAPS) {
|
||||||
|
@ -499,7 +492,10 @@ static void btrfs_discard_workfn(struct work_struct *work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
now = ktime_get_ns();
|
||||||
spin_lock(&discard_ctl->lock);
|
spin_lock(&discard_ctl->lock);
|
||||||
|
discard_ctl->prev_discard = trimmed;
|
||||||
|
discard_ctl->prev_discard_time = now;
|
||||||
discard_ctl->block_group = NULL;
|
discard_ctl->block_group = NULL;
|
||||||
spin_unlock(&discard_ctl->lock);
|
spin_unlock(&discard_ctl->lock);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue