aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2015-10-02 16:09:42 -0400
committerChris Mason <clm@fb.com>2015-10-21 21:55:40 -0400
commitcef404837002103584c7c82f1e3fc3ec5961f47b (patch)
tree85707bf5ecc1a773cddbf47e152eb41741b52619
parentc759c4e16179e47e099f491011e6acd7858f8625 (diff)
Btrfs: keep track of largest extent in bitmaps
We can waste a lot of time searching through bitmaps when we are heavily fragmented trying to find large contiguous areas that don't exist in the bitmap. So keep track of the max extent size when we do a full search of a bitmap so that next time around we can just skip the expensive searching if our max size is less than what we are looking for. Thanks, Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/free-space-cache.c39
-rw-r--r--fs/btrfs/free-space-cache.h1
2 files changed, 39 insertions, 1 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index a5922e814ada..e10c9668e4fd 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -1738,6 +1738,16 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
1738 unsigned long next_zero; 1738 unsigned long next_zero;
1739 unsigned long extent_bits; 1739 unsigned long extent_bits;
1740 1740
1741 /*
1742 * Skip searching the bitmap if we don't have a contiguous section that
1743 * is large enough for this allocation.
1744 */
1745 if (bitmap_info->max_extent_size &&
1746 bitmap_info->max_extent_size < *bytes) {
1747 *bytes = bitmap_info->max_extent_size;
1748 return -1;
1749 }
1750
1741 i = offset_to_bit(bitmap_info->offset, ctl->unit, 1751 i = offset_to_bit(bitmap_info->offset, ctl->unit,
1742 max_t(u64, *offset, bitmap_info->offset)); 1752 max_t(u64, *offset, bitmap_info->offset));
1743 bits = bytes_to_bits(*bytes, ctl->unit); 1753 bits = bytes_to_bits(*bytes, ctl->unit);
@@ -1762,6 +1772,7 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
1762 } 1772 }
1763 1773
1764 *bytes = (u64)(max_bits) * ctl->unit; 1774 *bytes = (u64)(max_bits) * ctl->unit;
1775 bitmap_info->max_extent_size = *bytes;
1765 return -1; 1776 return -1;
1766} 1777}
1767 1778
@@ -1943,6 +1954,12 @@ static u64 add_bytes_to_bitmap(struct btrfs_free_space_ctl *ctl,
1943 1954
1944 bitmap_set_bits(ctl, info, offset, bytes_to_set); 1955 bitmap_set_bits(ctl, info, offset, bytes_to_set);
1945 1956
1957 /*
1958 * We set some bytes, we have no idea what the max extent size is
1959 * anymore.
1960 */
1961 info->max_extent_size = 0;
1962
1946 return bytes_to_set; 1963 return bytes_to_set;
1947 1964
1948} 1965}
@@ -2782,6 +2799,7 @@ static int btrfs_bitmap_cluster(struct btrfs_block_group_cache *block_group,
2782 unsigned long want_bits; 2799 unsigned long want_bits;
2783 unsigned long min_bits; 2800 unsigned long min_bits;
2784 unsigned long found_bits; 2801 unsigned long found_bits;
2802 unsigned long max_bits = 0;
2785 unsigned long start = 0; 2803 unsigned long start = 0;
2786 unsigned long total_found = 0; 2804 unsigned long total_found = 0;
2787 int ret; 2805 int ret;
@@ -2791,6 +2809,13 @@ static int btrfs_bitmap_cluster(struct btrfs_block_group_cache *block_group,
2791 want_bits = bytes_to_bits(bytes, ctl->unit); 2809 want_bits = bytes_to_bits(bytes, ctl->unit);
2792 min_bits = bytes_to_bits(min_bytes, ctl->unit); 2810 min_bits = bytes_to_bits(min_bytes, ctl->unit);
2793 2811
2812 /*
2813 * Don't bother looking for a cluster in this bitmap if it's heavily
2814 * fragmented.
2815 */
2816 if (entry->max_extent_size &&
2817 entry->max_extent_size < cont1_bytes)
2818 return -ENOSPC;
2794again: 2819again:
2795 found_bits = 0; 2820 found_bits = 0;
2796 for_each_set_bit_from(i, entry->bitmap, BITS_PER_BITMAP) { 2821 for_each_set_bit_from(i, entry->bitmap, BITS_PER_BITMAP) {
@@ -2798,13 +2823,19 @@ again:
2798 BITS_PER_BITMAP, i); 2823 BITS_PER_BITMAP, i);
2799 if (next_zero - i >= min_bits) { 2824 if (next_zero - i >= min_bits) {
2800 found_bits = next_zero - i; 2825 found_bits = next_zero - i;
2826 if (found_bits > max_bits)
2827 max_bits = found_bits;
2801 break; 2828 break;
2802 } 2829 }
2830 if (next_zero - i > max_bits)
2831 max_bits = next_zero - i;
2803 i = next_zero; 2832 i = next_zero;
2804 } 2833 }
2805 2834
2806 if (!found_bits) 2835 if (!found_bits) {
2836 entry->max_extent_size = (u64)max_bits * ctl->unit;
2807 return -ENOSPC; 2837 return -ENOSPC;
2838 }
2808 2839
2809 if (!total_found) { 2840 if (!total_found) {
2810 start = i; 2841 start = i;
@@ -3540,6 +3571,7 @@ again:
3540 spin_lock(&ctl->tree_lock); 3571 spin_lock(&ctl->tree_lock);
3541 info->offset = offset; 3572 info->offset = offset;
3542 info->bytes = bytes; 3573 info->bytes = bytes;
3574 info->max_extent_size = 0;
3543 ret = link_free_space(ctl, info); 3575 ret = link_free_space(ctl, info);
3544 spin_unlock(&ctl->tree_lock); 3576 spin_unlock(&ctl->tree_lock);
3545 if (ret) 3577 if (ret)
@@ -3567,6 +3599,11 @@ again:
3567 } 3599 }
3568 3600
3569 bytes_added = add_bytes_to_bitmap(ctl, bitmap_info, offset, bytes); 3601 bytes_added = add_bytes_to_bitmap(ctl, bitmap_info, offset, bytes);
3602
3603 /* We used the newly allocated info, set the max_extent_size to bytes */
3604 if (!info)
3605 bitmap_info->max_extent_size = bytes_added;
3606
3570 bytes -= bytes_added; 3607 bytes -= bytes_added;
3571 offset += bytes_added; 3608 offset += bytes_added;
3572 spin_unlock(&ctl->tree_lock); 3609 spin_unlock(&ctl->tree_lock);
diff --git a/fs/btrfs/free-space-cache.h b/fs/btrfs/free-space-cache.h
index a16a029ad3b1..f251865eb6f3 100644
--- a/fs/btrfs/free-space-cache.h
+++ b/fs/btrfs/free-space-cache.h
@@ -23,6 +23,7 @@ struct btrfs_free_space {
23 struct rb_node offset_index; 23 struct rb_node offset_index;
24 u64 offset; 24 u64 offset;
25 u64 bytes; 25 u64 bytes;
26 u64 max_extent_size;
26 unsigned long *bitmap; 27 unsigned long *bitmap;
27 struct list_head list; 28 struct list_head list;
28}; 29};