aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.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/transaction.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/transaction.c')
-rw-r--r--fs/btrfs/transaction.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 48b455fdaac..924af6f2aea 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -439,6 +439,7 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
439 root->node->start); 439 root->node->start);
440 btrfs_set_root_level(&root->root_item, 440 btrfs_set_root_level(&root->root_item,
441 btrfs_header_level(root->node)); 441 btrfs_header_level(root->node));
442 btrfs_set_root_generation(&root->root_item, trans->transid);
442 ret = btrfs_update_root(trans, tree_root, 443 ret = btrfs_update_root(trans, tree_root,
443 &root->root_key, 444 &root->root_key,
444 &root->root_item); 445 &root->root_item);
@@ -456,6 +457,12 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
456{ 457{
457 struct btrfs_fs_info *fs_info = root->fs_info; 458 struct btrfs_fs_info *fs_info = root->fs_info;
458 struct list_head *next; 459 struct list_head *next;
460 struct extent_buffer *eb;
461
462 eb = btrfs_lock_root_node(fs_info->tree_root);
463 btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb, 0);
464 btrfs_tree_unlock(eb);
465 free_extent_buffer(eb);
459 466
460 while(!list_empty(&fs_info->dirty_cowonly_roots)) { 467 while(!list_empty(&fs_info->dirty_cowonly_roots)) {
461 next = fs_info->dirty_cowonly_roots.next; 468 next = fs_info->dirty_cowonly_roots.next;
@@ -559,6 +566,9 @@ static noinline int add_dirty_roots(struct btrfs_trans_handle *trans,
559 root->node->start); 566 root->node->start);
560 btrfs_set_root_level(&root->root_item, 567 btrfs_set_root_level(&root->root_item,
561 btrfs_header_level(root->node)); 568 btrfs_header_level(root->node));
569 btrfs_set_root_generation(&root->root_item,
570 root->root_key.offset);
571
562 err = btrfs_insert_root(trans, root->fs_info->tree_root, 572 err = btrfs_insert_root(trans, root->fs_info->tree_root,
563 &root->root_key, 573 &root->root_key,
564 &root->root_item); 574 &root->root_item);
@@ -756,6 +766,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
756 766
757 btrfs_set_root_bytenr(new_root_item, tmp->start); 767 btrfs_set_root_bytenr(new_root_item, tmp->start);
758 btrfs_set_root_level(new_root_item, btrfs_header_level(tmp)); 768 btrfs_set_root_level(new_root_item, btrfs_header_level(tmp));
769 btrfs_set_root_generation(new_root_item, trans->transid);
759 ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, 770 ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
760 new_root_item); 771 new_root_item);
761 btrfs_tree_unlock(tmp); 772 btrfs_tree_unlock(tmp);
@@ -946,6 +957,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
946 chunk_root->node->start); 957 chunk_root->node->start);
947 btrfs_set_super_chunk_root_level(&root->fs_info->super_copy, 958 btrfs_set_super_chunk_root_level(&root->fs_info->super_copy,
948 btrfs_header_level(chunk_root->node)); 959 btrfs_header_level(chunk_root->node));
960 btrfs_set_super_chunk_root_generation(&root->fs_info->super_copy,
961 btrfs_header_generation(chunk_root->node));
949 962
950 if (!root->fs_info->log_root_recovering) { 963 if (!root->fs_info->log_root_recovering) {
951 btrfs_set_super_log_root(&root->fs_info->super_copy, 0); 964 btrfs_set_super_log_root(&root->fs_info->super_copy, 0);