aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-04-03 16:29:03 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:01 -0400
commit8790d502e4401a4a3a4175b83a3a47e8d595c771 (patch)
tree7e01c053d6a99c3c2a6fb71a7338b083e953f0b3 /fs/btrfs/extent-tree.c
parent0ef8b2428a339e83fe225e82ef8bd0ea3f62b180 (diff)
Btrfs: Add support for mirroring across drives
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c93
1 files changed, 49 insertions, 44 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a34c289aec21..4ab98d8b73fa 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -230,9 +230,13 @@ again:
230 goto new_group; 230 goto new_group;
231 if (start + num > total_fs_bytes) 231 if (start + num > total_fs_bytes)
232 goto new_group; 232 goto new_group;
233 if (!block_group_bits(cache, data)) {
234 printk("block group bits don't match %Lu %Lu\n", cache->flags, data);
235 }
233 *start_ret = start; 236 *start_ret = start;
234 return 0; 237 return 0;
235 } out: 238 }
239out:
236 cache = btrfs_lookup_block_group(root->fs_info, search_start); 240 cache = btrfs_lookup_block_group(root->fs_info, search_start);
237 if (!cache) { 241 if (!cache) {
238 printk("Unable to find block group for %Lu\n", search_start); 242 printk("Unable to find block group for %Lu\n", search_start);
@@ -365,14 +369,17 @@ again:
365 if (cache->key.objectid > total_fs_bytes) 369 if (cache->key.objectid > total_fs_bytes)
366 break; 370 break;
367 371
368 if (full_search) 372 if (block_group_bits(cache, data)) {
369 free_check = cache->key.offset; 373 if (full_search)
370 else 374 free_check = cache->key.offset;
371 free_check = div_factor(cache->key.offset, factor); 375 else
376 free_check = div_factor(cache->key.offset,
377 factor);
372 378
373 if (used + cache->pinned < free_check) { 379 if (used + cache->pinned < free_check) {
374 found_group = cache; 380 found_group = cache;
375 goto found; 381 goto found;
382 }
376 } 383 }
377 cond_resched(); 384 cond_resched();
378 } 385 }
@@ -1038,6 +1045,19 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
1038 return 0; 1045 return 0;
1039} 1046}
1040 1047
1048static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
1049{
1050 u64 extra_flags = flags & (BTRFS_BLOCK_GROUP_RAID0 |
1051 BTRFS_BLOCK_GROUP_RAID1);
1052 if (extra_flags) {
1053 if (flags & BTRFS_BLOCK_GROUP_DATA)
1054 fs_info->avail_data_alloc_bits |= extra_flags;
1055 if (flags & BTRFS_BLOCK_GROUP_METADATA)
1056 fs_info->avail_metadata_alloc_bits |= extra_flags;
1057 if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
1058 fs_info->avail_system_alloc_bits |= extra_flags;
1059 }
1060}
1041 1061
1042static int do_chunk_alloc(struct btrfs_trans_handle *trans, 1062static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1043 struct btrfs_root *extent_root, u64 alloc_bytes, 1063 struct btrfs_root *extent_root, u64 alloc_bytes,
@@ -1060,7 +1080,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1060 if (space_info->full) 1080 if (space_info->full)
1061 return 0; 1081 return 0;
1062 1082
1063 thresh = div_factor(space_info->total_bytes, 7); 1083 thresh = div_factor(space_info->total_bytes, 6);
1064 if ((space_info->bytes_used + space_info->bytes_pinned + alloc_bytes) < 1084 if ((space_info->bytes_used + space_info->bytes_pinned + alloc_bytes) <
1065 thresh) 1085 thresh)
1066 return 0; 1086 return 0;
@@ -1079,16 +1099,7 @@ printk("space info full %Lu\n", flags);
1079 start, num_bytes); 1099 start, num_bytes);
1080 BUG_ON(ret); 1100 BUG_ON(ret);
1081 1101
1082 if (flags & BTRFS_BLOCK_GROUP_RAID0) { 1102 set_avail_alloc_bits(extent_root->fs_info, flags);
1083 if (flags & BTRFS_BLOCK_GROUP_DATA) {
1084 extent_root->fs_info->extra_data_alloc_bits =
1085 BTRFS_BLOCK_GROUP_RAID0;
1086 }
1087 if (flags & BTRFS_BLOCK_GROUP_METADATA) {
1088 extent_root->fs_info->extra_alloc_bits =
1089 BTRFS_BLOCK_GROUP_RAID0;
1090 }
1091 }
1092 return 0; 1103 return 0;
1093} 1104}
1094 1105
@@ -1529,6 +1540,7 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
1529 1540
1530 if (data & BTRFS_BLOCK_GROUP_METADATA) { 1541 if (data & BTRFS_BLOCK_GROUP_METADATA) {
1531 last_ptr = &root->fs_info->last_alloc; 1542 last_ptr = &root->fs_info->last_alloc;
1543 empty_cluster = 256 * 1024;
1532 } 1544 }
1533 1545
1534 if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) { 1546 if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) {
@@ -1693,6 +1705,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1693 u64 root_used; 1705 u64 root_used;
1694 u64 search_start = 0; 1706 u64 search_start = 0;
1695 u64 new_hint; 1707 u64 new_hint;
1708 u64 alloc_profile;
1696 u32 sizes[2]; 1709 u32 sizes[2];
1697 struct btrfs_fs_info *info = root->fs_info; 1710 struct btrfs_fs_info *info = root->fs_info;
1698 struct btrfs_root *extent_root = info->extent_root; 1711 struct btrfs_root *extent_root = info->extent_root;
@@ -1700,31 +1713,32 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1700 struct btrfs_extent_ref *ref; 1713 struct btrfs_extent_ref *ref;
1701 struct btrfs_path *path; 1714 struct btrfs_path *path;
1702 struct btrfs_key keys[2]; 1715 struct btrfs_key keys[2];
1703 int extra_chunk_alloc_bits = 0;
1704 1716
1705 if (data) { 1717 if (data) {
1706 data = BTRFS_BLOCK_GROUP_DATA | info->extra_data_alloc_bits; 1718 alloc_profile = info->avail_data_alloc_bits &
1719 info->data_alloc_profile;
1720 data = BTRFS_BLOCK_GROUP_DATA | alloc_profile;
1707 } else if (root == root->fs_info->chunk_root) { 1721 } else if (root == root->fs_info->chunk_root) {
1708 data = BTRFS_BLOCK_GROUP_SYSTEM; 1722 alloc_profile = info->avail_system_alloc_bits &
1723 info->system_alloc_profile;
1724 data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile;
1709 } else { 1725 } else {
1710 data = BTRFS_BLOCK_GROUP_METADATA | info->extra_alloc_bits; 1726 alloc_profile = info->avail_metadata_alloc_bits &
1727 info->metadata_alloc_profile;
1728 data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile;
1711 } 1729 }
1712 if (btrfs_super_num_devices(&info->super_copy) > 1 &&
1713 !(data & BTRFS_BLOCK_GROUP_SYSTEM))
1714 extra_chunk_alloc_bits = BTRFS_BLOCK_GROUP_RAID0;
1715 1730
1716 if (root->ref_cows) { 1731 if (root->ref_cows) {
1717 if (!(data & BTRFS_BLOCK_GROUP_METADATA)) { 1732 if (!(data & BTRFS_BLOCK_GROUP_METADATA)) {
1718 ret = do_chunk_alloc(trans, root->fs_info->extent_root, 1733 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
1719 2 * 1024 * 1024, 1734 2 * 1024 * 1024,
1720 BTRFS_BLOCK_GROUP_METADATA | 1735 BTRFS_BLOCK_GROUP_METADATA |
1721 info->extra_alloc_bits | 1736 (info->metadata_alloc_profile &
1722 extra_chunk_alloc_bits); 1737 info->avail_metadata_alloc_bits));
1723 BUG_ON(ret); 1738 BUG_ON(ret);
1724 } 1739 }
1725 ret = do_chunk_alloc(trans, root->fs_info->extent_root, 1740 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
1726 num_bytes + 2 * 1024 * 1024, data | 1741 num_bytes + 2 * 1024 * 1024, data);
1727 extra_chunk_alloc_bits);
1728 BUG_ON(ret); 1742 BUG_ON(ret);
1729 } 1743 }
1730 1744
@@ -2046,12 +2060,12 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2046 if (!next || !btrfs_buffer_uptodate(next)) { 2060 if (!next || !btrfs_buffer_uptodate(next)) {
2047 free_extent_buffer(next); 2061 free_extent_buffer(next);
2048 reada_walk_down(root, cur, path->slots[*level]); 2062 reada_walk_down(root, cur, path->slots[*level]);
2063
2064 mutex_unlock(&root->fs_info->fs_mutex);
2049 next = read_tree_block(root, bytenr, blocksize); 2065 next = read_tree_block(root, bytenr, blocksize);
2066 mutex_lock(&root->fs_info->fs_mutex);
2050 2067
2051 /* we used to drop the lock above, keep the 2068 /* we've dropped the lock, double check */
2052 * code to double check so that we won't forget
2053 * when we drop the lock again in the future
2054 */
2055 ret = lookup_extent_ref(trans, root, bytenr, 2069 ret = lookup_extent_ref(trans, root, bytenr,
2056 blocksize, &refs); 2070 blocksize, &refs);
2057 BUG_ON(ret); 2071 BUG_ON(ret);
@@ -2739,16 +2753,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
2739 } else if (cache->flags & BTRFS_BLOCK_GROUP_METADATA) { 2753 } else if (cache->flags & BTRFS_BLOCK_GROUP_METADATA) {
2740 bit = BLOCK_GROUP_METADATA; 2754 bit = BLOCK_GROUP_METADATA;
2741 } 2755 }
2742 if (cache->flags & BTRFS_BLOCK_GROUP_RAID0) { 2756 set_avail_alloc_bits(info, cache->flags);
2743 if (cache->flags & BTRFS_BLOCK_GROUP_DATA) {
2744 info->extra_data_alloc_bits =
2745 BTRFS_BLOCK_GROUP_RAID0;
2746 }
2747 if (cache->flags & BTRFS_BLOCK_GROUP_METADATA) {
2748 info->extra_alloc_bits =
2749 BTRFS_BLOCK_GROUP_RAID0;
2750 }
2751 }
2752 2757
2753 ret = update_space_info(info, cache->flags, found_key.offset, 2758 ret = update_space_info(info, cache->flags, found_key.offset,
2754 btrfs_block_group_used(&cache->item), 2759 btrfs_block_group_used(&cache->item),