aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-10-29 14:49:05 -0400
committerChris Mason <chris.mason@oracle.com>2008-10-29 14:49:05 -0400
commit84234f3a1f7c532e4afeba03cc8e7e4a8a5277ea (patch)
treec41f249b448f28b648b21c3898d0763b9c67ca6a /fs/btrfs/disk-io.c
parent2517920135b0d29e70453e5b03d70d7b94207df3 (diff)
Btrfs: Add root tree pointer transaction ids
This patch adds transaction IDs to root tree pointers. Transaction IDs in tree pointers are compared with the generation numbers in block headers when reading root blocks of trees. This can detect some types of IO errors. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index d1137d7ea8d4..94b4e50f6b2c 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -832,6 +832,7 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
832{ 832{
833 int ret; 833 int ret;
834 u32 blocksize; 834 u32 blocksize;
835 u64 generation;
835 836
836 __setup_root(tree_root->nodesize, tree_root->leafsize, 837 __setup_root(tree_root->nodesize, tree_root->leafsize,
837 tree_root->sectorsize, tree_root->stripesize, 838 tree_root->sectorsize, tree_root->stripesize,
@@ -840,9 +841,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
840 &root->root_item, &root->root_key); 841 &root->root_item, &root->root_key);
841 BUG_ON(ret); 842 BUG_ON(ret);
842 843
844 generation = btrfs_root_generation(&root->root_item);
843 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); 845 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
844 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 846 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
845 blocksize, 0); 847 blocksize, generation);
846 BUG_ON(!root->node); 848 BUG_ON(!root->node);
847 return 0; 849 return 0;
848} 850}
@@ -929,6 +931,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
929 struct btrfs_path *path; 931 struct btrfs_path *path;
930 struct extent_buffer *l; 932 struct extent_buffer *l;
931 u64 highest_inode; 933 u64 highest_inode;
934 u64 generation;
932 u32 blocksize; 935 u32 blocksize;
933 int ret = 0; 936 int ret = 0;
934 937
@@ -970,9 +973,10 @@ out:
970 kfree(root); 973 kfree(root);
971 return ERR_PTR(ret); 974 return ERR_PTR(ret);
972 } 975 }
976 generation = btrfs_root_generation(&root->root_item);
973 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); 977 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
974 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 978 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
975 blocksize, 0); 979 blocksize, generation);
976 BUG_ON(!root->node); 980 BUG_ON(!root->node);
977insert: 981insert:
978 if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { 982 if (location->objectid != BTRFS_TREE_LOG_OBJECTID) {
@@ -1357,6 +1361,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1357 u32 leafsize; 1361 u32 leafsize;
1358 u32 blocksize; 1362 u32 blocksize;
1359 u32 stripesize; 1363 u32 stripesize;
1364 u64 generation;
1360 struct buffer_head *bh; 1365 struct buffer_head *bh;
1361 struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root), 1366 struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root),
1362 GFP_NOFS); 1367 GFP_NOFS);
@@ -1596,13 +1601,14 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1596 1601
1597 blocksize = btrfs_level_size(tree_root, 1602 blocksize = btrfs_level_size(tree_root,
1598 btrfs_super_chunk_root_level(disk_super)); 1603 btrfs_super_chunk_root_level(disk_super));
1604 generation = btrfs_super_chunk_root_generation(disk_super);
1599 1605
1600 __setup_root(nodesize, leafsize, sectorsize, stripesize, 1606 __setup_root(nodesize, leafsize, sectorsize, stripesize,
1601 chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID); 1607 chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID);
1602 1608
1603 chunk_root->node = read_tree_block(chunk_root, 1609 chunk_root->node = read_tree_block(chunk_root,
1604 btrfs_super_chunk_root(disk_super), 1610 btrfs_super_chunk_root(disk_super),
1605 blocksize, 0); 1611 blocksize, generation);
1606 BUG_ON(!chunk_root->node); 1612 BUG_ON(!chunk_root->node);
1607 1613
1608 read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid, 1614 read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
@@ -1618,11 +1624,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1618 1624
1619 blocksize = btrfs_level_size(tree_root, 1625 blocksize = btrfs_level_size(tree_root,
1620 btrfs_super_root_level(disk_super)); 1626 btrfs_super_root_level(disk_super));
1621 1627 generation = btrfs_super_generation(disk_super);
1622 1628
1623 tree_root->node = read_tree_block(tree_root, 1629 tree_root->node = read_tree_block(tree_root,
1624 btrfs_super_root(disk_super), 1630 btrfs_super_root(disk_super),
1625 blocksize, 0); 1631 blocksize, generation);
1626 if (!tree_root->node) 1632 if (!tree_root->node)
1627 goto fail_sb_buffer; 1633 goto fail_sb_buffer;
1628 1634
@@ -1672,15 +1678,16 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1672 log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID); 1678 log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID);
1673 1679
1674 log_tree_root->node = read_tree_block(tree_root, bytenr, 1680 log_tree_root->node = read_tree_block(tree_root, bytenr,
1675 blocksize, 0); 1681 blocksize,
1682 generation + 1);
1676 ret = btrfs_recover_log_trees(log_tree_root); 1683 ret = btrfs_recover_log_trees(log_tree_root);
1677 BUG_ON(ret); 1684 BUG_ON(ret);
1678 } 1685 }
1686 fs_info->last_trans_committed = btrfs_super_generation(disk_super);
1679 1687
1680 ret = btrfs_cleanup_reloc_trees(tree_root); 1688 ret = btrfs_cleanup_reloc_trees(tree_root);
1681 BUG_ON(ret); 1689 BUG_ON(ret);
1682 1690
1683 fs_info->last_trans_committed = btrfs_super_generation(disk_super);
1684 return tree_root; 1691 return tree_root;
1685 1692
1686fail_cleaner: 1693fail_cleaner: