aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h6
-rw-r--r--fs/btrfs/disk-io.c282
-rw-r--r--fs/btrfs/disk-io.h11
-rw-r--r--fs/btrfs/extent-tree.c6
-rw-r--r--fs/btrfs/relocation.c5
-rw-r--r--fs/btrfs/root-tree.c170
-rw-r--r--fs/btrfs/tree-log.c3
-rw-r--r--fs/btrfs/volumes.c13
-rw-r--r--fs/btrfs/volumes.h1
9 files changed, 228 insertions, 269 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index d9ff585aadba..a84e59b7b006 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3376,9 +3376,9 @@ int __must_check btrfs_update_root(struct btrfs_trans_handle *trans,
3376 struct btrfs_root_item *item); 3376 struct btrfs_root_item *item);
3377void btrfs_read_root_item(struct extent_buffer *eb, int slot, 3377void btrfs_read_root_item(struct extent_buffer *eb, int slot,
3378 struct btrfs_root_item *item); 3378 struct btrfs_root_item *item);
3379int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct 3379int btrfs_find_root(struct btrfs_root *root, struct btrfs_key *search_key,
3380 btrfs_root_item *item, struct btrfs_key *key); 3380 struct btrfs_path *path, struct btrfs_root_item *root_item,
3381int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); 3381 struct btrfs_key *root_key);
3382int btrfs_find_orphan_roots(struct btrfs_root *tree_root); 3382int btrfs_find_orphan_roots(struct btrfs_root *tree_root);
3383void btrfs_set_root_node(struct btrfs_root_item *item, 3383void btrfs_set_root_node(struct btrfs_root_item *item,
3384 struct extent_buffer *node); 3384 struct extent_buffer *node);
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;
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index be69ce1b07a2..534d583e609d 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -63,14 +63,19 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
63int btrfs_commit_super(struct btrfs_root *root); 63int btrfs_commit_super(struct btrfs_root *root);
64struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, 64struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
65 u64 bytenr, u32 blocksize); 65 u64 bytenr, u32 blocksize);
66struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, 66struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
67 struct btrfs_key *location); 67 struct btrfs_key *location);
68int btrfs_init_fs_root(struct btrfs_root *root);
69int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
70 struct btrfs_root *root);
68struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, 71struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
69 struct btrfs_key *location); 72 struct btrfs_key *location);
70int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info); 73int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info);
71void btrfs_btree_balance_dirty(struct btrfs_root *root); 74void btrfs_btree_balance_dirty(struct btrfs_root *root);
72void btrfs_btree_balance_dirty_nodelay(struct btrfs_root *root); 75void btrfs_btree_balance_dirty_nodelay(struct btrfs_root *root);
73void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); 76void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
77 struct btrfs_root *root);
78void btrfs_free_fs_root(struct btrfs_root *root);
74void btrfs_mark_buffer_dirty(struct extent_buffer *buf); 79void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
75int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, 80int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
76 int atomic); 81 int atomic);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index b55b5fb0eb29..c989fe602faf 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -7447,8 +7447,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
7447 } 7447 }
7448 7448
7449 if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { 7449 if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) {
7450 ret = btrfs_find_last_root(tree_root, root->root_key.objectid, 7450 ret = btrfs_find_root(tree_root, &root->root_key, path,
7451 NULL, NULL); 7451 NULL, NULL);
7452 if (ret < 0) { 7452 if (ret < 0) {
7453 btrfs_abort_transaction(trans, tree_root, ret); 7453 btrfs_abort_transaction(trans, tree_root, ret);
7454 err = ret; 7454 err = ret;
@@ -7465,7 +7465,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
7465 } 7465 }
7466 7466
7467 if (root->in_radix) { 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 } else { 7469 } else {
7470 free_extent_buffer(root->node); 7470 free_extent_buffer(root->node);
7471 free_extent_buffer(root->commit_root); 7471 free_extent_buffer(root->commit_root);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 4febca4fc2de..f46b4cca4fa2 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -1355,8 +1355,7 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
1355 BUG_ON(ret); 1355 BUG_ON(ret);
1356 kfree(root_item); 1356 kfree(root_item);
1357 1357
1358 reloc_root = btrfs_read_fs_root_no_radix(root->fs_info->tree_root, 1358 reloc_root = btrfs_read_fs_root(root->fs_info->tree_root, &root_key);
1359 &root_key);
1360 BUG_ON(IS_ERR(reloc_root)); 1359 BUG_ON(IS_ERR(reloc_root));
1361 reloc_root->last_trans = trans->transid; 1360 reloc_root->last_trans = trans->transid;
1362 return reloc_root; 1361 return reloc_root;
@@ -4277,7 +4276,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
4277 key.type != BTRFS_ROOT_ITEM_KEY) 4276 key.type != BTRFS_ROOT_ITEM_KEY)
4278 break; 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 if (IS_ERR(reloc_root)) { 4280 if (IS_ERR(reloc_root)) {
4282 err = PTR_ERR(reloc_root); 4281 err = PTR_ERR(reloc_root);
4283 goto out; 4282 goto out;
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 5bf1ed57f178..79e683273de5 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -64,52 +64,59 @@ void btrfs_read_root_item(struct extent_buffer *eb, int slot,
64} 64}
65 65
66/* 66/*
67 * lookup the root with the highest offset for a given objectid. The key we do 67 * btrfs_find_root - lookup the root by the key.
68 * find is copied into 'key'. If we find something return 0, otherwise 1, < 0 68 * root: the root of the root tree
69 * on error. 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 */
71int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, 80int btrfs_find_root(struct btrfs_root *root, struct btrfs_key *search_key,
72 struct btrfs_root_item *item, struct btrfs_key *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 struct btrfs_key found_key; 84 struct btrfs_key found_key;
77 struct extent_buffer *l; 85 struct extent_buffer *l;
78 int ret; 86 int ret;
79 int slot; 87 int slot;
80 88
81 search_key.objectid = objectid; 89 ret = btrfs_search_slot(NULL, root, search_key, path, 0, 0);
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 if (ret < 0) 90 if (ret < 0)
90 goto out; 91 return ret;
91 92
92 BUG_ON(ret == 0); 93 if (search_key->offset != -1ULL) { /* the search key is exact */
93 if (path->slots[0] == 0) { 94 if (ret > 0)
94 ret = 1; 95 goto out;
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 l = path->nodes[0]; 104 l = path->nodes[0];
98 slot = path->slots[0] - 1; 105 slot = path->slots[0];
106
99 btrfs_item_key_to_cpu(l, &found_key, slot); 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 found_key.type != BTRFS_ROOT_ITEM_KEY) { 109 found_key.type != BTRFS_ROOT_ITEM_KEY) {
102 ret = 1; 110 ret = 1;
103 goto out; 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));
111out: 118out:
112 btrfs_free_path(path); 119 btrfs_release_path(path);
113 return ret; 120 return ret;
114} 121}
115 122
@@ -212,86 +219,6 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
212 return btrfs_insert_item(trans, root, key, item, sizeof(*item)); 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 */
221int 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
240again:
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;
285next:
286 slot++;
287 path->slots[0]++;
288 }
289 ret = 0;
290err:
291 btrfs_free_path(path);
292 return ret;
293}
294
295int btrfs_find_orphan_roots(struct btrfs_root *tree_root) 222int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
296{ 223{
297 struct extent_buffer *leaf; 224 struct extent_buffer *leaf;
@@ -340,20 +267,29 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
340 root_key.objectid = key.offset; 267 root_key.objectid = key.offset;
341 key.offset++; 268 key.offset++;
342 269
343 root = btrfs_read_fs_root_no_name(tree_root->fs_info, 270 root = btrfs_read_fs_root(tree_root, &root_key);
344 &root_key); 271 if (IS_ERR(root)) {
345 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 continue; 278 continue;
279 }
347 280
348 ret = PTR_ERR(root); 281 err = btrfs_init_fs_root(root);
349 if (ret != -ENOENT) { 282 if (err) {
350 err = ret; 283 btrfs_free_fs_root(root);
351 break; 284 break;
352 } 285 }
353 286
354 ret = btrfs_find_dead_roots(tree_root, root_key.objectid); 287 root->orphan_item_inserted = 1;
355 if (ret) { 288
356 err = ret; 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 break; 293 break;
358 } 294 }
359 } 295 }
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index c276ac9a0ec3..a59724e6c9f5 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4016,8 +4016,7 @@ again:
4016 if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID) 4016 if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID)
4017 break; 4017 break;
4018 4018
4019 log = btrfs_read_fs_root_no_radix(log_root_tree, 4019 log = btrfs_read_fs_root(log_root_tree, &found_key);
4020 &found_key);
4021 if (IS_ERR(log)) { 4020 if (IS_ERR(log)) {
4022 ret = PTR_ERR(log); 4021 ret = PTR_ERR(log);
4023 btrfs_error(fs_info, ret, 4022 btrfs_error(fs_info, ret,
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 24940085cdac..440de708f9eb 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -5367,7 +5367,6 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root,
5367 return NULL; 5367 return NULL;
5368 list_add(&device->dev_list, 5368 list_add(&device->dev_list,
5369 &fs_devices->devices); 5369 &fs_devices->devices);
5370 device->dev_root = root->fs_info->dev_root;
5371 device->devid = devid; 5370 device->devid = devid;
5372 device->work.func = pending_bios_fn; 5371 device->work.func = pending_bios_fn;
5373 device->fs_devices = fs_devices; 5372 device->fs_devices = fs_devices;
@@ -5593,7 +5592,6 @@ static int read_one_dev(struct btrfs_root *root,
5593 } 5592 }
5594 5593
5595 fill_device_from_item(leaf, dev_item, device); 5594 fill_device_from_item(leaf, dev_item, device);
5596 device->dev_root = root->fs_info->dev_root;
5597 device->in_fs_metadata = 1; 5595 device->in_fs_metadata = 1;
5598 if (device->writeable && !device->is_tgtdev_for_dev_replace) { 5596 if (device->writeable && !device->is_tgtdev_for_dev_replace) {
5599 device->fs_devices->total_rw_bytes += device->total_bytes; 5597 device->fs_devices->total_rw_bytes += device->total_bytes;
@@ -5751,6 +5749,17 @@ error:
5751 return ret; 5749 return ret;
5752} 5750}
5753 5751
5752void 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);
5761}
5762
5754static void __btrfs_reset_dev_stats(struct btrfs_device *dev) 5763static void __btrfs_reset_dev_stats(struct btrfs_device *dev)
5755{ 5764{
5756 int i; 5765 int i;
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index f6247e2a47f7..857acd34ccde 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -321,6 +321,7 @@ int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
321void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index); 321void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);
322int btrfs_get_dev_stats(struct btrfs_root *root, 322int btrfs_get_dev_stats(struct btrfs_root *root,
323 struct btrfs_ioctl_get_dev_stats *stats); 323 struct btrfs_ioctl_get_dev_stats *stats);
324void btrfs_init_devices_late(struct btrfs_fs_info *fs_info);
324int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info); 325int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info);
325int btrfs_run_dev_stats(struct btrfs_trans_handle *trans, 326int btrfs_run_dev_stats(struct btrfs_trans_handle *trans,
326 struct btrfs_fs_info *fs_info); 327 struct btrfs_fs_info *fs_info);