Commit cb517eabba4f109810dba2e5f37b0dcf22103065

Authored by Miao Xie
Committed by Josef Bacik
1 parent babbf170c7

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>

Showing 9 changed files with 228 additions and 269 deletions Side-by-side Diff

... ... @@ -3376,9 +3376,9 @@
3376 3376 struct btrfs_root_item *item);
3377 3377 void btrfs_read_root_item(struct extent_buffer *eb, int slot,
3378 3378 struct btrfs_root_item *item);
3379   -int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct
3380   - btrfs_root_item *item, struct btrfs_key *key);
3381   -int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid);
  3379 +int btrfs_find_root(struct btrfs_root *root, struct btrfs_key *search_key,
  3380 + struct btrfs_path *path, struct btrfs_root_item *root_item,
  3381 + struct btrfs_key *root_key);
3382 3382 int btrfs_find_orphan_roots(struct btrfs_root *tree_root);
3383 3383 void btrfs_set_root_node(struct btrfs_root_item *item,
3384 3384 struct extent_buffer *node);
... ... @@ -1234,39 +1234,6 @@
1234 1234 spin_lock_init(&root->root_item_lock);
1235 1235 }
1236 1236  
1237   -static 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   -
1270 1237 static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info)
1271 1238 {
1272 1239 struct btrfs_root *root = kzalloc(sizeof(*root), GFP_NOFS);
1273 1240  
1274 1241  
1275 1242  
1276 1243  
1277 1244  
1278 1245  
1279 1246  
1280 1247  
1281 1248  
1282 1249  
1283 1250  
... ... @@ -1451,70 +1418,73 @@
1451 1418 return 0;
1452 1419 }
1453 1420  
1454   -struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
1455   - struct btrfs_key *location)
  1421 +struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
  1422 + struct btrfs_key *key)
1456 1423 {
1457 1424 struct btrfs_root *root;
1458 1425 struct btrfs_fs_info *fs_info = tree_root->fs_info;
1459 1426 struct btrfs_path *path;
1460   - struct extent_buffer *l;
1461 1427 u64 generation;
1462 1428 u32 blocksize;
1463   - int ret = 0;
1464   - int slot;
  1429 + int ret;
1465 1430  
1466   - root = btrfs_alloc_root(fs_info);
1467   - if (!root)
  1431 + path = btrfs_alloc_path();
  1432 + if (!path)
1468 1433 return ERR_PTR(-ENOMEM);
1469   - if (location->offset == (u64)-1) {
1470   - ret = find_and_setup_root(tree_root, fs_info,
1471   - location->objectid, root);
1472   - if (ret) {
1473   - kfree(root);
1474   - return ERR_PTR(ret);
1475   - }
1476   - goto out;
  1434 +
  1435 + root = btrfs_alloc_root(fs_info);
  1436 + if (!root) {
  1437 + ret = -ENOMEM;
  1438 + goto alloc_fail;
1477 1439 }
1478 1440  
1479 1441 __setup_root(tree_root->nodesize, tree_root->leafsize,
1480 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();
1484   - if (!path) {
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);
  1445 + ret = btrfs_find_root(tree_root, key, path,
  1446 + &root->root_item, &root->root_key);
1496 1447 if (ret) {
1497   - kfree(root);
1498 1448 if (ret > 0)
1499 1449 ret = -ENOENT;
1500   - return ERR_PTR(ret);
  1450 + goto find_fail;
1501 1451 }
1502 1452  
1503 1453 generation = btrfs_root_generation(&root->root_item);
1504 1454 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
1505 1455 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
1506 1456 blocksize, generation);
1507   - if (!root->node || !extent_buffer_uptodate(root->node)) {
1508   - ret = (!root->node) ? -ENOMEM : -EIO;
1509   -
1510   - free_extent_buffer(root->node);
1511   - kfree(root);
1512   - return ERR_PTR(ret);
  1457 + if (!root->node) {
  1458 + ret = -ENOMEM;
  1459 + goto find_fail;
  1460 + } else if (!btrfs_buffer_uptodate(root->node, generation, 0)) {
  1461 + ret = -EIO;
  1462 + goto read_fail;
1513 1463 }
1514   -
1515 1464 root->commit_root = btrfs_root_node(root);
1516 1465 out:
1517   - if (location->objectid != BTRFS_TREE_LOG_OBJECTID) {
  1466 + btrfs_free_path(path);
  1467 + return root;
  1468 +
  1469 +read_fail:
  1470 + free_extent_buffer(root->node);
  1471 +find_fail:
  1472 + kfree(root);
  1473 +alloc_fail:
  1474 + root = ERR_PTR(ret);
  1475 + goto out;
  1476 +}
  1477 +
  1478 +struct 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 1488 root->ref_cows = 1;
1519 1489 btrfs_check_and_init_root_item(&root->root_item);
1520 1490 }
... ... @@ -1522,6 +1492,66 @@
1522 1492 return root;
1523 1493 }
1524 1494  
  1495 +int 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;
  1516 +fail:
  1517 + kfree(root->free_ino_ctl);
  1518 + kfree(root->free_ino_pinned);
  1519 + return ret;
  1520 +}
  1521 +
  1522 +struct 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 +
  1534 +int 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 +
1525 1555 struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
1526 1556 struct btrfs_key *location)
1527 1557 {
1528 1558  
1529 1559  
1530 1560  
1531 1561  
1532 1562  
... ... @@ -1542,58 +1572,30 @@
1542 1572 return fs_info->quota_root ? fs_info->quota_root :
1543 1573 ERR_PTR(-ENOENT);
1544 1574 again:
1545   - spin_lock(&fs_info->fs_roots_radix_lock);
1546   - root = radix_tree_lookup(&fs_info->fs_roots_radix,
1547   - (unsigned long)location->objectid);
1548   - spin_unlock(&fs_info->fs_roots_radix_lock);
  1575 + root = btrfs_lookup_fs_root(fs_info, location->objectid);
1549 1576 if (root)
1550 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 1580 if (IS_ERR(root))
1554 1581 return root;
1555 1582  
1556   - root->free_ino_ctl = kzalloc(sizeof(*root->free_ino_ctl), GFP_NOFS);
1557   - root->free_ino_pinned = kzalloc(sizeof(*root->free_ino_pinned),
1558   - GFP_NOFS);
1559   - if (!root->free_ino_pinned || !root->free_ino_ctl) {
1560   - ret = -ENOMEM;
  1583 + if (btrfs_root_refs(&root->root_item) == 0) {
  1584 + ret = -ENOENT;
1561 1585 goto fail;
1562 1586 }
1563 1587  
1564   - btrfs_init_free_ino_ctl(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);
  1588 + ret = btrfs_init_fs_root(root);
1570 1589 if (ret)
1571 1590 goto fail;
1572 1591  
1573   - if (btrfs_root_refs(&root->root_item) == 0) {
1574   - ret = -ENOENT;
1575   - goto fail;
1576   - }
1577   -
1578 1592 ret = btrfs_find_orphan_item(fs_info->tree_root, location->objectid);
1579 1593 if (ret < 0)
1580 1594 goto fail;
1581 1595 if (ret == 0)
1582 1596 root->orphan_item_inserted = 1;
1583 1597  
1584   - ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
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();
  1598 + ret = btrfs_insert_fs_root(fs_info, root);
1597 1599 if (ret) {
1598 1600 if (ret == -EEXIST) {
1599 1601 free_fs_root(root);
... ... @@ -1601,10 +1603,6 @@
1601 1603 }
1602 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 1606 return root;
1609 1607 fail:
1610 1608 free_fs_root(root);
... ... @@ -2050,7 +2048,7 @@
2050 2048 list_del(&gang[0]->root_list);
2051 2049  
2052 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 2052 } else {
2055 2053 free_extent_buffer(gang[0]->node);
2056 2054 free_extent_buffer(gang[0]->commit_root);
... ... @@ -2065,7 +2063,7 @@
2065 2063 if (!ret)
2066 2064 break;
2067 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  
2072 2070  
... ... @@ -2097,14 +2095,8 @@
2097 2095 int backup_index = 0;
2098 2096  
2099 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 2098 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info);
2103   - dev_root = fs_info->dev_root = btrfs_alloc_root(fs_info);
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) {
  2099 + if (!tree_root || !chunk_root) {
2108 2100 err = -ENOMEM;
2109 2101 goto fail;
2110 2102 }
2111 2103  
2112 2104  
2113 2105  
2114 2106  
2115 2107  
2116 2108  
2117 2109  
2118 2110  
2119 2111  
2120 2112  
... ... @@ -2655,33 +2647,44 @@
2655 2647 btrfs_set_root_node(&tree_root->root_item, tree_root->node);
2656 2648 tree_root->commit_root = btrfs_root_node(tree_root);
2657 2649  
2658   - ret = find_and_setup_root(tree_root, fs_info,
2659   - BTRFS_EXTENT_TREE_OBJECTID, extent_root);
2660   - if (ret)
  2650 + location.objectid = BTRFS_EXTENT_TREE_OBJECTID;
  2651 + location.type = BTRFS_ROOT_ITEM_KEY;
  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 2657 goto recovery_tree_root;
  2658 + }
2662 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,
2665   - BTRFS_DEV_TREE_OBJECTID, dev_root);
2666   - if (ret)
  2662 + location.objectid = BTRFS_DEV_TREE_OBJECTID;
  2663 + dev_root = btrfs_read_tree_root(tree_root, &location);
  2664 + if (IS_ERR(dev_root)) {
  2665 + ret = PTR_ERR(dev_root);
2667 2666 goto recovery_tree_root;
  2667 + }
