aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c79
1 files changed, 68 insertions, 11 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 3cf17257f89d..7feac5a475e9 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -849,6 +849,14 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
849 spin_lock_init(&root->list_lock); 849 spin_lock_init(&root->list_lock);
850 mutex_init(&root->objectid_mutex); 850 mutex_init(&root->objectid_mutex);
851 mutex_init(&root->log_mutex); 851 mutex_init(&root->log_mutex);
852 init_waitqueue_head(&root->log_writer_wait);
853 init_waitqueue_head(&root->log_commit_wait[0]);
854 init_waitqueue_head(&root->log_commit_wait[1]);
855 atomic_set(&root->log_commit[0], 0);
856 atomic_set(&root->log_commit[1], 0);
857 atomic_set(&root->log_writers, 0);
858 root->log_batch = 0;
859 root->log_transid = 0;
852 extent_io_tree_init(&root->dirty_log_pages, 860 extent_io_tree_init(&root->dirty_log_pages,
853 fs_info->btree_inode->i_mapping, GFP_NOFS); 861 fs_info->btree_inode->i_mapping, GFP_NOFS);
854 862
@@ -933,15 +941,16 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans,
933 return 0; 941 return 0;
934} 942}
935 943
936int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, 944static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
937 struct btrfs_fs_info *fs_info) 945 struct btrfs_fs_info *fs_info)
938{ 946{
939 struct btrfs_root *root; 947 struct btrfs_root *root;
940 struct btrfs_root *tree_root = fs_info->tree_root; 948 struct btrfs_root *tree_root = fs_info->tree_root;
949 struct extent_buffer *leaf;
941 950
942 root = kzalloc(sizeof(*root), GFP_NOFS); 951 root = kzalloc(sizeof(*root), GFP_NOFS);
943 if (!root) 952 if (!root)
944 return -ENOMEM; 953 return ERR_PTR(-ENOMEM);
945 954
946 __setup_root(tree_root->nodesize, tree_root->leafsize, 955 __setup_root(tree_root->nodesize, tree_root->leafsize,
947 tree_root->sectorsize, tree_root->stripesize, 956 tree_root->sectorsize, tree_root->stripesize,
@@ -950,12 +959,23 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
950 root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; 959 root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID;
951 root->root_key.type = BTRFS_ROOT_ITEM_KEY; 960 root->root_key.type = BTRFS_ROOT_ITEM_KEY;
952 root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; 961 root->root_key.offset = BTRFS_TREE_LOG_OBJECTID;
962 /*
963 * log trees do not get reference counted because they go away
964 * before a real commit is actually done. They do store pointers
965 * to file data extents, and those reference counts still get
966 * updated (along with back refs to the log tree).
967 */
953 root->ref_cows = 0; 968 root->ref_cows = 0;
954 969
955 root->node = btrfs_alloc_free_block(trans, root, root->leafsize, 970 leaf = btrfs_alloc_free_block(trans, root, root->leafsize,
956 0, BTRFS_TREE_LOG_OBJECTID, 971 0, BTRFS_TREE_LOG_OBJECTID,
957 trans->transid, 0, 0, 0); 972 trans->transid, 0, 0, 0);
973 if (IS_ERR(leaf)) {
974 kfree(root);
975 return ERR_CAST(leaf);
976 }
958 977
978 root->node = leaf;
959 btrfs_set_header_nritems(root->node, 0); 979 btrfs_set_header_nritems(root->node, 0);
960 btrfs_set_header_level(root->node, 0); 980 btrfs_set_header_level(root->node, 0);
961 btrfs_set_header_bytenr(root->node, root->node->start); 981 btrfs_set_header_bytenr(root->node, root->node->start);
@@ -967,7 +987,48 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
967 BTRFS_FSID_SIZE); 987 BTRFS_FSID_SIZE);
968 btrfs_mark_buffer_dirty(root->node); 988 btrfs_mark_buffer_dirty(root->node);
969 btrfs_tree_unlock(root->node); 989 btrfs_tree_unlock(root->node);
970 fs_info->log_root_tree = root; 990 return root;
991}
992
993int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
994 struct btrfs_fs_info *fs_info)
995{
996 struct btrfs_root *log_root;
997
998 log_root = alloc_log_tree(trans, fs_info);
999 if (IS_ERR(log_root))
1000 return PTR_ERR(log_root);
1001 WARN_ON(fs_info->log_root_tree);
1002 fs_info->log_root_tree = log_root;
1003 return 0;
1004}
1005
1006int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
1007 struct btrfs_root *root)
1008{
1009 struct btrfs_root *log_root;
1010 struct btrfs_inode_item *inode_item;
1011
1012 log_root = alloc_log_tree(trans, root->fs_info);
1013 if (IS_ERR(log_root))
1014 return PTR_ERR(log_root);
1015
1016 log_root->last_trans = trans->transid;
1017 log_root->root_key.offset = root->root_key.objectid;
1018
1019 inode_item = &log_root->root_item.inode;
1020 inode_item->generation = cpu_to_le64(1);
1021 inode_item->size = cpu_to_le64(3);
1022 inode_item->nlink = cpu_to_le32(1);
1023 inode_item->nbytes = cpu_to_le64(root->leafsize);
1024 inode_item->mode = cpu_to_le32(S_IFDIR | 0755);
1025
1026 btrfs_set_root_bytenr(&log_root->root_item, log_root->node->start);
1027 btrfs_set_root_generation(&log_root->root_item, trans->transid);
1028
1029 WARN_ON(root->log_root);
1030 root->log_root = log_root;
1031 root->log_transid = 0;
971 return 0; 1032 return 0;
972} 1033}
973 1034
@@ -1530,10 +1591,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1530 init_waitqueue_head(&fs_info->transaction_throttle); 1591 init_waitqueue_head(&fs_info->transaction_throttle);
1531 init_waitqueue_head(&fs_info->transaction_wait); 1592 init_waitqueue_head(&fs_info->transaction_wait);
1532 init_waitqueue_head(&fs_info->async_submit_wait); 1593 init_waitqueue_head(&fs_info->async_submit_wait);
1533 init_waitqueue_head(&fs_info->tree_log_wait);
1534 atomic_set(&fs_info->tree_log_commit, 0);
1535 atomic_set(&fs_info->tree_log_writers, 0);
1536 fs_info->tree_log_transid = 0;
1537 1594
1538 __setup_root(4096, 4096, 4096, 4096, tree_root, 1595 __setup_root(4096, 4096, 4096, 4096, tree_root,
1539 fs_info, BTRFS_ROOT_TREE_OBJECTID); 1596 fs_info, BTRFS_ROOT_TREE_OBJECTID);