diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 2c569b4d59d4..b69a46691a96 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1431,6 +1431,19 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans, | |||
1431 | data = BTRFS_BLOCK_GROUP_MIXED; | 1431 | data = BTRFS_BLOCK_GROUP_MIXED; |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | /* for SSD, cluster allocations together as much as possible */ | ||
1435 | if (btrfs_test_opt(root, SSD)) { | ||
1436 | if (!data) { | ||
1437 | if (root->fs_info->last_alloc) | ||
1438 | hint_byte = root->fs_info->last_alloc; | ||
1439 | else { | ||
1440 | hint_byte = hint_byte & | ||
1441 | ~((u64)BTRFS_BLOCK_GROUP_SIZE - 1); | ||
1442 | empty_size += 16 * 1024 * 1024; | ||
1443 | } | ||
1444 | } | ||
1445 | } | ||
1446 | |||
1434 | search_end = min(search_end, | 1447 | search_end = min(search_end, |
1435 | btrfs_super_total_bytes(&info->super_copy)); | 1448 | btrfs_super_total_bytes(&info->super_copy)); |
1436 | if (hint_byte) { | 1449 | if (hint_byte) { |
@@ -1456,6 +1469,19 @@ check_failed: | |||
1456 | } | 1469 | } |
1457 | search_start = find_search_start(root, &block_group, search_start, | 1470 | search_start = find_search_start(root, &block_group, search_start, |
1458 | total_needed, data); | 1471 | total_needed, data); |
1472 | |||
1473 | if (!data && btrfs_test_opt(root, SSD) && info->last_alloc && | ||
1474 | search_start != info->last_alloc) { | ||
1475 | info->last_alloc = 0; | ||
1476 | if (!empty_size) { | ||
1477 | empty_size += 16 * 1024 * 1024; | ||
1478 | total_needed += empty_size; | ||
1479 | } | ||
1480 | search_start = find_search_start(root, &block_group, | ||
1481 | search_start, total_needed, | ||
1482 | data); | ||
1483 | } | ||
1484 | |||
1459 | search_start = stripe_align(root, search_start); | 1485 | search_start = stripe_align(root, search_start); |
1460 | cached_start = search_start; | 1486 | cached_start = search_start; |
1461 | btrfs_init_path(path); | 1487 | btrfs_init_path(path); |
@@ -1610,6 +1636,8 @@ enospc: | |||
1610 | error: | 1636 | error: |
1611 | btrfs_release_path(root, path); | 1637 | btrfs_release_path(root, path); |
1612 | btrfs_free_path(path); | 1638 | btrfs_free_path(path); |
1639 | if (btrfs_test_opt(root, SSD) && !ret && !data) | ||
1640 | info->last_alloc = ins->objectid + ins->offset; | ||
1613 | return ret; | 1641 | return ret; |
1614 | } | 1642 | } |
1615 | /* | 1643 | /* |
@@ -1778,7 +1806,8 @@ struct extent_buffer *__btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
1778 | buf->start, buf->start + buf->len - 1, | 1806 | buf->start, buf->start + buf->len - 1, |
1779 | EXTENT_CSUM, GFP_NOFS); | 1807 | EXTENT_CSUM, GFP_NOFS); |
1780 | buf->flags |= EXTENT_CSUM; | 1808 | buf->flags |= EXTENT_CSUM; |
1781 | btrfs_set_buffer_defrag(buf); | 1809 | if (!btrfs_test_opt(root, SSD)) |
1810 | btrfs_set_buffer_defrag(buf); | ||
1782 | trans->blocks_used++; | 1811 | trans->blocks_used++; |
1783 | return buf; | 1812 | return buf; |
1784 | } | 1813 | } |