aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c80
1 files changed, 36 insertions, 44 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index b801eb4b3eef..cc89df4493ab 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -33,6 +33,28 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
33 btrfs_root *extent_root); 33 btrfs_root *extent_root);
34static int del_pending_extents(struct btrfs_trans_handle *trans, struct 34static int del_pending_extents(struct btrfs_trans_handle *trans, struct
35 btrfs_root *extent_root); 35 btrfs_root *extent_root);
36static int find_previous_extent(struct btrfs_root *root,
37 struct btrfs_path *path)
38{
39 struct btrfs_key found_key;
40 struct extent_buffer *leaf;
41 int ret;
42
43 while(1) {
44 if (path->slots[0] == 0) {
45 ret = btrfs_prev_leaf(root, path);
46 if (ret != 0)
47 return ret;
48 } else {
49 path->slots[0]--;
50 }
51 leaf = path->nodes[0];
52 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
53 if (found_key.type == BTRFS_EXTENT_ITEM_KEY)
54 return 0;
55 }
56 return 1;
57}
36 58
37static int cache_block_group(struct btrfs_root *root, 59static int cache_block_group(struct btrfs_root *root,
38 struct btrfs_block_group_cache *block_group) 60 struct btrfs_block_group_cache *block_group)
@@ -65,16 +87,19 @@ static int cache_block_group(struct btrfs_root *root,
65 first_free = block_group->key.objectid; 87 first_free = block_group->key.objectid;
66 key.objectid = block_group->key.objectid; 88 key.objectid = block_group->key.objectid;
67 key.offset = 0; 89 key.offset = 0;
68
69 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 90 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
70 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 91 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
71
72 if (ret < 0) 92 if (ret < 0)
73 return ret; 93 return ret;
74 94 ret = find_previous_extent(root, path);
75 if (ret && path->slots[0] > 0) 95 if (ret < 0)
76 path->slots[0]--; 96 return ret;
77 97 if (ret == 0) {
98 leaf = path->nodes[0];
99 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
100 if (key.objectid + key.offset > first_free)
101 first_free = key.objectid + key.offset;
102 }
78 while(1) { 103 while(1) {
79 leaf = path->nodes[0]; 104 leaf = path->nodes[0];
80 slot = path->slots[0]; 105 slot = path->slots[0];
@@ -88,15 +113,10 @@ static int cache_block_group(struct btrfs_root *root,
88 break; 113 break;
89 } 114 }
90 } 115 }
91
92 btrfs_item_key_to_cpu(leaf, &key, slot); 116 btrfs_item_key_to_cpu(leaf, &key, slot);
93 if (key.objectid < block_group->key.objectid) { 117 if (key.objectid < block_group->key.objectid) {
94 if (btrfs_key_type(&key) != BTRFS_EXTENT_REF_KEY &&
95 key.objectid + key.offset > first_free)
96 first_free = key.objectid + key.offset;
97 goto next; 118 goto next;
98 } 119 }
99
100 if (key.objectid >= block_group->key.objectid + 120 if (key.objectid >= block_group->key.objectid +
101 block_group->key.offset) { 121 block_group->key.offset) {
102 break; 122 break;
@@ -162,11 +182,9 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
162 return block_group; 182 return block_group;
163 return NULL; 183 return NULL;
164} 184}
165
166static u64 noinline find_search_start(struct btrfs_root *root, 185static u64 noinline find_search_start(struct btrfs_root *root,
167 struct btrfs_block_group_cache **cache_ret, 186 struct btrfs_block_group_cache **cache_ret,
168 u64 search_start, int num, 187 u64 search_start, int num, int data)
169 int data, int full_scan)
170{ 188{
171 int ret; 189 int ret;
172 struct btrfs_block_group_cache *cache = *cache_ret; 190 struct btrfs_block_group_cache *cache = *cache_ret;
@@ -771,9 +789,7 @@ again:
771out: 789out:
772 btrfs_free_path(path); 790 btrfs_free_path(path);
773 return total_count; 791 return total_count;
774
775} 792}
776
777int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, 793int btrfs_inc_root_ref(struct btrfs_trans_handle *trans,
778 struct btrfs_root *root, u64 owner_objectid) 794 struct btrfs_root *root, u64 owner_objectid)
779{ 795{
@@ -1422,7 +1438,7 @@ check_failed:
1422 orig_search_start); 1438 orig_search_start);
1423 } 1439 }
1424 search_start = find_search_start(root, &block_group, search_start, 1440 search_start = find_search_start(root, &block_group, search_start,
1425 total_needed, data, full_scan); 1441 total_needed, data);
1426 search_start = stripe_align(root, search_start); 1442 search_start = stripe_align(root, search_start);
1427 cached_start = search_start; 1443 cached_start = search_start;
1428 btrfs_init_path(path); 1444 btrfs_init_path(path);
@@ -1434,35 +1450,11 @@ check_failed:
1434 ret = btrfs_search_slot(trans, root, ins, path, 0, 0); 1450 ret = btrfs_search_slot(trans, root, ins, path, 0, 0);
1435 if (ret < 0) 1451 if (ret < 0)
1436 goto error; 1452 goto error;
1437 1453 ret = find_previous_extent(root, path);
1438 if (path->slots[0] > 0) { 1454 if (ret < 0)
1439 path->slots[0]--; 1455 goto error;
1440 }
1441
1442 l = path->nodes[0]; 1456 l = path->nodes[0];
1443 btrfs_item_key_to_cpu(l, &key, path->slots[0]); 1457 btrfs_item_key_to_cpu(l, &key, path->slots[0]);
1444
1445 /*
1446 * walk backwards to find the first extent item key
1447 */
1448 while(btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) {
1449 if (path->slots[0] == 0) {
1450 ret = btrfs_prev_leaf(root, path);
1451 if (ret != 0) {
1452 ret = btrfs_search_slot(trans, root, ins,
1453 path, 0, 0);
1454 if (ret < 0)
1455 goto error;
1456 if (path->slots[0] > 0)
1457 path->slots[0]--;
1458 break;
1459 }
1460 } else {
1461 path->slots[0]--;
1462 }
1463 l = path->nodes[0];
1464 btrfs_item_key_to_cpu(l, &key, path->slots[0]);
1465 }
1466 while (1) { 1458 while (1) {
1467 l = path->nodes[0]; 1459 l = path->nodes[0];
1468 slot = path->slots[0]; 1460 slot = path->slots[0];