2668 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,
2671   - BTRFS_CSUM_TREE_OBJECTID, csum_root);
2672   - if (ret)
  2672 + location.objectid = BTRFS_CSUM_TREE_OBJECTID;
  2673 + csum_root = btrfs_read_tree_root(tree_root, &location);
  2674 + if (IS_ERR(csum_root)) {
  2675 + ret = PTR_ERR(csum_root);
2673 2676 goto recovery_tree_root;
  2677 + }
2674 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,
2677   - BTRFS_QUOTA_TREE_OBJECTID, quota_root);
2678   - if (ret) {
2679   - kfree(quota_root);
2680   - quota_root = fs_info->quota_root = NULL;
2681   - } else {
  2681 + location.objectid = BTRFS_QUOTA_TREE_OBJECTID;
  2682 + quota_root = btrfs_read_tree_root(tree_root, &location);
  2683 + if (!IS_ERR(quota_root)) {
2682 2684 quota_root->track_dirty = 1;
2683 2685 fs_info->quota_enabled = 1;
2684 2686 fs_info->pending_quota_state = 1;
  2687 + fs_info->quota_root = quota_root;
2685 2688 }
2686 2689  
2687 2690 fs_info->generation = generation;
... ... @@ -2834,7 +2837,7 @@
2834 2837  
2835 2838 location.objectid = BTRFS_FS_TREE_OBJECTID;
2836 2839 location.type = BTRFS_ROOT_ITEM_KEY;
2837   - location.offset = (u64)-1;
  2840 + location.offset = 0;
2838 2841  
2839 2842 fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location);
2840 2843 if (IS_ERR(fs_info->fs_root)) {
... ... @@ -3381,7 +3384,9 @@
3381 3384 return ret;
3382 3385 }
3383 3386  
3384   -void 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. */
  3388 +void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
  3389 + struct btrfs_root *root)
3385 3390 {
3386 3391 spin_lock(&fs_info->fs_roots_radix_lock);
3387 3392 radix_tree_delete(&fs_info->fs_roots_radix,
... ... @@ -3413,6 +3418,11 @@
3413 3418 kfree(root->free_ino_pinned);
3414 3419 kfree(root->name);
3415 3420 kfree(root);
  3421 +}
  3422 +
  3423 +void btrfs_free_fs_root(struct btrfs_root *root)
  3424 +{
  3425 + free_fs_root(root);
3416 3426 }
3417 3427  
3418 3428 int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
... ... @@ -63,14 +63,19 @@
63 63 int btrfs_commit_super(struct btrfs_root *root);
64 64 struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
65 65 u64 bytenr, u32 blocksize);
66   -struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
67   - struct btrfs_key *location);
  66 +struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
  67 + struct btrfs_key *location);
  68 +int btrfs_init_fs_root(struct btrfs_root *root);
  69 +int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
  70 + struct btrfs_root *root);
