diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 38 |
1 files changed, 12 insertions, 26 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index cdbb5022da52..88f866f85e7a 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -104,7 +104,6 @@ static noinline int record_root_in_trans(struct btrfs_trans_handle *trans, | |||
104 | { | 104 | { |
105 | if (root->ref_cows && root->last_trans < trans->transid) { | 105 | if (root->ref_cows && root->last_trans < trans->transid) { |
106 | WARN_ON(root == root->fs_info->extent_root); | 106 | WARN_ON(root == root->fs_info->extent_root); |
107 | WARN_ON(root->root_item.refs == 0); | ||
108 | WARN_ON(root->commit_root != root->node); | 107 | WARN_ON(root->commit_root != root->node); |
109 | 108 | ||
110 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, | 109 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, |
@@ -720,7 +719,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
720 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); | 719 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); |
721 | 720 | ||
722 | key.objectid = objectid; | 721 | key.objectid = objectid; |
723 | key.offset = 0; | 722 | /* record when the snapshot was created in key.offset */ |
723 | key.offset = trans->transid; | ||
724 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 724 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
725 | 725 | ||
726 | old = btrfs_lock_root_node(root); | 726 | old = btrfs_lock_root_node(root); |
@@ -778,24 +778,14 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info, | |||
778 | ret = btrfs_update_inode(trans, parent_root, parent_inode); | 778 | ret = btrfs_update_inode(trans, parent_root, parent_inode); |
779 | BUG_ON(ret); | 779 | BUG_ON(ret); |
780 | 780 | ||
781 | /* add the backref first */ | ||
782 | ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root, | 781 | ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root, |
783 | pending->root_key.objectid, | 782 | pending->root_key.objectid, |
784 | BTRFS_ROOT_BACKREF_KEY, | ||
785 | parent_root->root_key.objectid, | 783 | parent_root->root_key.objectid, |
786 | parent_inode->i_ino, index, pending->name, | 784 | parent_inode->i_ino, index, pending->name, |
787 | namelen); | 785 | namelen); |
788 | 786 | ||
789 | BUG_ON(ret); | 787 | BUG_ON(ret); |
790 | 788 | ||
791 | /* now add the forward ref */ | ||
792 | ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root, | ||
793 | parent_root->root_key.objectid, | ||
794 | BTRFS_ROOT_REF_KEY, | ||
795 | pending->root_key.objectid, | ||
796 | parent_inode->i_ino, index, pending->name, | ||
797 | namelen); | ||
798 | |||
799 | inode = btrfs_lookup_dentry(parent_inode, pending->dentry); | 789 | inode = btrfs_lookup_dentry(parent_inode, pending->dentry); |
800 | d_instantiate(pending->dentry, inode); | 790 | d_instantiate(pending->dentry, inode); |
801 | fail: | 791 | fail: |
@@ -874,7 +864,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
874 | unsigned long timeout = 1; | 864 | unsigned long timeout = 1; |
875 | struct btrfs_transaction *cur_trans; | 865 | struct btrfs_transaction *cur_trans; |
876 | struct btrfs_transaction *prev_trans = NULL; | 866 | struct btrfs_transaction *prev_trans = NULL; |
877 | struct extent_io_tree *pinned_copy; | ||
878 | DEFINE_WAIT(wait); | 867 | DEFINE_WAIT(wait); |
879 | int ret; | 868 | int ret; |
880 | int should_grow = 0; | 869 | int should_grow = 0; |
@@ -915,13 +904,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
915 | return 0; | 904 | return 0; |
916 | } | 905 | } |
917 | 906 | ||
918 | pinned_copy = kmalloc(sizeof(*pinned_copy), GFP_NOFS); | ||
919 | if (!pinned_copy) | ||
920 | return -ENOMEM; | ||
921 | |||
922 | extent_io_tree_init(pinned_copy, | ||
923 | root->fs_info->btree_inode->i_mapping, GFP_NOFS); | ||
924 | |||
925 | trans->transaction->in_commit = 1; | 907 | trans->transaction->in_commit = 1; |
926 | trans->transaction->blocked = 1; | 908 | trans->transaction->blocked = 1; |
927 | if (cur_trans->list.prev != &root->fs_info->trans_list) { | 909 | if (cur_trans->list.prev != &root->fs_info->trans_list) { |
@@ -1019,6 +1001,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1019 | ret = commit_cowonly_roots(trans, root); | 1001 | ret = commit_cowonly_roots(trans, root); |
1020 | BUG_ON(ret); | 1002 | BUG_ON(ret); |
1021 | 1003 | ||
1004 | btrfs_prepare_extent_commit(trans, root); | ||
1005 | |||
1022 | cur_trans = root->fs_info->running_transaction; | 1006 | cur_trans = root->fs_info->running_transaction; |
1023 | spin_lock(&root->fs_info->new_trans_lock); | 1007 | spin_lock(&root->fs_info->new_trans_lock); |
1024 | root->fs_info->running_transaction = NULL; | 1008 | root->fs_info->running_transaction = NULL; |
@@ -1042,8 +1026,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1042 | memcpy(&root->fs_info->super_for_commit, &root->fs_info->super_copy, | 1026 | memcpy(&root->fs_info->super_for_commit, &root->fs_info->super_copy, |
1043 | sizeof(root->fs_info->super_copy)); | 1027 | sizeof(root->fs_info->super_copy)); |
1044 | 1028 | ||
1045 | btrfs_copy_pinned(root, pinned_copy); | ||
1046 | |||
1047 | trans->transaction->blocked = 0; | 1029 | trans->transaction->blocked = 0; |
1048 | 1030 | ||
1049 | wake_up(&root->fs_info->transaction_wait); | 1031 | wake_up(&root->fs_info->transaction_wait); |
@@ -1059,8 +1041,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1059 | */ | 1041 | */ |
1060 | mutex_unlock(&root->fs_info->tree_log_mutex); | 1042 | mutex_unlock(&root->fs_info->tree_log_mutex); |
1061 | 1043 | ||
1062 | btrfs_finish_extent_commit(trans, root, pinned_copy); | 1044 | btrfs_finish_extent_commit(trans, root); |
1063 | kfree(pinned_copy); | ||
1064 | 1045 | ||
1065 | /* do the directory inserts of any pending snapshot creations */ | 1046 | /* do the directory inserts of any pending snapshot creations */ |
1066 | finish_pending_snapshots(trans, root->fs_info); | 1047 | finish_pending_snapshots(trans, root->fs_info); |
@@ -1096,8 +1077,13 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
1096 | 1077 | ||
1097 | while (!list_empty(&list)) { | 1078 | while (!list_empty(&list)) { |
1098 | root = list_entry(list.next, struct btrfs_root, root_list); | 1079 | root = list_entry(list.next, struct btrfs_root, root_list); |
1099 | list_del_init(&root->root_list); | 1080 | list_del(&root->root_list); |
1100 | btrfs_drop_snapshot(root, 0); | 1081 | |
1082 | if (btrfs_header_backref_rev(root->node) < | ||
1083 | BTRFS_MIXED_BACKREF_REV) | ||
1084 | btrfs_drop_snapshot(root, 0); | ||
1085 | else | ||
1086 | btrfs_drop_snapshot(root, 1); | ||
1101 | } | 1087 | } |
1102 | return 0; | 1088 | return 0; |
1103 | } | 1089 | } |