Messages in this thread Patch in this message | | | From | Jia-Ju Bai <> | Subject | [PATCH 1/4] fs: btrfs: fix a data race in btrfs_block_group_done() | Date | Sat, 9 May 2020 13:20:01 +0800 |
| |
The functions btrfs_block_group_done() and caching_thread() are concurrently executed at runtime in the following call contexts:
Thread 1: btrfs_sync_file() start_ordered_ops() btrfs_fdatawrite_range() btrfs_writepages() [via function pointer] extent_writepages() extent_write_cache_pages() __extent_writepage() writepage_delalloc() btrfs_run_delalloc_range() cow_file_range() btrfs_reserve_extent() find_free_extent() btrfs_block_group_done()
Thread 2: caching_thread()
In btrfs_block_group_done(): smp_mb(); return cache->cached == BTRFS_CACHE_FINISHED || cache->cached == BTRFS_CACHE_ERROR;
In caching_thread(): spin_lock(&block_group->lock); block_group->caching_ctl = NULL; block_group->cached = ret ? BTRFS_CACHE_ERROR : BTRFS_CACHE_FINISHED; spin_unlock(&block_group->lock);
The values cache->cached and block_group->cached access the same memory, and thus a data race can occur. This data race was found and actually reproduced by our concurrency fuzzer.
To fix this race, the spinlock cache->lock is used to protect the access to cache->cached in btrfs_block_group_done().
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com> --- fs/btrfs/block-group.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h index 107bb557ca8d..fb5f12acea40 100644 --- a/fs/btrfs/block-group.h +++ b/fs/btrfs/block-group.h @@ -278,9 +278,13 @@ static inline u64 btrfs_system_alloc_profile(struct btrfs_fs_info *fs_info) static inline int btrfs_block_group_done(struct btrfs_block_group *cache) { + int flag; smp_mb(); - return cache->cached == BTRFS_CACHE_FINISHED || - cache->cached == BTRFS_CACHE_ERROR; + spin_lock(&cache->lock); + flag = (cache->cached == BTRFS_CACHE_FINISHED || + cache->cached == BTRFS_CACHE_ERROR); + spin_unlock(&cache->lock); + return flag; } #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS -- 2.17.1
| |