summaryrefslogtreecommitdiff
path: root/fs/btrfs
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@lsd.ic.unicamp.br>2011-11-28 12:04:43 -0200
committerDavid Sterba <dsterba@suse.cz>2011-11-30 18:46:06 +0100
commitf2d0f6765d6332f9be732965a0c6f3b8a55082b4 (patch)
treec9855b6e259e6b464c95b7ff0b9419023d02d703 /fs/btrfs
parentb772a86ea6d932ac29d5e50e67c977653c832f8a (diff)
downloadkernel-common-f2d0f6765d6332f9be732965a0c6f3b8a55082b4.tar.gz
kernel-common-f2d0f6765d6332f9be732965a0c6f3b8a55082b4.tar.bz2
kernel-common-f2d0f6765d6332f9be732965a0c6f3b8a55082b4.zip
Btrfs: initialize new bitmaps' list
We're failing to create clusters with bitmaps because setup_cluster_no_bitmap checks that the list is empty before inserting the bitmap entry in the list for setup_cluster_bitmap, but the list field is only initialized when it is restored from the on-disk free space cache, or when it is written out to disk. Besides a potential race condition due to the multiple use of the list field, filesystem performance severely degrades over time: as we use up all non-bitmap free extents, the try-to-set-up-cluster dance is done at every metadata block allocation. For every block group, we fail to set up a cluster, and after failing on them all up to twice, we fall back to the much slower unclustered allocation. To make matters worse, before the unclustered allocation, we try to create new block groups until we reach the 1% threshold, which introduces additional bitmaps and thus block groups that we'll iterate over at each metadata block request.
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/free-space-cache.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 6e5b7e463698..ff179b1e7423 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -1470,6 +1470,7 @@ static void add_new_bitmap(struct btrfs_free_space_ctl *ctl,
{
info->offset = offset_to_bitmap(ctl, offset);
info->bytes = 0;
+ INIT_LIST_HEAD(&info->list);
link_free_space(ctl, info);
ctl->total_bitmaps++;