diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2008-10-29 19:49:05 +0100 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-10-29 19:49:05 +0100 |
commit | 84234f3a1f7c532e4afeba03cc8e7e4a8a5277ea (patch) | |
tree | c41f249b448f28b648b21c3898d0763b9c67ca6a /fs/btrfs/transaction.c | |
parent | Btrfs: nuke fs wide allocation mutex V2 (diff) | |
download | linux-84234f3a1f7c532e4afeba03cc8e7e4a8a5277ea.tar.xz linux-84234f3a1f7c532e4afeba03cc8e7e4a8a5277ea.zip |
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.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 48b455fdaac5..924af6f2aeac 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, root->node->start); btrfs_set_root_level(&root->root_item, btrfs_header_level(root->node)); + btrfs_set_root_generation(&root->root_item, trans->transid); ret = btrfs_update_root(trans, tree_root, &root->root_key, &root->root_item); @@ -456,6 +457,12 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, { struct btrfs_fs_info *fs_info = root->fs_info; struct list_head *next; + struct extent_buffer *eb; + + eb = btrfs_lock_root_node(fs_info->tree_root); + btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb, 0); + btrfs_tree_unlock(eb); + free_extent_buffer(eb); while(!list_empty(&fs_info->dirty_cowonly_roots)) { next = fs_info->dirty_cowonly_roots.next; @@ -559,6 +566,9 @@ static noinline int add_dirty_roots(struct btrfs_trans_handle *trans, root->node->start); btrfs_set_root_level(&root->root_item, btrfs_header_level(root->node)); + btrfs_set_root_generation(&root->root_item, + root->root_key.offset); + err = btrfs_insert_root(trans, root->fs_info->tree_root, &root->root_key, &root->root_item); @@ -756,6 +766,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, btrfs_set_root_bytenr(new_root_item, tmp->start); btrfs_set_root_level(new_root_item, btrfs_header_level(tmp)); + btrfs_set_root_generation(new_root_item, trans->transid); ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, new_root_item); btrfs_tree_unlock(tmp); @@ -946,6 +957,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, chunk_root->node->start); btrfs_set_super_chunk_root_level(&root->fs_info->super_copy, btrfs_header_level(chunk_root->node)); + btrfs_set_super_chunk_root_generation(&root->fs_info->super_copy, + btrfs_header_generation(chunk_root->node)); if (!root->fs_info->log_root_recovering) { btrfs_set_super_log_root(&root->fs_info->super_copy, 0); |