aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2011-11-03 15:17:42 -0400
committerChris Mason <chris.mason@oracle.com>2011-11-06 03:04:15 -0500
commitaf31f5e5b84b5bf2bcec464153a5130b170b2770 (patch)
treef8f5d8f18a115431e8826fa1c46580311dc1e485 /fs/btrfs/disk-io.c
parent6c41761fc6efe1503103a1afe03a6635c0b5d4ec (diff)
Btrfs: add a log of past tree roots
This takes some of the free space in the btrfs super block to record information about most of the roots in the last four commits. It also adds a -o recovery to use the root history log when we're not able to read the tree of tree roots, the extent tree root, the device tree root or the csum root. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c291
1 files changed, 268 insertions, 23 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 761717c98278..a61f8a6cf219 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1134,10 +1134,12 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
1134 1134
1135 generation = btrfs_root_generation(&root->root_item); 1135 generation = btrfs_root_generation(&root->root_item);
1136 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); 1136 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
1137 root->commit_root = NULL;
1137 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 1138 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
1138 blocksize, generation); 1139 blocksize, generation);
1139 if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { 1140 if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
1140 free_extent_buffer(root->node); 1141 free_extent_buffer(root->node);
1142 root->node = NULL;
1141 return -EIO; 1143 return -EIO;
1142 } 1144 }
1143 root->commit_root = btrfs_root_node(root); 1145 root->commit_root = btrfs_root_node(root);
@@ -1576,6 +1578,228 @@ sleep:
1576 return 0; 1578 return 0;
1577} 1579}
1578 1580
1581/*
1582 * this will find the highest generation in the array of
1583 * root backups. The index of the highest array is returned,
1584 * or -1 if we can't find anything.
1585 *
1586 * We check to make sure the array is valid by comparing the
1587 * generation of the latest root in the array with the generation
1588 * in the super block. If they don't match we pitch it.
1589 */
1590static int find_newest_super_backup(struct btrfs_fs_info *info, u64 newest_gen)
1591{
1592 u64 cur;
1593 int newest_index = -1;
1594 struct btrfs_root_backup *root_backup;
1595 int i;
1596
1597 for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
1598 root_backup = info->super_copy->super_roots + i;
1599 cur = btrfs_backup_tree_root_gen(root_backup);
1600 if (cur == newest_gen)
1601 newest_index = i;
1602 }
1603
1604 /* check to see if we actually wrapped around */
1605 if (newest_index == BTRFS_NUM_BACKUP_ROOTS - 1) {
1606 root_backup = info->super_copy->super_roots;
1607 cur = btrfs_backup_tree_root_gen(root_backup);
1608 if (cur == newest_gen)
1609 newest_index = 0;
1610 }
1611 return newest_index;
1612}
1613
1614
1615/*
1616 * find the oldest backup so we know where to store new entries
1617 * in the backup array. This will set the backup_root_index
1618 * field in the fs_info struct
1619 */
1620static void find_oldest_super_backup(struct btrfs_fs_info *info,
1621 u64 newest_gen)
1622{
1623 int newest_index = -1;
1624
1625 newest_index = find_newest_super_backup(info, newest_gen);
1626 /* if there was garbage in there, just move along */
1627 if (newest_index == -1) {
1628 info->backup_root_index = 0;
1629 } else {
1630 info->backup_root_index = (newest_index + 1) % BTRFS_NUM_BACKUP_ROOTS;
1631 }
1632}
1633
1634/*
1635 * copy all the root pointers into the super backup array.
1636 * this will bump the backup pointer by one when it is
1637 * done
1638 */
1639static void backup_super_roots(struct btrfs_fs_info *info)
1640{
1641 int next_backup;
1642 struct btrfs_root_backup *root_backup;
1643 int last_backup;
1644
1645 next_backup = info->backup_root_index;
1646 last_backup = (next_backup + BTRFS_NUM_BACKUP_ROOTS - 1) %
1647 BTRFS_NUM_BACKUP_ROOTS;
1648
1649 /*
1650 * just overwrite the last backup if we're at the same generation
1651 * this happens only at umount
1652 */
1653 root_backup = info->super_for_commit->super_roots + last_backup;
1654 if (btrfs_backup_tree_root_gen(root_backup) ==
1655 btrfs_header_generation(info->tree_root->node))
1656 next_backup = last_backup;
1657
1658 root_backup = info->super_for_commit->super_roots + next_backup;
1659
1660 /*
1661 * make sure all of our padding and empty slots get zero filled
1662 * regardless of which ones we use today
1663 */
1664 memset(root_backup, 0, sizeof(*root_backup));
1665
1666 info->backup_root_index = (next_backup + 1) % BTRFS_NUM_BACKUP_ROOTS;
1667
1668 btrfs_set_backup_tree_root(root_backup, info->tree_root->node->start);
1669 btrfs_set_backup_tree_root_gen(root_backup,
1670 btrfs_header_generation(info->tree_root->node));
1671
1672 btrfs_set_backup_tree_root_level(root_backup,
1673 btrfs_header_level(info->tree_root->node));
1674
1675 btrfs_set_backup_chunk_root(root_backup, info->chunk_root->node->start);
1676 btrfs_set_backup_chunk_root_gen(root_backup,
1677 btrfs_header_generation(info->chunk_root->node));
1678 btrfs_set_backup_chunk_root_level(root_backup,
1679 btrfs_header_level(info->chunk_root->node));
1680
1681 btrfs_set_backup_extent_root(root_backup, info->extent_root->node->start);
1682 btrfs_set_backup_extent_root_gen(root_backup,
1683 btrfs_header_generation(info->extent_root->node));
1684 btrfs_set_backup_extent_root_level(root_backup,
1685 btrfs_header_level(info->extent_root->node));
1686
1687 btrfs_set_backup_fs_root(root_backup, info->fs_root->node->start);
1688 btrfs_set_backup_fs_root_gen(root_backup,
1689 btrfs_header_generation(info->fs_root->node));
1690 btrfs_set_backup_fs_root_level(root_backup,
1691 btrfs_header_level(info->fs_root->node));
1692
1693 btrfs_set_backup_dev_root(root_backup, info->dev_root->node->start);
1694 btrfs_set_backup_dev_root_gen(root_backup,
1695 btrfs_header_generation(info->dev_root->node));
1696 btrfs_set_backup_dev_root_level(root_backup,
1697 btrfs_header_level(info->dev_root->node));
1698
1699 btrfs_set_backup_csum_root(root_backup, info->csum_root->node->start);
1700 btrfs_set_backup_csum_root_gen(root_backup,
1701 btrfs_header_generation(info->csum_root->node));
1702 btrfs_set_backup_csum_root_level(root_backup,
1703 btrfs_header_level(info->csum_root->node));
1704
1705 btrfs_set_backup_total_bytes(root_backup,
1706 btrfs_super_total_bytes(info->super_copy));
1707 btrfs_set_backup_bytes_used(root_backup,
1708 btrfs_super_bytes_used(info->super_copy));
1709 btrfs_set_backup_num_devices(root_backup,
1710 btrfs_super_num_devices(info->super_copy));
1711
1712 /*
1713 * if we don't copy this out to the super_copy, it won't get remembered
1714 * for the next commit
1715 */
1716 memcpy(&info->super_copy->super_roots,
1717 &info->super_for_commit->super_roots,
1718 sizeof(*root_backup) * BTRFS_NUM_BACKUP_ROOTS);
1719}
1720
1721/*
1722 * this copies info out of the root backup array and back into
1723 * the in-memory super block. It is meant to help iterate through
1724 * the array, so you send it the number of backups you've already
1725 * tried and the last backup index you used.
1726 *
1727 * this returns -1 when it has tried all the backups
1728 */
1729static noinline int next_root_backup(struct btrfs_fs_info *info,
1730 struct btrfs_super_block *super,
1731 int *num_backups_tried, int *backup_index)
1732{
1733 struct btrfs_root_backup *root_backup;
1734 int newest = *backup_index;
1735
1736 if (*num_backups_tried == 0) {
1737 u64 gen = btrfs_super_generation(super);
1738
1739 newest = find_newest_super_backup(info, gen);
1740 if (newest == -1)
1741 return -1;
1742
1743 *backup_index = newest;
1744 *num_backups_tried = 1;
1745 } else if (*num_backups_tried == BTRFS_NUM_BACKUP_ROOTS) {
1746 /* we've tried all the backups, all done */
1747 return -1;
1748 } else {
1749 /* jump to the next oldest backup */
1750 newest = (*backup_index + BTRFS_NUM_BACKUP_ROOTS - 1) %
1751 BTRFS_NUM_BACKUP_ROOTS;
1752 *backup_index = newest;
1753 *num_backups_tried += 1;
1754 }
1755 root_backup = super->super_roots + newest;
1756
1757 btrfs_set_super_generation(super,
1758 btrfs_backup_tree_root_gen(root_backup));
1759 btrfs_set_super_root(super, btrfs_backup_tree_root(root_backup));
1760 btrfs_set_super_root_level(super,
1761 btrfs_backup_tree_root_level(root_backup));
1762 btrfs_set_super_bytes_used(super, btrfs_backup_bytes_used(root_backup));
1763
1764 /*
1765 * fixme: the total bytes and num_devices need to match or we should
1766 * need a fsck
1767 */
1768 btrfs_set_super_total_bytes(super, btrfs_backup_total_bytes(root_backup));
1769 btrfs_set_super_num_devices(super, btrfs_backup_num_devices(root_backup));
1770 return 0;
1771}
1772
1773/* helper to cleanup tree roots */
1774static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root)
1775{
1776 free_extent_buffer(info->tree_root->node);
1777 free_extent_buffer(info->tree_root->commit_root);
1778 free_extent_buffer(info->dev_root->node);
1779 free_extent_buffer(info->dev_root->commit_root);
1780 free_extent_buffer(info->extent_root->node);
1781 free_extent_buffer(info->extent_root->commit_root);
1782 free_extent_buffer(info->csum_root->node);
1783 free_extent_buffer(info->csum_root->commit_root);
1784
1785 info->tree_root->node = NULL;
1786 info->tree_root->commit_root = NULL;
1787 info->dev_root->node = NULL;
1788 info->dev_root->commit_root = NULL;
1789 info->extent_root->node = NULL;
1790 info->extent_root->commit_root = NULL;
1791 info->csum_root->node = NULL;
1792 info->csum_root->commit_root = NULL;
1793
1794 if (chunk_root) {
1795 free_extent_buffer(info->chunk_root->node);
1796 free_extent_buffer(info->chunk_root->commit_root);
1797 info->chunk_root->node = NULL;
1798 info->chunk_root->commit_root = NULL;
1799 }
1800}
1801
1802
1579struct btrfs_root *open_ctree(struct super_block *sb, 1803struct btrfs_root *open_ctree(struct super_block *sb,
1580 struct btrfs_fs_devices *fs_devices, 1804 struct btrfs_fs_devices *fs_devices,
1581 char *options) 1805 char *options)
@@ -1603,6 +1827,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1603 1827
1604 int ret; 1828 int ret;
1605 int err = -EINVAL; 1829 int err = -EINVAL;
1830 int num_backups_tried = 0;
1831 int backup_index = 0;
1606 1832
1607 struct btrfs_super_block *disk_super; 1833 struct btrfs_super_block *disk_super;
1608 1834
@@ -1782,6 +2008,13 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1782 btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY); 2008 btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY);
1783 2009
1784 /* 2010 /*
2011 * run through our array of backup supers and setup
2012 * our ring pointer to the oldest one
2013 */
2014 generation = btrfs_super_generation(disk_super);
2015 find_oldest_super_backup(fs_info, generation);
2016
2017 /*
1785 * In the long term, we'll store the compression type in the super 2018 * In the long term, we'll store the compression type in the super
1786 * block, and it'll be used for per file compression control. 2019 * block, and it'll be used for per file compression control.
1787 */ 2020 */
@@ -1938,7 +2171,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1938 if (!test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) { 2171 if (!test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) {
1939 printk(KERN_WARNING "btrfs: failed to read chunk root on %s\n", 2172 printk(KERN_WARNING "btrfs: failed to read chunk root on %s\n",
1940 sb->s_id); 2173 sb->s_id);
1941 goto fail_chunk_root; 2174 goto fail_tree_roots;
1942 } 2175 }
1943 btrfs_set_root_node(&chunk_root->root_item, chunk_root->node); 2176 btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
1944 chunk_root->commit_root = btrfs_root_node(chunk_root); 2177 chunk_root->commit_root = btrfs_root_node(chunk_root);
@@ -1953,11 +2186,12 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1953 if (ret) { 2186 if (ret) {
1954 printk(KERN_WARNING "btrfs: failed to read chunk tree on %s\n", 2187 printk(KERN_WARNING "btrfs: failed to read chunk tree on %s\n",
1955 sb->s_id); 2188 sb->s_id);
1956 goto fail_chunk_root; 2189 goto fail_tree_roots;
1957 } 2190 }
1958 2191
1959 btrfs_close_extra_devices(fs_devices); 2192 btrfs_close_extra_devices(fs_devices);
1960 2193
2194retry_root_backup:
1961 blocksize = btrfs_level_size(tree_root, 2195 blocksize = btrfs_level_size(tree_root,
1962 btrfs_super_root_level(disk_super)); 2196 btrfs_super_root_level(disk_super));
1963 generation = btrfs_super_generation(disk_super); 2197 generation = btrfs_super_generation(disk_super);
@@ -1965,32 +2199,33 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1965 tree_root->node = read_tree_block(tree_root, 2199 tree_root->node = read_tree_block(tree_root,
1966 btrfs_super_root(disk_super), 2200 btrfs_super_root(disk_super),
1967 blocksize, generation); 2201 blocksize, generation);
1968 if (!tree_root->node) 2202 if (!tree_root->node ||
1969 goto fail_chunk_root; 2203 !test_bit(EXTENT_BUFFER_UPTODATE, &tree_root->node->bflags)) {
1970 if (!test_bit(EXTENT_BUFFER_UPTODATE, &tree_root->node->bflags)) {
1971 printk(KERN_WARNING "btrfs: failed to read tree root on %s\n", 2204 printk(KERN_WARNING "btrfs: failed to read tree root on %s\n",
1972 sb->s_id); 2205 sb->s_id);
1973 goto fail_tree_root; 2206
2207 goto recovery_tree_root;
1974 } 2208 }
2209
1975 btrfs_set_root_node(&tree_root->root_item, tree_root->node); 2210 btrfs_set_root_node(&tree_root->root_item, tree_root->node);
1976 tree_root->commit_root = btrfs_root_node(tree_root); 2211 tree_root->commit_root = btrfs_root_node(tree_root);
1977 2212
1978 ret = find_and_setup_root(tree_root, fs_info, 2213 ret = find_and_setup_root(tree_root, fs_info,
1979 BTRFS_EXTENT_TREE_OBJECTID, extent_root); 2214 BTRFS_EXTENT_TREE_OBJECTID, extent_root);
1980 if (ret) 2215 if (ret)
1981 goto fail_tree_root; 2216 goto recovery_tree_root;
1982 extent_root->track_dirty = 1; 2217 extent_root->track_dirty = 1;
1983 2218
1984 ret = find_and_setup_root(tree_root, fs_info, 2219 ret = find_and_setup_root(tree_root, fs_info,
1985 BTRFS_DEV_TREE_OBJECTID, dev_root); 2220 BTRFS_DEV_TREE_OBJECTID, dev_root);
1986 if (ret) 2221 if (ret)
1987 goto fail_extent_root; 2222 goto recovery_tree_root;
1988 dev_root->track_dirty = 1; 2223 dev_root->track_dirty = 1;
1989 2224
1990 ret = find_and_setup_root(tree_root, fs_info, 2225 ret = find_and_setup_root(tree_root, fs_info,
1991 BTRFS_CSUM_TREE_OBJECTID, csum_root); 2226 BTRFS_CSUM_TREE_OBJECTID, csum_root);
1992 if (ret) 2227 if (ret)
1993 goto fail_dev_root; 2228 goto recovery_tree_root;
1994 2229
1995 csum_root->track_dirty = 1; 2230 csum_root->track_dirty = 1;
1996 2231
@@ -2123,20 +2358,10 @@ fail_cleaner:
2123 2358
2124fail_block_groups: 2359fail_block_groups:
2125 btrfs_free_block_groups(fs_info); 2360 btrfs_free_block_groups(fs_info);
2126 free_extent_buffer(csum_root->node); 2361
2127 free_extent_buffer(csum_root->commit_root); 2362fail_tree_roots:
2128fail_dev_root: 2363 free_root_pointers(fs_info, 1);
2129 free_extent_buffer(dev_root->node); 2364
2130 free_extent_buffer(dev_root->commit_root);
2131fail_extent_root:
2132 free_extent_buffer(extent_root->node);
2133 free_extent_buffer(extent_root->commit_root);
2134fail_tree_root:
2135 free_extent_buffer(tree_root->node);
2136 free_extent_buffer(tree_root->commit_root);
2137fail_chunk_root:
2138 free_extent_buffer(chunk_root->node);
2139 free_extent_buffer(chunk_root->commit_root);
2140fail_sb_buffer: 2365fail_sb_buffer:
2141 btrfs_stop_workers(&fs_info->generic_worker); 2366 btrfs_stop_workers(&fs_info->generic_worker);
2142 btrfs_stop_workers(&fs_info->fixup_workers); 2367 btrfs_stop_workers(&fs_info->fixup_workers);
@@ -2164,6 +2389,25 @@ fail_srcu:
2164fail: 2389fail:
2165 free_fs_info(fs_info); 2390 free_fs_info(fs_info);
2166 return ERR_PTR(err); 2391 return ERR_PTR(err);
2392
2393recovery_tree_root:
2394
2395 if (!btrfs_test_opt(tree_root, RECOVERY))
2396 goto fail_tree_roots;
2397
2398 free_root_pointers(fs_info, 0);
2399
2400 /* don't use the log in recovery mode, it won't be valid */
2401 btrfs_set_super_log_root(disk_super, 0);
2402
2403 /* we can't trust the free space cache either */
2404 btrfs_set_opt(fs_info->mount_opt, CLEAR_CACHE);
2405
2406 ret = next_root_backup(fs_info, fs_info->super_copy,
2407 &num_backups_tried, &backup_index);
2408 if (ret == -1)
2409 goto fail_block_groups;
2410 goto retry_root_backup;
2167} 2411}
2168 2412
2169static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate) 2413static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate)
@@ -2333,6 +2577,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors)
2333 2577
2334 max_errors = btrfs_super_num_devices(root->fs_info->super_copy) - 1; 2578 max_errors = btrfs_super_num_devices(root->fs_info->super_copy) - 1;
2335 do_barriers = !btrfs_test_opt(root, NOBARRIER); 2579 do_barriers = !btrfs_test_opt(root, NOBARRIER);
2580 backup_super_roots(root->fs_info);
2336 2581
2337 sb = root->fs_info->super_for_commit; 2582 sb = root->fs_info->super_for_commit;
2338 dev_item = &sb->dev_item; 2583 dev_item = &sb->dev_item;