68 71 struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
69 72 struct btrfs_key *location);
70 73 int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info);
71 74 void btrfs_btree_balance_dirty(struct btrfs_root *root);
72 75 void btrfs_btree_balance_dirty_nodelay(struct btrfs_root *root);
73   -void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root);
  76 +void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
  77 + struct btrfs_root *root);
  78 +void btrfs_free_fs_root(struct btrfs_root *root);
74 79 void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
75 80 int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
76 81 int atomic);
fs/btrfs/extent-tree.c
... ... @@ -7447,8 +7447,8 @@
7447 7447 }
7448 7448  
7449 7449 if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) {
7450   - ret = btrfs_find_last_root(tree_root, root->root_key.objectid,
7451   - NULL, NULL);
  7450 + ret = btrfs_find_root(tree_root, &root->root_key, path,
  7451 + NULL, NULL);
7452 7452 if (ret < 0) {
7453 7453 btrfs_abort_transaction(trans, tree_root, ret);
7454 7454 err = ret;
... ... @@ -7465,7 +7465,7 @@
7465 7465 }
7466 7466  
7467 7467 if (root->in_radix) {
7468   - btrfs_free_fs_root(tree_root->fs_info, root);
  7468 + btrfs_drop_and_free_fs_root(tree_root->fs_info, root);
7469 7469 } else {
7470 7470 free_extent_buffer(root->node);
7471 7471 free_extent_buffer(root->commit_root);
fs/btrfs/relocation.c
... ... @@ -1355,8 +1355,7 @@
1355 1355 BUG_ON(ret);
1356 1356 kfree(root_item);
1357 1357  
1358   - reloc_root = btrfs_read_fs_root_no_radix(root->fs_info->tree_root,
1359   - &root_key);
  1358 + reloc_root = btrfs_read_fs_root(root->fs_info->tree_root, &root_key);
1360 1359 BUG_ON(IS_ERR(reloc_root));
1361 1360 reloc_root->last_trans = trans->transid;
1362 1361 return reloc_root;
... ... @@ -4277,7 +4276,7 @@
4277 4276 key.type != BTRFS_ROOT_ITEM_KEY)
4278 4277 break;
4279 4278  
4280   - reloc_root = btrfs_read_fs_root_no_radix(root, &key);
  4279 + reloc_root = btrfs_read_fs_root(root, &key);
4281 4280 if (IS_ERR(reloc_root)) {
4282 4281 err = PTR_ERR(reloc_root);
4283 4282 goto out;
fs/btrfs/root-tree.c
... ... @@ -64,52 +64,59 @@
64 64 }
65 65  
66 66 /*
67   - * lookup the root with the highest offset for a given objectid. The key we do
68   - * find is copied into 'key'. If we find something return 0, otherwise 1, < 0
69   - * on error.
  67 + * btrfs_find_root - lookup the root by the key.
  68 + * root: the root of the root tree
  69 + * search_key: the key to search
  70 + * path: the path we search
  71 + * root_item: the root item of the tree we look for
  72 + * root_key: the reak key of the tree we look for
  73 + *
  74 + * If ->offset of 'seach_key' is -1ULL, it means we are not sure the offset
  75 + * of the search key, just lookup the root with the highest offset for a
  76 + * given objectid.
  77 + *
  78 + * If we find something return 0, otherwise > 0, < 0 on error.
70 79 */
71   -int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
72   - struct btrfs_root_item *item, struct btrfs_key *key)
  80 +int btrfs_find_root(struct btrfs_root *root, struct btrfs_key *search_key,
  81 + struct btrfs_path *path, struct btrfs_root_item *root_item,
  82 + struct btrfs_key *root_key)
