diff options
| author | Filipe Manana <fdmanana@suse.com> | 2015-11-19 10:57:20 +0000 | 
|---|---|---|
| committer | Chris Mason <clm@fb.com> | 2015-11-25 05:19:51 -0800 | 
| commit | 020d5b7366fc03e4bf84142ae6f63031ac504e33 (patch) | |
| tree | 8f2c36c78f0d213d379e172f3a824c9d90ab1b2b /net/lapb/lapb_timer.c | |
| parent | 31388ab2edac833defa4193172edc1d409868bfb (diff) | |
Btrfs: fix race between scrub and block group deletion
Scrub can race with the cleaner kthread deleting block groups that are
unused (and with relocation too) leading to a failure with error -EINVAL
that gets returned to user space.
The following diagram illustrates how it happens:
              CPU 1                                 CPU 2
 cleaner kthread
   btrfs_delete_unused_bgs()
     gets block group X from
     fs_info->unused_bgs
     sets block group to RO
       btrfs_remove_chunk(bg X)
         deletes device extents
                                         scrub_enumerate_chunks()
                                           searches device tree using
                                           its commit root
                                           finds device extent for
                                           block group X
                                           gets block group X from the tree
                                           fs_info->block_group_cache_tree
                                           (via btrfs_lookup_block_group())
                                           sets bg X to RO (again)
          btrfs_remove_block_group(bg X)
            deletes block group from
            fs_info->block_group_cache_tree
            removes extent map from
            fs_info->mapping_tree
                                               scrub_chunk(offset X)
                                                 searches fs_info->mapping_tree
                                                 for extent map starting at
                                                 offset X
                                                    --> doesn't find any such
                                                        extent map
                                                    --> returns -EINVAL and scrub
                                                        errors out to userspace
                                                        with -EINVAL
Fix this by dealing with an extent map lookup failure as an indicator of
block group deletion.
Issue reproduced with fstest btrfs/071.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'net/lapb/lapb_timer.c')
0 files changed, 0 insertions, 0 deletions
