btrfs-progs: Fix one-byte overlap bug in free_block_group_cache
authorQu Wenruo <quwenruo.btrfs@gmx.com>
Mon, 11 Sep 2017 06:36:07 +0000 (15:36 +0900)
committerDavid Sterba <dsterba@suse.com>
Mon, 25 Sep 2017 13:17:52 +0000 (15:17 +0200)
free_block_group_cache() calls clear_extent_bits() with wrong end, which
is one byte larger than the correct range.

This will cause the next adjacent cache state to be split.  And due to
the split, private pointer (which points to block group cache) will be
reset to NULL.

This is very hard to detect as this function only gets called in
cleanup_temp_chunks() which is just before mkfs finishes.  This bug only
gets exposed when reworking --rootdir option.

Signed-off-by: Qu Wenruo <quwenruo.btrfs@gmx.com>
Signed-off-by: David Sterba <dsterba@suse.com>
extent-tree.c

index eed5688..525a237 100644 (file)
@@ -3724,7 +3724,7 @@ static int free_block_group_cache(struct btrfs_trans_handle *trans,
                btrfs_remove_free_space_cache(cache);
                kfree(cache->free_space_ctl);
        }
-       clear_extent_bits(&fs_info->block_group_cache, bytenr, bytenr + len,
+       clear_extent_bits(&fs_info->block_group_cache, bytenr, bytenr + len - 1,
                          (unsigned int)-1);
        ret = free_space_info(fs_info, flags, len, 0, NULL);
        if (ret < 0)