aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/transaction.c97
1 files changed, 31 insertions, 66 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 43054285f638..01cebd661997 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -755,10 +755,17 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
755 struct btrfs_root_item *new_root_item; 755 struct btrfs_root_item *new_root_item;
756 struct btrfs_root *tree_root = fs_info->tree_root; 756 struct btrfs_root *tree_root = fs_info->tree_root;
757 struct btrfs_root *root = pending->root; 757 struct btrfs_root *root = pending->root;
758 struct btrfs_root *parent_root;
759 struct inode *parent_inode;
758 struct extent_buffer *tmp; 760 struct extent_buffer *tmp;
759 struct extent_buffer *old; 761 struct extent_buffer *old;
760 int ret; 762 int ret;
761 u64 objectid; 763 u64 objectid;
764 int namelen;
765 u64 index = 0;
766
767 parent_inode = pending->dentry->d_parent->d_inode;
768 parent_root = BTRFS_I(parent_inode)->root;
762 769
763 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); 770 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
764 if (!new_root_item) { 771 if (!new_root_item) {
@@ -769,79 +776,59 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
769 if (ret) 776 if (ret)
770 goto fail; 777 goto fail;
771 778
772 record_root_in_trans(trans, root);
773 btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
774 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
775
776 key.objectid = objectid; 779 key.objectid = objectid;
777 /* record when the snapshot was created in key.offset */ 780 /* record when the snapshot was created in key.offset */
778 key.offset = trans->transid; 781 key.offset = trans->transid;
779 btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); 782 btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
780 783
781 old = btrfs_lock_root_node(root);
782 btrfs_cow_block(trans, root, old, NULL, 0, &old);
783 btrfs_set_lock_blocking(old);
784
785 btrfs_copy_root(trans, root, old, &tmp, objectid);
786 btrfs_tree_unlock(old);
787 free_extent_buffer(old);
788
789 btrfs_set_root_node(new_root_item, tmp);
790 ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
791 new_root_item);
792 btrfs_tree_unlock(tmp);
793 free_extent_buffer(tmp);
794 if (ret)
795 goto fail;
796
797 key.offset = (u64)-1;
798 memcpy(&pending->root_key, &key, sizeof(key)); 784 memcpy(&pending->root_key, &key, sizeof(key));
799fail: 785 pending->root_key.offset = (u64)-1;
800 kfree(new_root_item);
801 return ret;
802}
803
804static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
805 struct btrfs_pending_snapshot *pending)
806{
807 int ret;
808 int namelen;
809 u64 index = 0;
810 struct btrfs_trans_handle *trans;
811 struct inode *parent_inode;
812 struct btrfs_root *parent_root;
813
814 parent_inode = pending->dentry->d_parent->d_inode;
815 parent_root = BTRFS_I(parent_inode)->root;
816 trans = btrfs_join_transaction(parent_root, 1);
817 786
787 record_root_in_trans(trans, parent_root);
818 /* 788 /*
819 * insert the directory item 789 * insert the directory item
820 */ 790 */
821 namelen = strlen(pending->name); 791 namelen = strlen(pending->name);
822 ret = btrfs_set_inode_index(parent_inode, &index); 792 ret = btrfs_set_inode_index(parent_inode, &index);
793 BUG_ON(ret);
823 ret = btrfs_insert_dir_item(trans, parent_root, 794 ret = btrfs_insert_dir_item(trans, parent_root,
824 pending->name, namelen, 795 pending->name, namelen,
825 parent_inode->i_ino, 796 parent_inode->i_ino,
826 &pending->root_key, BTRFS_FT_DIR, index); 797 &pending->root_key, BTRFS_FT_DIR, index);
827 798 BUG_ON(ret);
828 if (ret)
829 goto fail;
830 799
831 btrfs_i_size_write(parent_inode, parent_inode->i_size + namelen * 2); 800 btrfs_i_size_write(parent_inode, parent_inode->i_size + namelen * 2);
832 ret = btrfs_update_inode(trans, parent_root, parent_inode); 801 ret = btrfs_update_inode(trans, parent_root, parent_inode);
833 BUG_ON(ret); 802 BUG_ON(ret);
834 803
804 record_root_in_trans(trans, root);
805 btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
806 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
807
808 old = btrfs_lock_root_node(root);
809 btrfs_cow_block(trans, root, old, NULL, 0, &old);
810 btrfs_set_lock_blocking(old);
811
812 btrfs_copy_root(trans, root, old, &tmp, objectid);
813 btrfs_tree_unlock(old);
814 free_extent_buffer(old);
815
816 btrfs_set_root_node(new_root_item, tmp);
817 ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
818 new_root_item);
819 BUG_ON(ret);
820 btrfs_tree_unlock(tmp);
821 free_extent_buffer(tmp);
822
835 ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root, 823 ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root,
836 pending->root_key.objectid, 824 pending->root_key.objectid,
837 parent_root->root_key.objectid, 825 parent_root->root_key.objectid,
838 parent_inode->i_ino, index, pending->name, 826 parent_inode->i_ino, index, pending->name,
839 namelen); 827 namelen);
840
841 BUG_ON(ret); 828 BUG_ON(ret);
842 829
843fail: 830fail:
844 btrfs_end_transaction(trans, fs_info->fs_root); 831 kfree(new_root_item);
845 return ret; 832 return ret;
846} 833}
847 834
@@ -862,25 +849,6 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
862 return 0; 849 return 0;
863} 850}
864 851
865static noinline int finish_pending_snapshots(struct btrfs_trans_handle *trans,
866 struct btrfs_fs_info *fs_info)
867{
868 struct btrfs_pending_snapshot *pending;
869 struct list_head *head = &trans->transaction->pending_snapshots;
870 int ret;
871
872 while (!list_empty(head)) {
873 pending = list_entry(head->next,
874 struct btrfs_pending_snapshot, list);
875 ret = finish_pending_snapshot(fs_info, pending);
876 BUG_ON(ret);
877 list_del(&pending->list);
878 kfree(pending->name);
879 kfree(pending);
880 }
881 return 0;
882}
883
884static void update_super_roots(struct btrfs_root *root) 852static void update_super_roots(struct btrfs_root *root)
885{ 853{
886 struct btrfs_root_item *root_item; 854 struct btrfs_root_item *root_item;
@@ -1092,9 +1060,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1092 1060
1093 btrfs_finish_extent_commit(trans, root); 1061 btrfs_finish_extent_commit(trans, root);
1094 1062
1095 /* do the directory inserts of any pending snapshot creations */
1096 finish_pending_snapshots(trans, root->fs_info);
1097
1098 mutex_lock(&root->fs_info->trans_mutex); 1063 mutex_lock(&root->fs_info->trans_mutex);
1099 1064
1100 cur_trans->commit_done = 1; 1065 cur_trans->commit_done = 1;