aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-03-24 15:01:56 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:00 -0400
commit0b86a832a1f38abec695864ec2eaedc9d2383f1b (patch)
tree8ec0db0b55f77eb6a23fe7db3c1064d298db55c1 /fs/btrfs/extent-tree.c
parent7f93bf8d27653726e3721c01fefc523487ecf2af (diff)
Btrfs: Add support for multiple devices per filesystem
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c429
1 files changed, 115 insertions, 314 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index ebfd304138ca..2cd957d6e8d8 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -24,37 +24,19 @@
24#include "disk-io.h" 24#include "disk-io.h"
25#include "print-tree.h" 25#include "print-tree.h"
26#include "transaction.h" 26#include "transaction.h"
27#include "volumes.h"
27 28
28#define BLOCK_GROUP_DATA EXTENT_WRITEBACK 29#define BLOCK_GROUP_DATA EXTENT_WRITEBACK
29#define BLOCK_GROUP_METADATA EXTENT_UPTODATE 30#define BLOCK_GROUP_METADATA EXTENT_UPTODATE
31#define BLOCK_GROUP_SYSTEM EXTENT_NEW
32
30#define BLOCK_GROUP_DIRTY EXTENT_DIRTY 33#define BLOCK_GROUP_DIRTY EXTENT_DIRTY
31 34
32static int finish_current_insert(struct btrfs_trans_handle *trans, struct 35static int finish_current_insert(struct btrfs_trans_handle *trans, struct
33 btrfs_root *extent_root); 36 btrfs_root *extent_root);
34static int del_pending_extents(struct btrfs_trans_handle *trans, struct 37static int del_pending_extents(struct btrfs_trans_handle *trans, struct
35 btrfs_root *extent_root); 38 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 39
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}
58 40
59static int cache_block_group(struct btrfs_root *root, 41static int cache_block_group(struct btrfs_root *root,
60 struct btrfs_block_group_cache *block_group) 42 struct btrfs_block_group_cache *block_group)
@@ -91,7 +73,7 @@ static int cache_block_group(struct btrfs_root *root,
91 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 73 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
92 if (ret < 0) 74 if (ret < 0)
93 return ret; 75 return ret;
94 ret = find_previous_extent(root, path); 76 ret = btrfs_previous_item(root, path, 0, BTRFS_EXTENT_ITEM_KEY);
95 if (ret < 0) 77 if (ret < 0)
96 return ret; 78 return ret;
97 if (ret == 0) { 79 if (ret == 0) {
@@ -168,7 +150,8 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
168 block_group_cache = &info->block_group_cache; 150 block_group_cache = &info->block_group_cache;
169 ret = find_first_extent_bit(block_group_cache, 151 ret = find_first_extent_bit(block_group_cache,
170 bytenr, &start, &end, 152 bytenr, &start, &end,
171 BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA); 153 BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA |
154 BLOCK_GROUP_SYSTEM);
172 if (ret) { 155 if (ret) {
173 return NULL; 156 return NULL;
174 } 157 }
@@ -182,23 +165,38 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
182 return block_group; 165 return block_group;
183 return NULL; 166 return NULL;
184} 167}
185static u64 noinline find_search_start(struct btrfs_root *root, 168
169static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits)
170{
171 if ((bits & BLOCK_GROUP_DATA) &&
172 (cache->flags & BTRFS_BLOCK_GROUP_DATA))
173 return 1;
174 if ((bits & BLOCK_GROUP_METADATA) &&
175 (cache->flags & BTRFS_BLOCK_GROUP_METADATA))
176 return 1;
177 if ((bits & BLOCK_GROUP_SYSTEM) &&
178 (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM))
179 return 1;
180 return 0;
181}
182
183static int noinline find_search_start(struct btrfs_root *root,
186 struct btrfs_block_group_cache **cache_ret, 184 struct btrfs_block_group_cache **cache_ret,
187 u64 search_start, int num, int data) 185 u64 *start_ret, int num, int data)
188{ 186{
189 int ret; 187 int ret;
190 struct btrfs_block_group_cache *cache = *cache_ret; 188 struct btrfs_block_group_cache *cache = *cache_ret;
191 struct extent_io_tree *free_space_cache; 189 struct extent_io_tree *free_space_cache;
192 struct extent_state *state;
193 u64 last; 190 u64 last;
194 u64 start = 0; 191 u64 start = 0;
192 u64 end = 0;
195 u64 cache_miss = 0; 193 u64 cache_miss = 0;
196 u64 total_fs_bytes; 194 u64 total_fs_bytes;
195 u64 search_start = *start_ret;
197 int wrapped = 0; 196 int wrapped = 0;
198 197
199 if (!cache) { 198 if (!cache)
200 goto out; 199 goto out;
201 }
202 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); 200 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
203 free_space_cache = &root->fs_info->free_space_cache; 201 free_space_cache = &root->fs_info->free_space_cache;
204 202
@@ -208,6 +206,9 @@ again:
208 goto out; 206 goto out;
209 207
210 last = max(search_start, cache->key.objectid); 208 last = max(search_start, cache->key.objectid);
209 if (!block_group_bits(cache, data)) {
210 goto new_group;
211 }
211 212
212 while(1) { 213 while(1) {
213 ret = find_first_extent_bit(&root->fs_info->free_space_cache, 214 ret = find_first_extent_bit(&root->fs_info->free_space_cache,
@@ -225,22 +226,20 @@ again:
225 cache_miss = start; 226 cache_miss = start;
226 continue; 227 continue;
227 } 228 }
228 if (data != BTRFS_BLOCK_GROUP_MIXED && 229 if (start + num > cache->key.objectid + cache->key.offset)
229 start + num > cache->key.objectid + cache->key.offset)
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 return start; 233 *start_ret = start;
234 return 0;
234 } 235 }
235out: 236out:
236 cache = btrfs_lookup_block_group(root->fs_info, search_start); 237 cache = btrfs_lookup_block_group(root->fs_info, search_start);
237 if (!cache) { 238 if (!cache) {
238 printk("Unable to find block group for %Lu\n", 239 printk("Unable to find block group for %Lu\n", search_start);
239 search_start);
240 WARN_ON(1); 240 WARN_ON(1);
241 return search_start;
242 } 241 }
243 return search_start; 242 return -ENOSPC;
244 243
245new_group: 244new_group:
246 last = cache->key.objectid + cache->key.offset; 245 last = cache->key.objectid + cache->key.offset;
@@ -251,7 +250,6 @@ no_cache:
251 if (!wrapped) { 250 if (!wrapped) {
252 wrapped = 1; 251 wrapped = 1;
253 last = search_start; 252 last = search_start;
254 data = BTRFS_BLOCK_GROUP_MIXED;
255 goto wrapped; 253 goto wrapped;
256 } 254 }
257 goto out; 255 goto out;
@@ -299,7 +297,6 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
299 int ret; 297 int ret;
300 int full_search = 0; 298 int full_search = 0;
301 int factor = 8; 299 int factor = 8;
302 int data_swap = 0;
303 300
304 block_group_cache = &info->block_group_cache; 301 block_group_cache = &info->block_group_cache;
305 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); 302 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
@@ -307,19 +304,12 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
307 if (!owner) 304 if (!owner)
308 factor = 8; 305 factor = 8;
309 306
310 if (data == BTRFS_BLOCK_GROUP_MIXED) { 307 bit = data;
311 bit = BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA;
312 factor = 10;
313 } else if (data)
314 bit = BLOCK_GROUP_DATA;
315 else
316 bit = BLOCK_GROUP_METADATA;
317 308
318 if (search_start && search_start < total_fs_bytes) { 309 if (search_start && search_start < total_fs_bytes) {
319 struct btrfs_block_group_cache *shint; 310 struct btrfs_block_group_cache *shint;
320 shint = btrfs_lookup_block_group(info, search_start); 311 shint = btrfs_lookup_block_group(info, search_start);
321 if (shint && (shint->data == data || 312 if (shint && block_group_bits(shint, data)) {
322 shint->data == BTRFS_BLOCK_GROUP_MIXED)) {
323 used = btrfs_block_group_used(&shint->item); 313 used = btrfs_block_group_used(&shint->item);
324 if (used + shint->pinned < 314 if (used + shint->pinned <
325 div_factor(shint->key.offset, factor)) { 315 div_factor(shint->key.offset, factor)) {
@@ -327,8 +317,8 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
327 } 317 }
328 } 318 }
329 } 319 }
330 if (hint && hint->key.objectid < total_fs_bytes && 320 if (hint && block_group_bits(hint, data) &&
331 (hint->data == data || hint->data == BTRFS_BLOCK_GROUP_MIXED)) { 321 hint->key.objectid < total_fs_bytes) {
332 used = btrfs_block_group_used(&hint->item); 322 used = btrfs_block_group_used(&hint->item);
333 if (used + hint->pinned < 323 if (used + hint->pinned <
334 div_factor(hint->key.offset, factor)) { 324 div_factor(hint->key.offset, factor)) {
@@ -379,12 +369,6 @@ again:
379 full_search = 1; 369 full_search = 1;
380 goto again; 370 goto again;
381 } 371 }
382 if (!data_swap) {
383 data_swap = 1;
384 bit = BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA;
385 last = search_start;
386 goto again;
387 }
388found: 372found:
389 return found_group; 373 return found_group;
390} 374}
@@ -1002,7 +986,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
1002static int update_block_group(struct btrfs_trans_handle *trans, 986static int update_block_group(struct btrfs_trans_handle *trans,
1003 struct btrfs_root *root, 987 struct btrfs_root *root,
1004 u64 bytenr, u64 num_bytes, int alloc, 988 u64 bytenr, u64 num_bytes, int alloc,
1005 int mark_free, int data) 989 int mark_free)
1006{ 990{
1007 struct btrfs_block_group_cache *cache; 991 struct btrfs_block_group_cache *cache;
1008 struct btrfs_fs_info *info = root->fs_info; 992 struct btrfs_fs_info *info = root->fs_info;
@@ -1027,41 +1011,6 @@ static int update_block_group(struct btrfs_trans_handle *trans,
1027 old_val = btrfs_block_group_used(&cache->item); 1011 old_val = btrfs_block_group_used(&cache->item);
1028 num_bytes = min(total, cache->key.offset - byte_in_group); 1012 num_bytes = min(total, cache->key.offset - byte_in_group);
1029 if (alloc) { 1013 if (alloc) {
1030 if (cache->data != data &&
1031 old_val < (cache->key.offset >> 1)) {
1032 int bit_to_clear;
1033 int bit_to_set;
1034 cache->data = data;
1035 if (data) {
1036 bit_to_clear = BLOCK_GROUP_METADATA;
1037 bit_to_set = BLOCK_GROUP_DATA;
1038 cache->item.flags &=
1039 ~BTRFS_BLOCK_GROUP_MIXED;
1040 cache->item.flags |=
1041 BTRFS_BLOCK_GROUP_DATA;
1042 } else {
1043 bit_to_clear = BLOCK_GROUP_DATA;
1044 bit_to_set = BLOCK_GROUP_METADATA;
1045 cache->item.flags &=
1046 ~BTRFS_BLOCK_GROUP_MIXED;
1047 cache->item.flags &=
1048 ~BTRFS_BLOCK_GROUP_DATA;
1049 }
1050 clear_extent_bits(&info->block_group_cache,
1051 start, end, bit_to_clear,
1052 GFP_NOFS);
1053 set_extent_bits(&info->block_group_cache,
1054 start, end, bit_to_set,
1055 GFP_NOFS);
1056 } else if (cache->data != data &&
1057 cache->data != BTRFS_BLOCK_GROUP_MIXED) {
1058 cache->data = BTRFS_BLOCK_GROUP_MIXED;
1059 set_extent_bits(&info->block_group_cache,
1060 start, end,
1061 BLOCK_GROUP_DATA |
1062 BLOCK_GROUP_METADATA,
1063 GFP_NOFS);
1064 }
1065 old_val += num_bytes; 1014 old_val += num_bytes;
1066 } else { 1015 } else {
1067 old_val -= num_bytes; 1016 old_val -= num_bytes;
@@ -1357,7 +1306,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
1357 return ret; 1306 return ret;
1358 } 1307 }
1359 ret = update_block_group(trans, root, bytenr, num_bytes, 0, 1308 ret = update_block_group(trans, root, bytenr, num_bytes, 0,
1360 mark_free, 0); 1309 mark_free);
1361 BUG_ON(ret); 1310 BUG_ON(ret);
1362 } 1311 }
1363 btrfs_free_path(path); 1312 btrfs_free_path(path);
@@ -1450,38 +1399,21 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
1450 u64 exclude_start, u64 exclude_nr, 1399 u64 exclude_start, u64 exclude_nr,
1451 int data) 1400 int data)
1452{ 1401{
1453 struct btrfs_path *path;
1454 struct btrfs_key key;
1455 u64 hole_size = 0;
1456 u64 aligned;
1457 int ret; 1402 int ret;
1458 int slot = 0;
1459 u64 last_byte = 0;
1460 u64 *last_ptr = NULL;
1461 u64 orig_search_start = search_start; 1403 u64 orig_search_start = search_start;
1462 int start_found;
1463 struct extent_buffer *l;
1464 struct btrfs_root * root = orig_root->fs_info->extent_root; 1404 struct btrfs_root * root = orig_root->fs_info->extent_root;
1465 struct btrfs_fs_info *info = root->fs_info; 1405 struct btrfs_fs_info *info = root->fs_info;
1466 u64 total_needed = num_bytes; 1406 u64 total_needed = num_bytes;
1467 int level;
1468 struct btrfs_block_group_cache *block_group; 1407 struct btrfs_block_group_cache *block_group;
1469 int full_scan = 0; 1408 int full_scan = 0;
1470 int wrapped = 0; 1409 int wrapped = 0;
1471 int empty_cluster;
1472 u64 cached_start;
1473 1410
1474 WARN_ON(num_bytes < root->sectorsize); 1411 WARN_ON(num_bytes < root->sectorsize);
1475 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); 1412 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
1476 1413
1477 level = btrfs_header_level(root->node);
1478
1479 if (num_bytes >= 32 * 1024 * 1024 && hint_byte) {
1480 data = BTRFS_BLOCK_GROUP_MIXED;
1481 }
1482
1483 if (search_end == (u64)-1) 1414 if (search_end == (u64)-1)
1484 search_end = btrfs_super_total_bytes(&info->super_copy); 1415 search_end = btrfs_super_total_bytes(&info->super_copy);
1416
1485 if (hint_byte) { 1417 if (hint_byte) {
1486 block_group = btrfs_lookup_block_group(info, hint_byte); 1418 block_group = btrfs_lookup_block_group(info, hint_byte);
1487 if (!block_group) 1419 if (!block_group)
@@ -1495,7 +1427,7 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
1495 } 1427 }
1496 1428
1497 total_needed += empty_size; 1429 total_needed += empty_size;
1498 path = btrfs_alloc_path(); 1430
1499check_failed: 1431check_failed:
1500 if (!block_group) { 1432 if (!block_group) {
1501 block_group = btrfs_lookup_block_group(info, search_start); 1433 block_group = btrfs_lookup_block_group(info, search_start);
@@ -1503,135 +1435,49 @@ check_failed:
1503 block_group = btrfs_lookup_block_group(info, 1435 block_group = btrfs_lookup_block_group(info,
1504 orig_search_start); 1436 orig_search_start);
1505 } 1437 }
1506 search_start = find_search_start(root, &block_group, search_start, 1438 ret = find_search_start(root, &block_group, &search_start,
1507 total_needed, data); 1439 total_needed, data);
1508 search_start = stripe_align(root, search_start); 1440 if (ret)
1509 cached_start = search_start;
1510 btrfs_init_path(path);
1511 ins->objectid = search_start;
1512 ins->offset = 0;
1513 start_found = 0;
1514 path->reada = 2;
1515
1516 ret = btrfs_search_slot(trans, root, ins, path, 0, 0);
1517 if (ret < 0)
1518 goto error;
1519 ret = find_previous_extent(root, path);
1520 if (ret < 0)
1521 goto error; 1441 goto error;
1522 l = path->nodes[0];
1523 btrfs_item_key_to_cpu(l, &key, path->slots[0]);
1524 while (1) {
1525 l = path->nodes[0];
1526 slot = path->slots[0];
1527 if (slot >= btrfs_header_nritems(l)) {
1528 ret = btrfs_next_leaf(root, path);
1529 if (ret == 0)
1530 continue;
1531 if (ret < 0)
1532 goto error;
1533 1442
1534 search_start = max(search_start, 1443 search_start = stripe_align(root, search_start);
1535 block_group->key.objectid); 1444 ins->objectid = search_start;
1536 if (!start_found) { 1445 ins->offset = num_bytes;
1537 aligned = stripe_align(root, search_start);
1538 ins->objectid = aligned;
1539 if (aligned >= search_end) {
1540 ret = -ENOSPC;
1541 goto error;
1542 }
1543 ins->offset = search_end - aligned;
1544 start_found = 1;
1545 goto check_pending;
1546 }
1547 ins->objectid = stripe_align(root,
1548 last_byte > search_start ?
1549 last_byte : search_start);
1550 if (search_end <= ins->objectid) {
1551 ret = -ENOSPC;
1552 goto error;
1553 }
1554 ins->offset = search_end - ins->objectid;
1555 BUG_ON(ins->objectid >= search_end);
1556 goto check_pending;
1557 }
1558 btrfs_item_key_to_cpu(l, &key, slot);
1559
1560 if (key.objectid >= search_start && key.objectid > last_byte &&
1561 start_found) {
1562 if (last_byte < search_start)
1563 last_byte = search_start;
1564 aligned = stripe_align(root, last_byte);
1565 hole_size = key.objectid - aligned;
1566 if (key.objectid > aligned && hole_size >= num_bytes) {
1567 ins->objectid = aligned;
1568 ins->offset = hole_size;
1569 goto check_pending;
1570 }
1571 }
1572 if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) {
1573 if (!start_found && btrfs_key_type(&key) ==
1574 BTRFS_BLOCK_GROUP_ITEM_KEY) {
1575 last_byte = key.objectid;
1576 start_found = 1;
1577 }
1578 goto next;
1579 }
1580
1581
1582 start_found = 1;
1583 last_byte = key.objectid + key.offset;
1584
1585 if (!full_scan && data != BTRFS_BLOCK_GROUP_MIXED &&
1586 last_byte >= block_group->key.objectid +
1587 block_group->key.offset) {
1588 btrfs_release_path(root, path);
1589 search_start = block_group->key.objectid +
1590 block_group->key.offset;
1591 goto new_group;
1592 }
1593next:
1594 path->slots[0]++;
1595 cond_resched();
1596 }
1597check_pending:
1598 /* we have to make sure we didn't find an extent that has already
1599 * been allocated by the map tree or the original allocation
1600 */
1601 btrfs_release_path(root, path);
1602 BUG_ON(ins->objectid < search_start);
1603 1446
1604 if (ins->objectid + num_bytes >= search_end) 1447 if (ins->objectid + num_bytes >= search_end)
1605 goto enospc; 1448 goto enospc;
1606 if (!full_scan && data != BTRFS_BLOCK_GROUP_MIXED && 1449
1607 ins->objectid + num_bytes > block_group-> 1450 if (ins->objectid + num_bytes >
1608 key.objectid + block_group->key.offset) { 1451 block_group->key.objectid + block_group->key.offset) {
1609 search_start = block_group->key.objectid + 1452 search_start = block_group->key.objectid +
1610 block_group->key.offset; 1453 block_group->key.offset;
1611 goto new_group; 1454 goto new_group;
1612 } 1455 }
1456
1613 if (test_range_bit(&info->extent_ins, ins->objectid, 1457 if (test_range_bit(&info->extent_ins, ins->objectid,
1614 ins->objectid + num_bytes -1, EXTENT_LOCKED, 0)) { 1458 ins->objectid + num_bytes -1, EXTENT_LOCKED, 0)) {
1615 search_start = ins->objectid + num_bytes; 1459 search_start = ins->objectid + num_bytes;
1616 goto new_group; 1460 goto new_group;
1617 } 1461 }
1462
1618 if (test_range_bit(&info->pinned_extents, ins->objectid, 1463 if (test_range_bit(&info->pinned_extents, ins->objectid,
1619 ins->objectid + num_bytes -1, EXTENT_DIRTY, 0)) { 1464 ins->objectid + num_bytes -1, EXTENT_DIRTY, 0)) {
1620 search_start = ins->objectid + num_bytes; 1465 search_start = ins->objectid + num_bytes;
1621 goto new_group; 1466 goto new_group;
1622 } 1467 }
1468
1623 if (exclude_nr > 0 && (ins->objectid + num_bytes > exclude_start && 1469 if (exclude_nr > 0 && (ins->objectid + num_bytes > exclude_start &&
1624 ins->objectid < exclude_start + exclude_nr)) { 1470 ins->objectid < exclude_start + exclude_nr)) {
1625 search_start = exclude_start + exclude_nr; 1471 search_start = exclude_start + exclude_nr;
1626 goto new_group; 1472 goto new_group;
1627 } 1473 }
1628 if (!data) { 1474
1475 if (!(data & BLOCK_GROUP_DATA)) {
1629 block_group = btrfs_lookup_block_group(info, ins->objectid); 1476 block_group = btrfs_lookup_block_group(info, ins->objectid);
1630 if (block_group) 1477 if (block_group)
1631 trans->block_group = block_group; 1478 trans->block_group = block_group;
1632 } 1479 }
1633 ins->offset = num_bytes; 1480 ins->offset = num_bytes;
1634 btrfs_free_path(path);
1635 return 0; 1481 return 0;
1636 1482
1637new_group: 1483new_group:
@@ -1646,7 +1492,6 @@ enospc:
1646 if (!full_scan) 1492 if (!full_scan)
1647 total_needed -= empty_size; 1493 total_needed -= empty_size;
1648 full_scan = 1; 1494 full_scan = 1;
1649 data = BTRFS_BLOCK_GROUP_MIXED;
1650 } else 1495 } else
1651 wrapped = 1; 1496 wrapped = 1;
1652 } 1497 }
@@ -1657,8 +1502,6 @@ enospc:
1657 goto check_failed; 1502 goto check_failed;
1658 1503
1659error: 1504error:
1660 btrfs_release_path(root, path);
1661 btrfs_free_path(path);
1662 return ret; 1505 return ret;
1663} 1506}
1664/* 1507/*
@@ -1689,6 +1532,13 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1689 struct btrfs_path *path; 1532 struct btrfs_path *path;
1690 struct btrfs_key keys[2]; 1533 struct btrfs_key keys[2];
1691 1534
1535 if (data)
1536 data = BLOCK_GROUP_DATA;
1537 else if (root == root->fs_info->chunk_root)
1538 data = BLOCK_GROUP_SYSTEM;
1539 else
1540 data = BLOCK_GROUP_METADATA;
1541
1692 new_hint = max(hint_byte, root->fs_info->alloc_start); 1542 new_hint = max(hint_byte, root->fs_info->alloc_start);
1693 if (new_hint < btrfs_super_total_bytes(&info->super_copy)) 1543 if (new_hint < btrfs_super_total_bytes(&info->super_copy))
1694 hint_byte = new_hint; 1544 hint_byte = new_hint;
@@ -1718,7 +1568,6 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1718 set_extent_bits(&root->fs_info->extent_ins, ins->objectid, 1568 set_extent_bits(&root->fs_info->extent_ins, ins->objectid,
1719 ins->objectid + ins->offset - 1, 1569 ins->objectid + ins->offset - 1,
1720 EXTENT_LOCKED, GFP_NOFS); 1570 EXTENT_LOCKED, GFP_NOFS);
1721 WARN_ON(data == 1);
1722 goto update_block; 1571 goto update_block;
1723 } 1572 }
1724 1573
@@ -1768,8 +1617,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1768 } 1617 }
1769 1618
1770update_block: 1619update_block:
1771 ret = update_block_group(trans, root, ins->objectid, ins->offset, 1, 0, 1620 ret = update_block_group(trans, root, ins->objectid, ins->offset, 1, 0);
1772 data);
1773 if (ret) { 1621 if (ret) {
1774 printk("update block group failed for %Lu %Lu\n", 1622 printk("update block group failed for %Lu %Lu\n",
1775 ins->objectid, ins->offset); 1623 ins->objectid, ins->offset);
@@ -2457,7 +2305,7 @@ again:
2457 if (ret < 0) 2305 if (ret < 0)
2458 goto out; 2306 goto out;
2459 2307
2460 ret = find_previous_extent(root, path); 2308 ret = btrfs_previous_item(root, path, 0, BTRFS_EXTENT_ITEM_KEY);
2461 if (ret < 0) 2309 if (ret < 0)
2462 goto out; 2310 goto out;
2463 if (ret == 0) { 2311 if (ret == 0) {
@@ -2604,95 +2452,48 @@ out:
2604int btrfs_grow_extent_tree(struct btrfs_trans_handle *trans, 2452int btrfs_grow_extent_tree(struct btrfs_trans_handle *trans,
2605 struct btrfs_root *root, u64 new_size) 2453 struct btrfs_root *root, u64 new_size)
2606{ 2454{
2607 struct btrfs_path *path; 2455 btrfs_set_super_total_bytes(&root->fs_info->super_copy, new_size);
2608 u64 nr = 0; 2456 return 0;
2609 u64 cur_byte; 2457}
2610 u64 old_size;
2611 unsigned long rem;
2612 struct btrfs_block_group_cache *cache;
2613 struct btrfs_block_group_item *item;
2614 struct btrfs_fs_info *info = root->fs_info;
2615 struct extent_io_tree *block_group_cache;
2616 struct btrfs_key key;
2617 struct extent_buffer *leaf;
2618 int ret;
2619 int bit;
2620
2621 old_size = btrfs_super_total_bytes(&info->super_copy);
2622 block_group_cache = &info->block_group_cache;
2623
2624 root = info->extent_root;
2625
2626 cache = btrfs_lookup_block_group(root->fs_info, old_size - 1);
2627
2628 cur_byte = cache->key.objectid + cache->key.offset;
2629 if (cur_byte >= new_size)
2630 goto set_size;
2631
2632 key.offset = BTRFS_BLOCK_GROUP_SIZE;
2633 btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY);
2634 2458
2635 path = btrfs_alloc_path(); 2459int find_first_block_group(struct btrfs_root *root, struct btrfs_path *path,
2636 if (!path) 2460 struct btrfs_key *key)
2637 return -ENOMEM; 2461{
2462 int ret;
2463 struct btrfs_key found_key;
2464 struct extent_buffer *leaf;
2465 int slot;
2638 2466
2639 while(cur_byte < new_size) { 2467 ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
2640 key.objectid = cur_byte; 2468 if (ret < 0)
2641 ret = btrfs_insert_empty_item(trans, root, path, &key, 2469 return ret;
2642 sizeof(struct btrfs_block_group_item)); 2470 while(1) {
2643 BUG_ON(ret); 2471 slot = path->slots[0];
2644 leaf = path->nodes[0]; 2472 leaf = path->nodes[0];
2645 item = btrfs_item_ptr(leaf, path->slots[0], 2473 if (slot >= btrfs_header_nritems(leaf)) {
2646 struct btrfs_block_group_item); 2474 ret = btrfs_next_leaf(root, path);
2647 2475 if (ret == 0)
2648 btrfs_set_disk_block_group_used(leaf, item, 0); 2476 continue;
2649 div_long_long_rem(nr, 3, &rem); 2477 if (ret < 0)
2650 if (rem) { 2478 goto error;
2651 btrfs_set_disk_block_group_flags(leaf, item, 2479 break;
2652 BTRFS_BLOCK_GROUP_DATA);
2653 } else {
2654 btrfs_set_disk_block_group_flags(leaf, item, 0);
2655 }
2656 nr++;
2657
2658 cache = kmalloc(sizeof(*cache), GFP_NOFS);
2659 BUG_ON(!cache);
2660
2661 read_extent_buffer(leaf, &cache->item, (unsigned long)item,
2662 sizeof(cache->item));
2663
2664 memcpy(&cache->key, &key, sizeof(key));
2665 cache->cached = 0;
2666 cache->pinned = 0;
2667 cur_byte = key.objectid + key.offset;
2668 btrfs_release_path(root, path);
2669
2670 if (cache->item.flags & BTRFS_BLOCK_GROUP_DATA) {
2671 bit = BLOCK_GROUP_DATA;
2672 cache->data = BTRFS_BLOCK_GROUP_DATA;
2673 } else {
2674 bit = BLOCK_GROUP_METADATA;
2675 cache->data = 0;
2676 } 2480 }
2481 btrfs_item_key_to_cpu(leaf, &found_key, slot);
2677 2482
2678 /* use EXTENT_LOCKED to prevent merging */ 2483 if (found_key.objectid >= key->objectid &&
2679 set_extent_bits(block_group_cache, key.objectid, 2484 found_key.type == BTRFS_BLOCK_GROUP_ITEM_KEY)
2680 key.objectid + key.offset - 1, 2485 return 0;
2681 bit | EXTENT_LOCKED, GFP_NOFS); 2486 path->slots[0]++;
2682 set_state_private(block_group_cache, key.objectid,
2683 (unsigned long)cache);
2684 } 2487 }
2685 btrfs_free_path(path); 2488 ret = -ENOENT;
2686set_size: 2489error:
2687 btrfs_set_super_total_bytes(&info->super_copy, new_size); 2490 return ret;
2688 return 0;
2689} 2491}
2690 2492
2691int btrfs_read_block_groups(struct btrfs_root *root) 2493int btrfs_read_block_groups(struct btrfs_root *root)
2692{ 2494{
2693 struct btrfs_path *path; 2495 struct btrfs_path *path;
2694 int ret; 2496 int ret;
2695 int err = 0;
2696 int bit; 2497 int bit;
2697 struct btrfs_block_group_cache *cache; 2498 struct btrfs_block_group_cache *cache;
2698 struct btrfs_fs_info *info = root->fs_info; 2499 struct btrfs_fs_info *info = root->fs_info;
@@ -2702,28 +2503,28 @@ int btrfs_read_block_groups(struct btrfs_root *root)
2702 struct extent_buffer *leaf; 2503 struct extent_buffer *leaf;
2703 2504
2704 block_group_cache = &info->block_group_cache; 2505 block_group_cache = &info->block_group_cache;
2705
2706 root = info->extent_root; 2506 root = info->extent_root;
2707 key.objectid = 0; 2507 key.objectid = 0;
2708 key.offset = BTRFS_BLOCK_GROUP_SIZE; 2508 key.offset = 0;
2709 btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); 2509 btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY);
2710
2711 path = btrfs_alloc_path(); 2510 path = btrfs_alloc_path();
2712 if (!path) 2511 if (!path)
2713 return -ENOMEM; 2512 return -ENOMEM;
2714 2513
2715 while(1) { 2514 while(1) {
2716 ret = btrfs_search_slot(NULL, info->extent_root, 2515 ret = find_first_block_group(root, path, &key);
2717 &key, path, 0, 0); 2516 if (ret > 0) {
2718 if (ret != 0) { 2517 ret = 0;
2719 err = ret; 2518 goto error;
2720 break;
2721 } 2519 }
2520 if (ret != 0)
2521 goto error;
2522
2722 leaf = path->nodes[0]; 2523 leaf = path->nodes[0];
2723 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 2524 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
2724 cache = kmalloc(sizeof(*cache), GFP_NOFS); 2525 cache = kmalloc(sizeof(*cache), GFP_NOFS);
2725 if (!cache) { 2526 if (!cache) {
2726 err = -1; 2527 ret = -ENOMEM;
2727 break; 2528 break;
2728 } 2529 }
2729 2530
@@ -2733,18 +2534,17 @@ int btrfs_read_block_groups(struct btrfs_root *root)
2733 memcpy(&cache->key, &found_key, sizeof(found_key)); 2534 memcpy(&cache->key, &found_key, sizeof(found_key));
2734 cache->cached = 0; 2535 cache->cached = 0;
2735 cache->pinned = 0; 2536 cache->pinned = 0;
2537
2736 key.objectid = found_key.objectid + found_key.offset; 2538 key.objectid = found_key.objectid + found_key.offset;
2737 btrfs_release_path(root, path); 2539 btrfs_release_path(root, path);
2738 2540 cache->flags = btrfs_block_group_flags(&cache->item);
2739 if (cache->item.flags & BTRFS_BLOCK_GROUP_MIXED) { 2541 bit = 0;
2740 bit = BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA; 2542 if (cache->flags & BTRFS_BLOCK_GROUP_DATA) {
2741 cache->data = BTRFS_BLOCK_GROUP_MIXED;
2742 } else if (cache->item.flags & BTRFS_BLOCK_GROUP_DATA) {
2743 bit = BLOCK_GROUP_DATA; 2543 bit = BLOCK_GROUP_DATA;
2744 cache->data = BTRFS_BLOCK_GROUP_DATA; 2544 } else if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) {
2745 } else { 2545 bit = BLOCK_GROUP_SYSTEM;
2546 } else if (cache->flags & BTRFS_BLOCK_GROUP_METADATA) {
2746 bit = BLOCK_GROUP_METADATA; 2547 bit = BLOCK_GROUP_METADATA;
2747 cache->data = 0;
2748 } 2548 }
2749 2549
2750 /* use EXTENT_LOCKED to prevent merging */ 2550 /* use EXTENT_LOCKED to prevent merging */
@@ -2758,7 +2558,8 @@ int btrfs_read_block_groups(struct btrfs_root *root)
2758 btrfs_super_total_bytes(&info->super_copy)) 2558 btrfs_super_total_bytes(&info->super_copy))
2759 break; 2559 break;
2760 } 2560 }
2761 2561 ret = 0;
2562error:
2762 btrfs_free_path(path); 2563 btrfs_free_path(path);
2763 return 0; 2564 return ret;
2764} 2565}