73 83 {
74   - struct btrfs_path *path;
75   - struct btrfs_key search_key;
76 84 struct btrfs_key found_key;
77 85 struct extent_buffer *l;
78 86 int ret;
79 87 int slot;
80 88  
81   - search_key.objectid = objectid;
82   - search_key.type = BTRFS_ROOT_ITEM_KEY;
83   - search_key.offset = (u64)-1;
84   -
85   - path = btrfs_alloc_path();
86   - if (!path)
87   - return -ENOMEM;
88   - ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
  89 + ret = btrfs_search_slot(NULL, root, search_key, path, 0, 0);
89 90 if (ret < 0)
90   - goto out;
  91 + return ret;
91 92  
92   - BUG_ON(ret == 0);
93   - if (path->slots[0] == 0) {
94   - ret = 1;
95   - goto out;
  93 + if (search_key->offset != -1ULL) { /* the search key is exact */
  94 + if (ret > 0)
  95 + goto out;
  96 + } else {
  97 + BUG_ON(ret == 0); /* Logical error */
  98 + if (path->slots[0] == 0)
  99 + goto out;
  100 + path->slots[0]--;
  101 + ret = 0;
96 102 }
  103 +
97 104 l = path->nodes[0];
98   - slot = path->slots[0] - 1;
  105 + slot = path->slots[0];
  106 +
99 107 btrfs_item_key_to_cpu(l, &found_key, slot);
100   - if (found_key.objectid != objectid ||
  108 + if (found_key.objectid != search_key->objectid ||
101 109 found_key.type != BTRFS_ROOT_ITEM_KEY) {
102 110 ret = 1;
103 111 goto out;
104 112 }
105   - if (item)
106   - btrfs_read_root_item(l, slot, item);
107   - if (key)
108   - memcpy(key, &found_key, sizeof(found_key));
109 113  
110   - ret = 0;
  114 + if (root_item)
  115 + btrfs_read_root_item(l, slot, root_item);
  116 + if (root_key)
  117 + memcpy(root_key, &found_key, sizeof(found_key));
111 118 out:
112   - btrfs_free_path(path);
  119 + btrfs_release_path(path);
113 120 return ret;
114 121 }
115 122  
... ... @@ -212,86 +219,6 @@
212 219 return btrfs_insert_item(trans, root, key, item, sizeof(*item));
213 220 }
214 221  
215   -/*
216   - * at mount time we want to find all the old transaction snapshots that were in
217   - * the process of being deleted if we crashed. This is any root item with an
218   - * offset lower than the latest root. They need to be queued for deletion to
219   - * finish what was happening when we crashed.
220   - */
221   -int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid)
222   -{
223   - struct btrfs_root *dead_root;
224   - struct btrfs_root_item *ri;
225   - struct btrfs_key key;
226   - struct btrfs_key found_key;
227   - struct btrfs_path *path;
228   - int ret;
229   - u32 nritems;
230   - struct extent_buffer *leaf;
231   - int slot;
232   -
233   - key.objectid = objectid;
234   - btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
235   - key.offset = 0;
236   - path = btrfs_alloc_path();
237   - if (!path)
238   - return -ENOMEM;
239   -
240   -again:
241   - ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
242   - if (ret < 0)
243   - goto err;
244   - while (1) {
245   - leaf = path->nodes[0];
246   - nritems = btrfs_header_nritems(leaf);
247   - slot = path->slots[0];
248   - if (slot >= nritems) {
249   - ret = btrfs_next_leaf(root, path);
250   - if (ret)
251   - break;
252   - leaf = path->nodes[0];
253   - nritems = btrfs_header_nritems(leaf);
254   - slot = path->slots[0];
255   - }
256   - btrfs_item_key_to_cpu(leaf, &key, slot);
257   - if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY)
258   - goto next;
259   -
260   - if (key.objectid < objectid)
261   - goto next;
262   -
263   - if (key.objectid > objectid)
264   - break;
265   -
266   - ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item);
267   - if (btrfs_disk_root_refs(leaf, ri) != 0)
268   - goto next;
269   -
270   - memcpy(&found_key, &key, sizeof(key));
271   - key.offset++;
272   - btrfs_release_path(path);
273   - dead_root =
274   - btrfs_read_fs_root_no_radix(root->fs_info->tree_root,
275   - &found_key);
276   - if (IS_ERR(dead_root)) {
277   - ret = PTR_ERR(dead_root);
278   - goto err;
279   - }
280   -
281   - ret = btrfs_add_dead_root(dead_root);
282   - if (ret)
283   - goto err;
284   - goto again;
285   -next:
286   - slot++;
287   - path->slots[0]++;
288   - }
289   - ret = 0;
290   -err:
291   - btrfs_free_path(path);
292   - return ret;
293   -}
294   -
295 222 int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
296 223 {
297 224 struct extent_buffer *leaf;
298 225  
299 226  
300 227  
... ... @@ -340,20 +267,29 @@
340 267 root_key.objectid = key.offset;
341 268 key.offset++;
342 269  
343   - root = btrfs_read_fs_root_no_name(tree_root->fs_info,
344   - &root_key);
345   - if (!IS_ERR(root))
  270 + root = btrfs_read_fs_root(tree_root, &root_key);
  271 + if (IS_ERR(root)) {
  272 + err = PTR_ERR(root);
  273 + break;
  274 + }
  275 +
  276 + if (btrfs_root_refs(&root->root_item) == 0) {
  277 + btrfs_add_dead_root(root);
346 278 continue;
  279 + }
347 280  
348   - ret = PTR_ERR(root);
349   - if (ret != -ENOENT) {
350   - err = ret;
  281 + err = btrfs_init_fs_root(root);
  282 + if (err) {
  283 + btrfs_free_fs_root(root);
351 284 break;
352 285 }
353 286  
354   - ret = btrfs_find_dead_roots(tree_root, root_key.objectid);
355   - if (ret) {
356   - err = ret;
  287 + root->orphan_item_inserted = 1;
  288 +
  289 + err = btrfs_insert_fs_root(root->fs_info, root);
  290 + if (err) {
  291 + BUG_ON(err == -EEXIST);
  292 + btrfs_free_fs_root(root);
357 293 break;
358 294 }
359 295 }
... ... @@ -4016,8 +4016,7 @@
4016 4016 if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID)
4017 4017 break;
4018 4018  
4019   - log = btrfs_read_fs_root_no_radix(log_root_tree,
4020   - &found_key);
  4019 + log = btrfs_read_fs_root(log_root_tree, &found_key);
4021 4020 if (IS_ERR(log)) {
4022 4021 ret = PTR_ERR(log);
4023 4022 btrfs_error(fs_info, ret,
... ... @@ -5367,7 +5367,6 @@
5367 5367 return NULL;
5368 5368 list_add(&device->dev_list,
5369 5369 &fs_devices->devices);
5370   - device->dev_root = root->fs_info->dev_root;
5371 5370 device->devid = devid;
5372 5371 device->work.func = pending_bios_fn;
5373 5372 device->fs_devices = fs_devices;
... ... @@ -5593,7 +5592,6 @@
5593 5592 }
5594 5593  
5595 5594 fill_device_from_item(leaf, dev_item, device);
5596   - device->dev_root = root->fs_info->dev_root;
5597 5595 device->in_fs_metadata = 1;
5598 5596 if (device->writeable && !device->is_tgtdev_for_dev_replace) {
5599 5597 device->fs_devices->total_rw_bytes += device->total_bytes;
... ... @@ -5749,6 +5747,17 @@
5749 5747  
5750 5748 btrfs_free_path(path);
5751 5749 return ret;
  5750 +}
  5751 +
  5752 +void btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
  5753 +{
  5754 + struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
  5755 + struct btrfs_device *device;
  5756 +
  5757 + mutex_lock(&fs_devices->device_list_mutex);
  5758 + list_for_each_entry(device, &fs_devices->devices, dev_list)
  5759 + device->dev_root = fs_info->dev_root;
  5760 + mutex_unlock(&fs_devices->device_list_mutex);
5752 5761 }
5753 5762  
5754 5763 static void __btrfs_reset_dev_stats(struct btrfs_device *dev)
... ... @@ -321,6 +321,7 @@
321 321 void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);
322 322 int btrfs_get_dev_stats(struct btrfs_root *root,
323 323 struct btrfs_ioctl_get_dev_stats *stats);
  324 +void btrfs_init_devices_late(struct btrfs_fs_info *fs_info);
324 325 int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info);
325 326 int btrfs_run_dev_stats(struct btrfs_trans_handle *trans,
326 327 struct btrfs_fs_info *fs_info);