diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-03-24 15:02:07 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:01 -0400 |
commit | 239b14b32dc39232ebf9cce29ff77c4c564355fd (patch) | |
tree | f7a95d97d71ef9d0f355a71a83e2ba1f62944e04 /fs/btrfs/extent-tree.c | |
parent | 0d81ba5dbedef0c3970d6aa318aa84920943e6e3 (diff) |
Btrfs: Bring back mount -o ssd optimizations
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 14eb8fc87015..e9ef644ff56f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1473,13 +1473,31 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans, | |||
1473 | struct btrfs_root * root = orig_root->fs_info->extent_root; | 1473 | struct btrfs_root * root = orig_root->fs_info->extent_root; |
1474 | struct btrfs_fs_info *info = root->fs_info; | 1474 | struct btrfs_fs_info *info = root->fs_info; |
1475 | u64 total_needed = num_bytes; | 1475 | u64 total_needed = num_bytes; |
1476 | u64 *last_ptr = NULL; | ||
1476 | struct btrfs_block_group_cache *block_group; | 1477 | struct btrfs_block_group_cache *block_group; |
1477 | int full_scan = 0; | 1478 | int full_scan = 0; |
1478 | int wrapped = 0; | 1479 | int wrapped = 0; |
1480 | int empty_cluster = 2 * 1024 * 1024; | ||
1479 | 1481 | ||
1480 | WARN_ON(num_bytes < root->sectorsize); | 1482 | WARN_ON(num_bytes < root->sectorsize); |
1481 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); | 1483 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); |
1482 | 1484 | ||
1485 | if (data & BTRFS_BLOCK_GROUP_METADATA) { | ||
1486 | last_ptr = &root->fs_info->last_alloc; | ||
1487 | } | ||
1488 | |||
1489 | if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) { | ||
1490 | last_ptr = &root->fs_info->last_data_alloc; | ||
1491 | } | ||
1492 | |||
1493 | if (last_ptr) { | ||
1494 | if (*last_ptr) | ||
1495 | hint_byte = *last_ptr; | ||
1496 | else { | ||
1497 | empty_size += empty_cluster; | ||
1498 | } | ||
1499 | } | ||
1500 | |||
1483 | if (search_end == (u64)-1) | 1501 | if (search_end == (u64)-1) |
1484 | search_end = btrfs_super_total_bytes(&info->super_copy); | 1502 | search_end = btrfs_super_total_bytes(&info->super_copy); |
1485 | 1503 | ||
@@ -1489,11 +1507,14 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans, | |||
1489 | hint_byte = search_start; | 1507 | hint_byte = search_start; |
1490 | block_group = btrfs_find_block_group(root, block_group, | 1508 | block_group = btrfs_find_block_group(root, block_group, |
1491 | hint_byte, data, 1); | 1509 | hint_byte, data, 1); |
1510 | if (last_ptr && *last_ptr == 0 && block_group) | ||
1511 | hint_byte = block_group->key.objectid; | ||
1492 | } else { | 1512 | } else { |
1493 | block_group = btrfs_find_block_group(root, | 1513 | block_group = btrfs_find_block_group(root, |
1494 | trans->block_group, | 1514 | trans->block_group, |
1495 | search_start, data, 1); | 1515 | search_start, data, 1); |
1496 | } | 1516 | } |
1517 | search_start = max(search_start, hint_byte); | ||
1497 | 1518 | ||
1498 | total_needed += empty_size; | 1519 | total_needed += empty_size; |
1499 | 1520 | ||
@@ -1506,9 +1527,36 @@ check_failed: | |||
1506 | } | 1527 | } |
1507 | ret = find_search_start(root, &block_group, &search_start, | 1528 | ret = find_search_start(root, &block_group, &search_start, |
1508 | total_needed, data); | 1529 | total_needed, data); |
1530 | if (ret == -ENOSPC && last_ptr && *last_ptr) { | ||
1531 | *last_ptr = 0; | ||
1532 | block_group = btrfs_lookup_block_group(info, | ||
1533 | orig_search_start); | ||
1534 | search_start = orig_search_start; | ||
1535 | ret = find_search_start(root, &block_group, &search_start, | ||
1536 | total_needed, data); | ||
1537 | } | ||
1538 | if (ret == -ENOSPC) | ||
1539 | goto enospc; | ||
1509 | if (ret) | 1540 | if (ret) |
1510 | goto error; | 1541 | goto error; |
1511 | 1542 | ||
1543 | if (last_ptr && *last_ptr && search_start != *last_ptr) { | ||
1544 | *last_ptr = 0; | ||
1545 | if (!empty_size) { | ||
1546 | empty_size += empty_cluster; | ||
1547 | total_needed += empty_size; | ||
1548 | } | ||
1549 | block_group = btrfs_lookup_block_group(info, | ||
1550 | orig_search_start); | ||
1551 | search_start = orig_search_start; | ||
1552 | ret = find_search_start(root, &block_group, | ||
1553 | &search_start, total_needed, data); | ||
1554 | if (ret == -ENOSPC) | ||
1555 | goto enospc; | ||
1556 | if (ret) | ||
1557 | goto error; | ||
1558 | } | ||
1559 | |||
1512 | search_start = stripe_align(root, search_start); | 1560 | search_start = stripe_align(root, search_start); |
1513 | ins->objectid = search_start; | 1561 | ins->objectid = search_start; |
1514 | ins->offset = num_bytes; | 1562 | ins->offset = num_bytes; |
@@ -1547,6 +1595,13 @@ check_failed: | |||
1547 | trans->block_group = block_group; | 1595 | trans->block_group = block_group; |
1548 | } | 1596 | } |
1549 | ins->offset = num_bytes; | 1597 | ins->offset = num_bytes; |
1598 | if (last_ptr) { | ||
1599 | *last_ptr = ins->objectid + ins->offset; | ||
1600 | if (*last_ptr == | ||
1601 | btrfs_super_total_bytes(&root->fs_info->super_copy)) { | ||
1602 | *last_ptr = 0; | ||
1603 | } | ||
1604 | } | ||
1550 | return 0; | 1605 | return 0; |
1551 | 1606 | ||
1552 | new_group: | 1607 | new_group: |
@@ -1612,12 +1667,12 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
1612 | if (root->ref_cows) { | 1667 | if (root->ref_cows) { |
1613 | if (data != BTRFS_BLOCK_GROUP_METADATA) { | 1668 | if (data != BTRFS_BLOCK_GROUP_METADATA) { |
1614 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | 1669 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
1615 | num_bytes, | 1670 | 2 * 1024 * 1024, |
1616 | BTRFS_BLOCK_GROUP_METADATA); | 1671 | BTRFS_BLOCK_GROUP_METADATA); |
1617 | BUG_ON(ret); | 1672 | BUG_ON(ret); |
1618 | } | 1673 | } |
1619 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | 1674 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
1620 | num_bytes, data); | 1675 | num_bytes + 2 * 1024 * 1024, data); |
1621 | BUG_ON(ret); | 1676 | BUG_ON(ret); |
1622 | } | 1677 | } |
1623 | 1678 | ||