diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-09-23 16:24:10 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-09-23 16:24:10 -0400 |
commit | dc4fea795bf7e3f80dbfa3a40b8ab89427e9aed5 (patch) | |
tree | 1926c96f145965c393a2c8ab523c327dd1a241cf /fs/btrfs/free-space-cache.c | |
parent | c8f2efc8f636506e0f0c2ba4035382076875f0c1 (diff) | |
parent | 9d23108df359e572a0dca0b631bfee9f5e0fa9ea (diff) |
Merge branch 'master' into usb-next
We have USB fixes now in Linus's tree that we need to properly sort out
with reverts and the like in the usb-next branch, so merge them together
and do it by hand.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/btrfs/free-space-cache.c')
-rw-r--r-- | fs/btrfs/free-space-cache.c | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 3f0ddfce96e6..b4f9904c4c6b 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -1431,13 +1431,19 @@ static void bitmap_set_bits(struct btrfs_free_space_ctl *ctl, | |||
1431 | ctl->free_space += bytes; | 1431 | ctl->free_space += bytes; |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | /* | ||
1435 | * If we can not find suitable extent, we will use bytes to record | ||
1436 | * the size of the max extent. | ||
1437 | */ | ||
1434 | static int search_bitmap(struct btrfs_free_space_ctl *ctl, | 1438 | static int search_bitmap(struct btrfs_free_space_ctl *ctl, |
1435 | struct btrfs_free_space *bitmap_info, u64 *offset, | 1439 | struct btrfs_free_space *bitmap_info, u64 *offset, |
1436 | u64 *bytes) | 1440 | u64 *bytes) |
1437 | { | 1441 | { |
1438 | unsigned long found_bits = 0; | 1442 | unsigned long found_bits = 0; |
1443 | unsigned long max_bits = 0; | ||
1439 | unsigned long bits, i; | 1444 | unsigned long bits, i; |
1440 | unsigned long next_zero; | 1445 | unsigned long next_zero; |
1446 | unsigned long extent_bits; | ||
1441 | 1447 | ||
1442 | i = offset_to_bit(bitmap_info->offset, ctl->unit, | 1448 | i = offset_to_bit(bitmap_info->offset, ctl->unit, |
1443 | max_t(u64, *offset, bitmap_info->offset)); | 1449 | max_t(u64, *offset, bitmap_info->offset)); |
@@ -1446,9 +1452,12 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl, | |||
1446 | for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) { | 1452 | for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) { |
1447 | next_zero = find_next_zero_bit(bitmap_info->bitmap, | 1453 | next_zero = find_next_zero_bit(bitmap_info->bitmap, |
1448 | BITS_PER_BITMAP, i); | 1454 | BITS_PER_BITMAP, i); |
1449 | if ((next_zero - i) >= bits) { | 1455 | extent_bits = next_zero - i; |
1450 | found_bits = next_zero - i; | 1456 | if (extent_bits >= bits) { |
1457 | found_bits = extent_bits; | ||
1451 | break; | 1458 | break; |
1459 | } else if (extent_bits > max_bits) { | ||
1460 | max_bits = extent_bits; | ||
1452 | } | 1461 | } |
1453 | i = next_zero; | 1462 | i = next_zero; |
1454 | } | 1463 | } |
@@ -1459,38 +1468,41 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl, | |||
1459 | return 0; | 1468 | return 0; |
1460 | } | 1469 | } |
1461 | 1470 | ||
1471 | *bytes = (u64)(max_bits) * ctl->unit; | ||
1462 | return -1; | 1472 | return -1; |
1463 | } | 1473 | } |
1464 | 1474 | ||
1475 | /* Cache the size of the max extent in bytes */ | ||
1465 | static struct btrfs_free_space * | 1476 | static struct btrfs_free_space * |
1466 | find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes, | 1477 | find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes, |
1467 | unsigned long align) | 1478 | unsigned long align, u64 *max_extent_size) |
1468 | { | 1479 | { |
1469 | struct btrfs_free_space *entry; | 1480 | struct btrfs_free_space *entry; |
1470 | struct rb_node *node; | 1481 | struct rb_node *node; |
1471 | u64 ctl_off; | ||
1472 | u64 tmp; | 1482 | u64 tmp; |
1473 | u64 align_off; | 1483 | u64 align_off; |
1474 | int ret; | 1484 | int ret; |
1475 | 1485 | ||
1476 | if (!ctl->free_space_offset.rb_node) | 1486 | if (!ctl->free_space_offset.rb_node) |
1477 | return NULL; | 1487 | goto out; |
1478 | 1488 | ||
1479 | entry = tree_search_offset(ctl, offset_to_bitmap(ctl, *offset), 0, 1); | 1489 | entry = tree_search_offset(ctl, offset_to_bitmap(ctl, *offset), 0, 1); |
1480 | if (!entry) | 1490 | if (!entry) |
1481 | return NULL; | 1491 | goto out; |
1482 | 1492 | ||
1483 | for (node = &entry->offset_index; node; node = rb_next(node)) { | 1493 | for (node = &entry->offset_index; node; node = rb_next(node)) { |
1484 | entry = rb_entry(node, struct btrfs_free_space, offset_index); | 1494 | entry = rb_entry(node, struct btrfs_free_space, offset_index); |
1485 | if (entry->bytes < *bytes) | 1495 | if (entry->bytes < *bytes) { |
1496 | if (entry->bytes > *max_extent_size) | ||
1497 | *max_extent_size = entry->bytes; | ||
1486 | continue; | 1498 | continue; |
1499 | } | ||
1487 | 1500 | ||
1488 | /* make sure the space returned is big enough | 1501 | /* make sure the space returned is big enough |
1489 | * to match our requested alignment | 1502 | * to match our requested alignment |
1490 | */ | 1503 | */ |
1491 | if (*bytes >= align) { | 1504 | if (*bytes >= align) { |
1492 | ctl_off = entry->offset - ctl->start; | 1505 | tmp = entry->offset - ctl->start + align - 1; |
1493 | tmp = ctl_off + align - 1;; | ||
1494 | do_div(tmp, align); | 1506 | do_div(tmp, align); |
1495 | tmp = tmp * align + ctl->start; | 1507 | tmp = tmp * align + ctl->start; |
1496 | align_off = tmp - entry->offset; | 1508 | align_off = tmp - entry->offset; |
@@ -1499,14 +1511,22 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes, | |||
1499 | tmp = entry->offset; | 1511 | tmp = entry->offset; |
1500 | } | 1512 | } |
1501 | 1513 | ||
1502 | if (entry->bytes < *bytes + align_off) | 1514 | if (entry->bytes < *bytes + align_off) { |
1515 | if (entry->bytes > *max_extent_size) | ||
1516 | *max_extent_size = entry->bytes; | ||
1503 | continue; | 1517 | continue; |
1518 | } | ||
1504 | 1519 | ||
1505 | if (entry->bitmap) { | 1520 | if (entry->bitmap) { |
1506 | ret = search_bitmap(ctl, entry, &tmp, bytes); | 1521 | u64 size = *bytes; |
1522 | |||
1523 | ret = search_bitmap(ctl, entry, &tmp, &size); | ||
1507 | if (!ret) { | 1524 | if (!ret) { |
1508 | *offset = tmp; | 1525 | *offset = tmp; |
1526 | *bytes = size; | ||
1509 | return entry; | 1527 | return entry; |
1528 | } else if (size > *max_extent_size) { | ||
1529 | *max_extent_size = size; | ||
1510 | } | 1530 | } |
1511 | continue; | 1531 | continue; |
1512 | } | 1532 | } |
@@ -1515,7 +1535,7 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes, | |||
1515 | *bytes = entry->bytes - align_off; | 1535 | *bytes = entry->bytes - align_off; |
1516 | return entry; | 1536 | return entry; |
1517 | } | 1537 | } |
1518 | 1538 | out: | |
1519 | return NULL; | 1539 | return NULL; |
1520 | } | 1540 | } |
1521 | 1541 | ||
@@ -2116,7 +2136,8 @@ void btrfs_remove_free_space_cache(struct btrfs_block_group_cache *block_group) | |||
2116 | } | 2136 | } |
2117 | 2137 | ||
2118 | u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, | 2138 | u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, |
2119 | u64 offset, u64 bytes, u64 empty_size) | 2139 | u64 offset, u64 bytes, u64 empty_size, |
2140 | u64 *max_extent_size) | ||
2120 | { | 2141 | { |
2121 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 2142 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
2122 | struct btrfs_free_space *entry = NULL; | 2143 | struct btrfs_free_space *entry = NULL; |
@@ -2127,7 +2148,7 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, | |||
2127 | 2148 | ||
2128 | spin_lock(&ctl->tree_lock); | 2149 | spin_lock(&ctl->tree_lock); |
2129 | entry = find_free_space(ctl, &offset, &bytes_search, | 2150 | entry = find_free_space(ctl, &offset, &bytes_search, |
2130 | block_group->full_stripe_len); | 2151 | block_group->full_stripe_len, max_extent_size); |
2131 | if (!entry) | 2152 | if (!entry) |
2132 | goto out; | 2153 | goto out; |
2133 | 2154 | ||
@@ -2137,7 +2158,6 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, | |||
2137 | if (!entry->bytes) | 2158 | if (!entry->bytes) |
2138 | free_bitmap(ctl, entry); | 2159 | free_bitmap(ctl, entry); |
2139 | } else { | 2160 | } else { |
2140 | |||
2141 | unlink_free_space(ctl, entry); | 2161 | unlink_free_space(ctl, entry); |
2142 | align_gap_len = offset - entry->offset; | 2162 | align_gap_len = offset - entry->offset; |
2143 | align_gap = entry->offset; | 2163 | align_gap = entry->offset; |
@@ -2151,7 +2171,6 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, | |||
2151 | else | 2171 | else |
2152 | link_free_space(ctl, entry); | 2172 | link_free_space(ctl, entry); |
2153 | } | 2173 | } |
2154 | |||
2155 | out: | 2174 | out: |
2156 | spin_unlock(&ctl->tree_lock); | 2175 | spin_unlock(&ctl->tree_lock); |
2157 | 2176 | ||
@@ -2206,7 +2225,8 @@ int btrfs_return_cluster_to_free_space( | |||
2206 | static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, | 2225 | static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, |
2207 | struct btrfs_free_cluster *cluster, | 2226 | struct btrfs_free_cluster *cluster, |
2208 | struct btrfs_free_space *entry, | 2227 | struct btrfs_free_space *entry, |
2209 | u64 bytes, u64 min_start) | 2228 | u64 bytes, u64 min_start, |
2229 | u64 *max_extent_size) | ||
2210 | { | 2230 | { |
2211 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 2231 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
2212 | int err; | 2232 | int err; |
@@ -2218,8 +2238,11 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, | |||
2218 | search_bytes = bytes; | 2238 | search_bytes = bytes; |
2219 | 2239 | ||
2220 | err = search_bitmap(ctl, entry, &search_start, &search_bytes); | 2240 | err = search_bitmap(ctl, entry, &search_start, &search_bytes); |
2221 | if (err) | 2241 | if (err) { |
2242 | if (search_bytes > *max_extent_size) | ||
2243 | *max_extent_size = search_bytes; | ||
2222 | return 0; | 2244 | return 0; |
2245 | } | ||
2223 | 2246 | ||
2224 | ret = search_start; | 2247 | ret = search_start; |
2225 | __bitmap_clear_bits(ctl, entry, ret, bytes); | 2248 | __bitmap_clear_bits(ctl, entry, ret, bytes); |
@@ -2234,7 +2257,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, | |||
2234 | */ | 2257 | */ |
2235 | u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, | 2258 | u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, |
2236 | struct btrfs_free_cluster *cluster, u64 bytes, | 2259 | struct btrfs_free_cluster *cluster, u64 bytes, |
2237 | u64 min_start) | 2260 | u64 min_start, u64 *max_extent_size) |
2238 | { | 2261 | { |
2239 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; | 2262 | struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; |
2240 | struct btrfs_free_space *entry = NULL; | 2263 | struct btrfs_free_space *entry = NULL; |
@@ -2254,6 +2277,9 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, | |||
2254 | 2277 | ||
2255 | entry = rb_entry(node, struct btrfs_free_space, offset_index); | 2278 | entry = rb_entry(node, struct btrfs_free_space, offset_index); |
2256 | while(1) { | 2279 | while(1) { |
2280 | if (entry->bytes < bytes && entry->bytes > *max_extent_size) | ||
2281 | *max_extent_size = entry->bytes; | ||
2282 | |||
2257 | if (entry->bytes < bytes || | 2283 | if (entry->bytes < bytes || |
2258 | (!entry->bitmap && entry->offset < min_start)) { | 2284 | (!entry->bitmap && entry->offset < min_start)) { |
2259 | node = rb_next(&entry->offset_index); | 2285 | node = rb_next(&entry->offset_index); |
@@ -2267,7 +2293,8 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, | |||
2267 | if (entry->bitmap) { | 2293 | if (entry->bitmap) { |
2268 | ret = btrfs_alloc_from_bitmap(block_group, | 2294 | ret = btrfs_alloc_from_bitmap(block_group, |
2269 | cluster, entry, bytes, | 2295 | cluster, entry, bytes, |
2270 | cluster->window_start); | 2296 | cluster->window_start, |
2297 | max_extent_size); | ||
2271 | if (ret == 0) { | 2298 | if (ret == 0) { |
2272 | node = rb_next(&entry->offset_index); | 2299 | node = rb_next(&entry->offset_index); |
2273 | if (!node) | 2300 | if (!node) |