aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-05-15 03:48:19 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-06-14 11:29:37 -0400
commitcb517eabba4f109810dba2e5f37b0dcf22103065 (patch)
tree5c553813bf6fdc41df3912a1146828cba64d3b17 /fs/btrfs/disk-io.c
parentbabbf170c781f24095336c82ebf18ad272ddb773 (diff)
Btrfs: cleanup the similar code of the fs root read
There are several functions whose code is similar, such as btrfs_find_last_root() btrfs_read_fs_root_no_radix() Besides that, some functions are invoked twice, it is unnecessary, for example, we are sure that all roots which is found in btrfs_find_orphan_roots() have their orphan items, so it is unnecessary to check the orphan item again. So cleanup it. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c282
1 files changed, 146 insertions, 136 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 8dbd908a3a97..c65a5aac1e45 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1234,39 +1234,6 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
1234 spin_lock_init(&root->root_item_lock); 1234 spin_lock_init(&root->root_item_lock);
1235} 1235}
1236 1236
1237static int __must_check find_and_setup_root(struct btrfs_root *tree_root,
1238 struct btrfs_fs_info *fs_info,
1239 u64 objectid,
1240 struct btrfs_root *root)
1241{
1242 int ret;
1243 u32 blocksize;
1244 u64 generation;
1245
1246 __setup_root(tree_root->nodesize, tree_root->leafsize,
1247 tree_root->sectorsize, tree_root->stripesize,
1248 root, fs_info, objectid);
1249 ret = btrfs_find_last_root(tree_root, objectid,
1250 &root->root_item, &root->root_key);
1251 if (ret > 0)
1252 return -ENOENT;
1253 else if (ret < 0)
1254 return ret;
1255
1256 generation = btrfs_root_generation(&root->root_item);
1257 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
1258 root->commit_root = NULL;
1259 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
1260 blocksize, generation);
1261 if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) {
1262 free_extent_buffer(root->node);
1263 root->node = NULL;
1264 return -EIO;
1265 }
1266 root->commit_root = btrfs_root_node(root);
1267 return 0;
1268}
1269
1270static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info) 1237static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info)
1271{ 1238{
1272 struct btrfs_root *root = kzalloc(sizeof(*root), GFP_NOFS); 1239 struct btrfs_root *root = kzalloc(sizeof(*root), GFP_NOFS);
@@ -1451,70 +1418,73 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
1451 return 0; 1418 return 0;
1452} 1419}
1453 1420
1454struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, 1421struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
1455 struct btrfs_key *location) 1422 struct btrfs_key *key)
1456{ 1423{
1457 struct btrfs_root *root; 1424 struct btrfs_root *root;
1458 struct btrfs_fs_info *fs_info = tree_root->fs_info; 1425 struct btrfs_fs_info *fs_info = tree_root->fs_info;
1459 struct btrfs_path *path; 1426 struct btrfs_path *path;
1460 struct extent_buffer *l;
1461 u64 generation; 1427 u64 generation;
1462 u32 blocksize; 1428 u32 blocksize;
1463 int ret = 0; 1429 int ret;
1464 int slot;
1465 1430
1466 root = btrfs_alloc_root(fs_info); 1431 path = btrfs_alloc_path();
1467 if (!root) 1432 if (!path)
1468 return ERR_PTR(-ENOMEM); 1433 return ERR_PTR(-ENOMEM);
1469 if (location->offset == (u64)-1) { 1434
1470 ret = find_and_setup_root(tree_root, fs_info, 1435 root = btrfs_alloc_root(fs_info);
1471 location->objectid, root); 1436 if (!root) {
1472 if (ret) { 1437 ret = -ENOMEM;
1473 kfree(root); 1438 goto alloc_fail;
1474 return ERR_PTR(ret);
1475 }
1476 goto out;
1477 } 1439 }
1478 1440
1479 __setup_root(tree_root->nodesize, tree_root->leafsize, 1441 __setup_root(tree_root->nodesize, tree_root->leafsize,
1480 tree_root->sectorsize, tree_root->stripesize, 1442 tree_root->sectorsize, tree_root->stripesize,
1481 root, fs_info, location->objectid); 1443 root, fs_info, key->objectid);
1482 1444
1483 path = btrfs_alloc_path(); 1445 ret = btrfs_find_root(tree_root, key, path,
1484 if (!path) { 1446 &root->root_item, &root->root_key);
1485 kfree(root);
1486 return ERR_PTR(-ENOMEM);
1487 }
1488 ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0);
1489 if (ret == 0) {
1490 l = path->nodes[0];
1491 slot = path->slots[0];
1492 btrfs_read_root_item(l, slot, &root->root_item);
1493 memcpy(&root->root_key, location, sizeof(*location));
1494 }
1495 btrfs_free_path(path);
1496 if (ret) { 1447 if (ret) {
1497 kfree(root);
1498 if (ret > 0) 1448 if (ret > 0)
1499 ret = -ENOENT; 1449 ret = -ENOENT;
1500 return ERR_PTR(ret); 1450 goto find_fail;
1501 } 1451 }
1502 1452
1503 generation = btrfs_root_generation(&root->root_item); 1453 generation = btrfs_root_generation(&root->root_item);
1504 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); 1454 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
1505 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 1455 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
1506 blocksize, generation); 1456 blocksize, generation);
1507 if (!root->node || !extent_buffer_uptodate(root->node)) { 1457 if (!root->node) {
1508 ret = (!root->node) ? -ENOMEM : -EIO; 1458 ret = -ENOMEM;
1509 1459 goto find_fail;
1510 free_extent_buffer(root->node); 1460 } else if (!btrfs_buffer_uptodate(root->node, generation, 0)) {
1511 kfree(root); 1461 ret = -EIO;
1512 return ERR_PTR(ret); 1462 goto read_fail;
1513 } 1463 }
1514
1515 root->commit_root = btrfs_root_node(root); 1464 root->commit_root = btrfs_root_node(root);
1516out: 1465out:
1517 if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { 1466 btrfs_free_path(path);
1467 return root;
1468
1469read_fail:
1470 free_extent_buffer(root->node);
1471find_fail:
1472 kfree(root);
1473alloc_fail:
1474 root = ERR_PTR(ret);
1475 goto out;
1476}
1477
1478struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
1479 struct btrfs_key *location)
1480{
1481 struct btrfs_root *root;
1482
1483 root = btrfs_read_tree_root(tree_root, location);
1484 if (IS_ERR(root))
1485 return root;
1486
1487 if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
1518 root->ref_cows = 1; 1488 root->ref_cows = 1;
1519 btrfs_check_and_init_root_item(&root->root_item); 1489 btrfs_check_and_init_root_item(&root->root_item);
1520 } 1490 }
@@ -1522,6 +1492,66 @@ out:
1522 return root; 1492 return root;
1523} 1493}
1524 1494
1495int btrfs_init_fs_root(struct btrfs_root *root)
1496{
1497 int ret;
1498
1499 root->free_ino_ctl = kzalloc(sizeof(*root->free_ino_ctl), GFP_NOFS);
1500 root->free_ino_pinned = kzalloc(sizeof(*root->free_ino_pinned),
1501 GFP_NOFS);
1502 if (!root->free_ino_pinned || !root->free_ino_ctl) {
1503 ret = -ENOMEM;
1504 goto fail;
1505 }
1506
1507 btrfs_init_free_ino_ctl(root);
1508 mutex_init(&root->fs_commit_mutex);
1509 spin_lock_init(&root->cache_lock);
1510 init_waitqueue_head(&root->cache_wait);
1511
1512 ret = get_anon_bdev(&root->anon_dev);
1513 if (ret)
1514 goto fail;
1515 return 0;
1516fail:
1517 kfree(root->free_ino_ctl);
1518 kfree(root->free_ino_pinned);
1519 return ret;
1520}
1521
1522struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
1523 u64 root_id)
1524{
1525 struct btrfs_root *root;
1526
1527 spin_lock(&fs_info->fs_roots_radix_lock);
1528 root = radix_tree_lookup(&fs_info->fs_roots_radix,
1529 (unsigned long)root_id);
1530 spin_unlock(&fs_info->fs_roots_radix_lock);
1531 return root;
1532}
1533
1534int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
1535 struct btrfs_root *root)
1536{
1537 int ret;
1538
1539 ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
1540 if (ret)
1541 return ret;
1542
1543 spin_lock(&fs_info->fs_roots_radix_lock);
1544 ret = radix_tree_insert(&fs_info->fs_roots_radix,
1545 (unsigned long)root->root_key.objectid,
1546 root);
1547 if (ret == 0)
1548 root->in_radix = 1;
1549 spin_unlock(&fs_info->fs_roots_radix_lock);
1550 radix_tree_preload_end();
1551
1552 return ret;
1553}
1554
1525struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, 1555struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
1526 struct btrfs_key *location) 1556 struct btrfs_key *location)
1527{ 1557{
@@ -1542,58 +1572,30 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
1542 return fs_info->quota_root ? fs_info->quota_root : 1572 return fs_info->quota_root ? fs_info->quota_root :
1543 ERR_PTR(-ENOENT); 1573 ERR_PTR(-ENOENT);
1544again: 1574again:
1545 spin_lock(&fs_info->fs_roots_radix_lock); 1575 root = btrfs_lookup_fs_root(fs_info, location->objectid);
1546 root = radix_tree_lookup(&fs_info->fs_roots_radix,
1547 (unsigned long)location->objectid);
1548 spin_unlock(&fs_info->fs_roots_radix_lock);
1549 if (root) 1576 if (root)
1550 return root; 1577 return root;
1551 1578
1552 root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location); 1579 root = btrfs_read_fs_root(fs_info->tree_root, location);
1553 if (IS_ERR(root)) 1580 if (IS_ERR(root))
1554 return root; 1581 return root;
1555 1582
1556 root->free_ino_ctl = kzalloc(sizeof(*root->free_ino_ctl), GFP_NOFS); 1583 if (btrfs_root_refs(&root->root_item) == 0) {
1557 root->free_ino_pinned = kzalloc(sizeof(*root->free_ino_pinned), 1584 ret = -ENOENT;
1558 GFP_NOFS);
1559 if (!root->free_ino_pinned || !root->free_ino_ctl) {
1560 ret = -ENOMEM;
1561 goto fail; 1585 goto fail;
1562 } 1586 }
1563 1587
1564 btrfs_init_free_ino_ctl(root); 1588 ret = btrfs_init_fs_root(root);
1565 mutex_init(&root->fs_commit_mutex);
1566 spin_lock_init(&root->cache_lock);
1567 init_waitqueue_head(&root->cache_wait);
1568
1569 ret = get_anon_bdev(&root->anon_dev);
1570 if (ret) 1589 if (ret)
1571 goto fail; 1590 goto fail;
1572 1591
1573 if (btrfs_root_refs(&root->root_item) == 0) {
1574 ret = -ENOENT;
1575 goto fail;
1576 }
1577
1578 ret = btrfs_find_orphan_item(fs_info->tree_root, location->objectid); 1592 ret = btrfs_find_orphan_item(fs_info->tree_root, location->objectid);
1579 if (ret < 0) 1593 if (ret < 0)
1580 goto fail; 1594 goto fail;
1581 if (ret == 0) 1595 if (ret == 0)
1582 root->orphan_item_inserted = 1; 1596 root->orphan_item_inserted = 1;
1583 1597
1584 ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); 1598 ret = btrfs_insert_fs_root(fs_info, root);
1585 if (ret)
1586 goto fail;
1587
1588 spin_lock(&fs_info->fs_roots_radix_lock);
1589 ret = radix_tree_insert(&fs_info->fs_roots_radix,
1590 (unsigned long)root->root_key.objectid,
1591 root);
1592 if (ret == 0)
1593 root->in_radix = 1;
1594
1595 spin_unlock(&fs_info->fs_roots_radix_lock);
1596 radix_tree_preload_end();
1597 if (ret) { 1599 if (ret) {
1598 if (ret == -EEXIST) { 1600 if (ret == -EEXIST) {
1599 free_fs_root(root); 1601 free_fs_root(root);
@@ -1601,10 +1603,6 @@ again:
1601 } 1603 }
1602 goto fail; 1604 goto fail;
1603 } 1605 }
1604
1605 ret = btrfs_find_dead_roots(fs_info->tree_root,
1606 root->root_key.objectid);
1607 WARN_ON(ret);
1608 return root; 1606 return root;
1609fail: 1607fail:
1610 free_fs_root(root); 1608 free_fs_root(root);
@@ -2050,7 +2048,7 @@ static void del_fs_roots(struct btrfs_fs_info *fs_info)
2050 list_del(&gang[0]->root_list); 2048 list_del(&gang[0]->root_list);
2051 2049
2052 if (gang[0]->in_radix) { 2050 if (gang[0]->in_radix) {
2053 btrfs_free_fs_root(fs_info, gang[0]); 2051 btrfs_drop_and_free_fs_root(fs_info, gang[0]);
2054 } else { 2052 } else {
2055 free_extent_buffer(gang[0]->node); 2053 free_extent_buffer(gang[0]->node);
2056 free_extent_buffer(gang[0]->commit_root); 2054 free_extent_buffer(gang[0]->commit_root);
@@ -2065,7 +2063,7 @@ static void del_fs_roots(struct btrfs_fs_info *fs_info)
2065 if (!ret) 2063 if (!ret)
2066 break; 2064 break;
2067 for (i = 0; i < ret; i++) 2065 for (i = 0; i < ret; i++)
2068 btrfs_free_fs_root(fs_info, gang[i]); 2066 btrfs_drop_and_free_fs_root(fs_info, gang[i]);
2069 } 2067 }
2070} 2068}
2071 2069
@@ -2097,14 +2095,8 @@ int open_ctree(struct super_block *sb,
2097 int backup_index = 0; 2095 int backup_index = 0;
2098 2096
2099 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info); 2097 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info);
2100 extent_root = fs_info->extent_root = btrfs_alloc_root(fs_info);
2101 csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info);
2102 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); 2098 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info);
2103 dev_root = fs_info->dev_root = btrfs_alloc_root(fs_info); 2099 if (!tree_root || !chunk_root) {
2104 quota_root = fs_info->quota_root = btrfs_alloc_root(fs_info);
2105
2106 if (!tree_root || !extent_root || !csum_root ||
2107 !chunk_root || !dev_root || !quota_root) {
2108 err = -ENOMEM; 2100 err = -ENOMEM;
2109 goto fail; 2101 goto fail;
2110 } 2102 }
@@ -2655,33 +2647,44 @@ retry_root_backup:
2655 btrfs_set_root_node(&tree_root->root_item, tree_root->node); 2647 btrfs_set_root_node(&tree_root->root_item, tree_root->node);
2656 tree_root->commit_root = btrfs_root_node(tree_root); 2648 tree_root->commit_root = btrfs_root_node(tree_root);
2657 2649
2658 ret = find_and_setup_root(tree_root, fs_info, 2650 location.objectid = BTRFS_EXTENT_TREE_OBJECTID;
2659 BTRFS_EXTENT_TREE_OBJECTID, extent_root); 2651 location.type = BTRFS_ROOT_ITEM_KEY;
2660 if (ret) 2652 location.offset = 0;
2653
2654 extent_root = btrfs_read_tree_root(tree_root, &location);
2655 if (IS_ERR(extent_root)) {
2656 ret = PTR_ERR(extent_root);
2661 goto recovery_tree_root; 2657 goto recovery_tree_root;
2658 }
2662 extent_root->track_dirty = 1; 2659 extent_root->track_dirty = 1;
2660 fs_info->extent_root = extent_root;
2663 2661
2664 ret = find_and_setup_root(tree_root, fs_info, 2662 location.objectid = BTRFS_DEV_TREE_OBJECTID;
2665 BTRFS_DEV_TREE_OBJECTID, dev_root); 2663 dev_root = btrfs_read_tree_root(tree_root, &location);
2666 if (ret) 2664 if (IS_ERR(dev_root)) {
2665 ret = PTR_ERR(dev_root);
2667 goto recovery_tree_root; 2666 goto recovery_tree_root;
2667 }
2668 dev_root->track_dirty = 1; 2668 dev_root->track_dirty = 1;
2669 fs_info->dev_root = dev_root;
2670 btrfs_init_devices_late(fs_info);
2669 2671
2670 ret = find_and_setup_root(tree_root, fs_info, 2672 location.objectid = BTRFS_CSUM_TREE_OBJECTID;
2671 BTRFS_CSUM_TREE_OBJECTID, csum_root); 2673 csum_root = btrfs_read_tree_root(tree_root, &location);
2672 if (ret) 2674 if (IS_ERR(csum_root)) {
2675 ret = PTR_ERR(csum_root);
2673 goto recovery_tree_root; 2676 goto recovery_tree_root;
2677 }
2674 csum_root->track_dirty = 1; 2678 csum_root->track_dirty = 1;
2679 fs_info->csum_root = csum_root;
2675 2680
2676 ret = find_and_setup_root(tree_root, fs_info, 2681 location.objectid = BTRFS_QUOTA_TREE_OBJECTID;
2677 BTRFS_QUOTA_TREE_OBJECTID, quota_root); 2682 quota_root = btrfs_read_tree_root(tree_root, &location);
2678 if (ret) { 2683 if (!IS_ERR(quota_root)) {
2679 kfree(quota_root);
2680 quota_root = fs_info->quota_root = NULL;
2681 } else {
2682 quota_root->track_dirty = 1; 2684 quota_root->track_dirty = 1;
2683 fs_info->quota_enabled = 1; 2685 fs_info->quota_enabled = 1;
2684 fs_info->pending_quota_state = 1; 2686 fs_info->pending_quota_state = 1;
2687 fs_info->quota_root = quota_root;
2685 } 2688 }
2686 2689
2687 fs_info->generation = generation; 2690 fs_info->generation = generation;
@@ -2834,7 +2837,7 @@ retry_root_backup:
2834 2837
2835 location.objectid = BTRFS_FS_TREE_OBJECTID; 2838 location.objectid = BTRFS_FS_TREE_OBJECTID;
2836 location.type = BTRFS_ROOT_ITEM_KEY; 2839 location.type = BTRFS_ROOT_ITEM_KEY;
2837 location.offset = (u64)-1; 2840 location.offset = 0;
2838 2841
2839 fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); 2842 fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location);
2840 if (IS_ERR(fs_info->fs_root)) { 2843 if (IS_ERR(fs_info->fs_root)) {
@@ -3381,7 +3384,9 @@ int write_ctree_super(struct btrfs_trans_handle *trans,
3381 return ret; 3384 return ret;
3382} 3385}
3383 3386
3384void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) 3387/* Drop a fs root from the radix tree and free it. */
3388void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
3389 struct btrfs_root *root)
3385{ 3390{
3386 spin_lock(&fs_info->fs_roots_radix_lock); 3391 spin_lock(&fs_info->fs_roots_radix_lock);
3387 radix_tree_delete(&fs_info->fs_roots_radix, 3392 radix_tree_delete(&fs_info->fs_roots_radix,
@@ -3415,6 +3420,11 @@ static void free_fs_root(struct btrfs_root *root)
3415 kfree(root); 3420 kfree(root);
3416} 3421}
3417 3422
3423void btrfs_free_fs_root(struct btrfs_root *root)
3424{
3425 free_fs_root(root);
3426}
3427
3418int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info) 3428int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
3419{ 3429{
3420 u64 root_objectid = 0; 3430 u64 root_objectid = 0;