]> git.baikalelectronics.ru Git - kernel.git/commit
Btrfs: fix scrub preventing unused block groups from being deleted
authorFilipe Manana <fdmanana@suse.com>
Thu, 19 Nov 2015 11:45:48 +0000 (11:45 +0000)
committerChris Mason <clm@fb.com>
Wed, 25 Nov 2015 13:22:08 +0000 (05:22 -0800)
commit55c147f24dc00a4c7ca39faca58b4a4459442443
treea521154fb1e3384087e4a828197f69eca158d280
parent7dd4da814ac4939eb5811acbb7f1d523145646a6
Btrfs: fix scrub preventing unused block groups from being deleted

Currently scrub can race with the cleaner kthread when the later attempts
to delete an unused block group, and the result is preventing the cleaner
kthread from ever deleting later the block group - unless the block group
becomes used and unused again. The following diagram illustrates that
race:

              CPU 1                                 CPU 2

 cleaner kthread
   btrfs_delete_unused_bgs()

     gets block group X from
     fs_info->unused_bgs and
     removes it from that list

                                             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

     sees the block group is
     already RO and therefore
     doesn't delete it nor adds
     it back to unused list

So fix this by making scrub add the block group again to the list of
unused block groups if the block group is still unused when it finished
scrubbing it and it hasn't been removed already.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/scrub.c