aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-10-30 14:20:02 -0400
committerChris Mason <chris.mason@oracle.com>2008-10-30 14:20:02 -0400
commit80ff385665b7fca29fefe358a60ab0d09f9b8e87 (patch)
tree8a801d3f268d289b62f8dac87df8b757fb3b19d4
parent6643558db29006825dbb10012b3f8890aca4bcd5 (diff)
Btrfs: update nodatacow code v2
This patch simplifies the nodatacow checker. If all references were created after the latest snapshot, then we can avoid COW safely. This patch also updates run_delalloc_nocow to do more fine-grained checking. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
-rw-r--r--fs/btrfs/ctree.h8
-rw-r--r--fs/btrfs/extent-tree.c131
-rw-r--r--fs/btrfs/inode.c213
-rw-r--r--fs/btrfs/ioctl.c1
-rw-r--r--fs/btrfs/ordered-data.c9
-rw-r--r--fs/btrfs/ordered-data.h3
-rw-r--r--fs/btrfs/transaction.c2
7 files changed, 154 insertions, 213 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index ca5547af6090..8bf6a085a730 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -454,6 +454,7 @@ struct btrfs_root_item {
454 __le64 bytenr; 454 __le64 bytenr;
455 __le64 byte_limit; 455 __le64 byte_limit;
456 __le64 bytes_used; 456 __le64 bytes_used;
457 __le64 last_snapshot;
457 __le32 flags; 458 __le32 flags;
458 __le32 refs; 459 __le32 refs;
459 struct btrfs_disk_key drop_progress; 460 struct btrfs_disk_key drop_progress;
@@ -1413,6 +1414,8 @@ BTRFS_SETGET_STACK_FUNCS(root_refs, struct btrfs_root_item, refs, 32);
1413BTRFS_SETGET_STACK_FUNCS(root_flags, struct btrfs_root_item, flags, 32); 1414BTRFS_SETGET_STACK_FUNCS(root_flags, struct btrfs_root_item, flags, 32);
1414BTRFS_SETGET_STACK_FUNCS(root_used, struct btrfs_root_item, bytes_used, 64); 1415BTRFS_SETGET_STACK_FUNCS(root_used, struct btrfs_root_item, bytes_used, 64);
1415BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, byte_limit, 64); 1416BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, byte_limit, 64);
1417BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item,
1418 last_snapshot, 64);
1416 1419
1417/* struct btrfs_super_block */ 1420/* struct btrfs_super_block */
1418BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64); 1421BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64);
@@ -1564,9 +1567,8 @@ int btrfs_update_pinned_extents(struct btrfs_root *root,
1564 u64 bytenr, u64 num, int pin); 1567 u64 bytenr, u64 num, int pin);
1565int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, 1568int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans,
1566 struct btrfs_root *root, struct extent_buffer *leaf); 1569 struct btrfs_root *root, struct extent_buffer *leaf);
1567int btrfs_cross_ref_exists(struct btrfs_trans_handle *trans, 1570int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
1568 struct btrfs_root *root, 1571 struct btrfs_root *root, u64 bytenr);
1569 struct btrfs_key *key, u64 bytenr);
1570int btrfs_extent_post_op(struct btrfs_trans_handle *trans, 1572int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
1571 struct btrfs_root *root); 1573 struct btrfs_root *root);
1572int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy); 1574int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 535cee47fcfb..1eb69a91b727 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -848,9 +848,8 @@ out:
848 return 0; 848 return 0;
849} 849}
850 850
851static int get_reference_status(struct btrfs_root *root, u64 bytenr, 851int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
852 u64 parent_gen, u64 ref_objectid, 852 struct btrfs_root *root, u64 bytenr)
853 u64 *min_generation, u32 *ref_count)
854{ 853{
855 struct btrfs_root *extent_root = root->fs_info->extent_root; 854 struct btrfs_root *extent_root = root->fs_info->extent_root;
856 struct btrfs_path *path; 855 struct btrfs_path *path;
@@ -858,8 +857,8 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr,
858 struct btrfs_extent_ref *ref_item; 857 struct btrfs_extent_ref *ref_item;
859 struct btrfs_key key; 858 struct btrfs_key key;
860 struct btrfs_key found_key; 859 struct btrfs_key found_key;
861 u64 root_objectid = root->root_key.objectid; 860 u64 ref_root;
862 u64 ref_generation; 861 u64 last_snapshot;
863 u32 nritems; 862 u32 nritems;
864 int ret; 863 int ret;
865 864
@@ -872,7 +871,9 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr,
872 if (ret < 0) 871 if (ret < 0)
873 goto out; 872 goto out;
874 BUG_ON(ret == 0); 873 BUG_ON(ret == 0);
875 if (ret < 0 || path->slots[0] == 0) 874
875 ret = -ENOENT;
876 if (path->slots[0] == 0)
876 goto out; 877 goto out;
877 878
878 path->slots[0]--; 879 path->slots[0]--;
@@ -880,14 +881,10 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr,
880 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 881 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
881 882
882 if (found_key.objectid != bytenr || 883 if (found_key.objectid != bytenr ||
883 found_key.type != BTRFS_EXTENT_ITEM_KEY) { 884 found_key.type != BTRFS_EXTENT_ITEM_KEY)
884 ret = 1;
885 goto out; 885 goto out;
886 }
887
888 *ref_count = 0;
889 *min_generation = (u64)-1;
890 886
887 last_snapshot = btrfs_root_last_snapshot(&root->root_item);
891 while (1) { 888 while (1) {
892 leaf = path->nodes[0]; 889 leaf = path->nodes[0];
893 nritems = btrfs_header_nritems(leaf); 890 nritems = btrfs_header_nritems(leaf);
@@ -910,114 +907,22 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr,
910 907
911 ref_item = btrfs_item_ptr(leaf, path->slots[0], 908 ref_item = btrfs_item_ptr(leaf, path->slots[0],
912 struct btrfs_extent_ref); 909 struct btrfs_extent_ref);
913 ref_generation = btrfs_ref_generation(leaf, ref_item); 910 ref_root = btrfs_ref_root(leaf, ref_item);
914 /* 911 if (ref_root != root->root_key.objectid &&
915 * For (parent_gen > 0 && parent_gen > ref_generation): 912 ref_root != BTRFS_TREE_LOG_OBJECTID) {
916 * 913 ret = 1;
917 * we reach here through the oldest root, therefore
918 * all other reference from same snapshot should have
919 * a larger generation.
920 */
921 if ((root_objectid != btrfs_ref_root(leaf, ref_item)) ||
922 (parent_gen > 0 && parent_gen > ref_generation) ||
923 (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID &&
924 ref_objectid != btrfs_ref_objectid(leaf, ref_item))) {
925 *ref_count = 2;
926 break;
927 }
928
929 *ref_count = 1;
930 if (*min_generation > ref_generation)
931 *min_generation = ref_generation;
932
933 path->slots[0]++;
934 }
935 ret = 0;
936out:
937 btrfs_free_path(path);
938 return ret;
939}
940
941int btrfs_cross_ref_exists(struct btrfs_trans_handle *trans,
942 struct btrfs_root *root,
943 struct btrfs_key *key, u64 bytenr)
944{
945 struct btrfs_root *old_root;
946 struct btrfs_path *path = NULL;
947 struct extent_buffer *eb;
948 struct btrfs_file_extent_item *item;
949 u64 ref_generation;
950 u64 min_generation;
951 u64 extent_start;
952 u32 ref_count;
953 int level;
954 int ret;
955
956 BUG_ON(trans == NULL);
957 BUG_ON(key->type != BTRFS_EXTENT_DATA_KEY);
958 ret = get_reference_status(root, bytenr, 0, key->objectid,
959 &min_generation, &ref_count);
960 if (ret)
961 return ret;
962
963 if (ref_count != 1)
964 return 1;
965
966 old_root = root->dirty_root->root;
967 ref_generation = old_root->root_key.offset;
968
969 /* all references are created in running transaction */
970 if (min_generation > ref_generation) {
971 ret = 0;
972 goto out;
973 }
974
975 path = btrfs_alloc_path();
976 if (!path) {
977 ret = -ENOMEM;
978 goto out;
979 }
980
981 path->skip_locking = 1;
982 /* if no item found, the extent is referenced by other snapshot */
983 ret = btrfs_search_slot(NULL, old_root, key, path, 0, 0);
984 if (ret)
985 goto out;
986
987 eb = path->nodes[0];
988 item = btrfs_item_ptr(eb, path->slots[0],
989 struct btrfs_file_extent_item);
990 if (btrfs_file_extent_type(eb, item) != BTRFS_FILE_EXTENT_REG ||
991 btrfs_file_extent_disk_bytenr(eb, item) != bytenr) {
992 ret = 1;
993 goto out;
994 }
995
996 for (level = BTRFS_MAX_LEVEL - 1; level >= -1; level--) {
997 if (level >= 0) {
998 eb = path->nodes[level];
999 if (!eb)
1000 continue;
1001 extent_start = eb->start;
1002 } else
1003 extent_start = bytenr;
1004
1005 ret = get_reference_status(root, extent_start, ref_generation,
1006 0, &min_generation, &ref_count);
1007 if (ret)
1008 goto out; 914 goto out;
1009 915 }
1010 if (ref_count != 1) { 916 if (btrfs_ref_generation(leaf, ref_item) <= last_snapshot) {
1011 ret = 1; 917 ret = 1;
1012 goto out; 918 goto out;
1013 } 919 }
1014 if (level >= 0) 920
1015 ref_generation = btrfs_header_generation(eb); 921 path->slots[0]++;
1016 } 922 }
1017 ret = 0; 923 ret = 0;
1018out: 924out:
1019 if (path) 925 btrfs_free_path(path);
1020 btrfs_free_path(path);
1021 return ret; 926 return ret;
1022} 927}
1023 928
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e8511d14b119..3e6f0568fdb4 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -298,6 +298,7 @@ static int cow_file_range(struct inode *inode, struct page *locked_page,
298 unsigned long max_compressed = 128 * 1024; 298 unsigned long max_compressed = 128 * 1024;
299 unsigned long max_uncompressed = 256 * 1024; 299 unsigned long max_uncompressed = 256 * 1024;
300 int i; 300 int i;
301 int ordered_type;
301 int will_compress; 302 int will_compress;
302 303
303 trans = btrfs_join_transaction(root, 1); 304 trans = btrfs_join_transaction(root, 1);
@@ -491,9 +492,10 @@ again:
491 } 492 }
492 493
493 cur_alloc_size = ins.offset; 494 cur_alloc_size = ins.offset;
495 ordered_type = will_compress ? BTRFS_ORDERED_COMPRESSED : 0;
494 ret = btrfs_add_ordered_extent(inode, start, ins.objectid, 496 ret = btrfs_add_ordered_extent(inode, start, ins.objectid,
495 ram_size, cur_alloc_size, 0, 497 ram_size, cur_alloc_size,
496 will_compress); 498 ordered_type);
497 BUG_ON(ret); 499 BUG_ON(ret);
498 500
499 if (disk_num_bytes < cur_alloc_size) { 501 if (disk_num_bytes < cur_alloc_size) {
@@ -587,115 +589,148 @@ free_pages_out:
587static int run_delalloc_nocow(struct inode *inode, struct page *locked_page, 589static int run_delalloc_nocow(struct inode *inode, struct page *locked_page,
588 u64 start, u64 end, int *page_started) 590 u64 start, u64 end, int *page_started)
589{ 591{
590 u64 extent_start;
591 u64 extent_end;
592 u64 bytenr;
593 u64 loops = 0;
594 u64 total_fs_bytes;
595 struct btrfs_root *root = BTRFS_I(inode)->root; 592 struct btrfs_root *root = BTRFS_I(inode)->root;
596 struct btrfs_block_group_cache *block_group;
597 struct btrfs_trans_handle *trans; 593 struct btrfs_trans_handle *trans;
598 struct extent_buffer *leaf; 594 struct extent_buffer *leaf;
599 int found_type;
600 struct btrfs_path *path; 595 struct btrfs_path *path;
601 struct btrfs_file_extent_item *item; 596 struct btrfs_file_extent_item *fi;
602 int ret;
603 int err = 0;
604 struct btrfs_key found_key; 597 struct btrfs_key found_key;
598 u64 cow_start;
599 u64 cur_offset;
600 u64 extent_end;
601 u64 disk_bytenr;
602 u64 num_bytes;
603 int extent_type;
604 int ret;
605 int nocow;
606 int check_prev = 1;
605 607
606 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
607 path = btrfs_alloc_path(); 608 path = btrfs_alloc_path();
608 BUG_ON(!path); 609 BUG_ON(!path);
609 trans = btrfs_join_transaction(root, 1); 610 trans = btrfs_join_transaction(root, 1);
610 BUG_ON(!trans); 611 BUG_ON(!trans);
611again:
612 ret = btrfs_lookup_file_extent(NULL, root, path,
613 inode->i_ino, start, 0);
614 if (ret < 0) {
615 err = ret;
616 goto out;
617 }
618
619 if (ret != 0) {
620 if (path->slots[0] == 0)
621 goto not_found;
622 path->slots[0]--;
623 }
624
625 leaf = path->nodes[0];
626 item = btrfs_item_ptr(leaf, path->slots[0],
627 struct btrfs_file_extent_item);
628
629 /* are we inside the extent that was found? */
630 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
631 found_type = btrfs_key_type(&found_key);
632 if (found_key.objectid != inode->i_ino ||
633 found_type != BTRFS_EXTENT_DATA_KEY)
634 goto not_found;
635
636 found_type = btrfs_file_extent_type(leaf, item);
637 extent_start = found_key.offset;
638 if (found_type == BTRFS_FILE_EXTENT_REG) {
639 u64 extent_num_bytes;
640
641 extent_num_bytes = btrfs_file_extent_num_bytes(leaf, item);
642 extent_end = extent_start + extent_num_bytes;
643 err = 0;
644 612
645 if (btrfs_file_extent_compression(leaf, item) || 613 cow_start = (u64)-1;
646 btrfs_file_extent_encryption(leaf,item) || 614 cur_offset = start;
647 btrfs_file_extent_other_encoding(leaf, item)) 615 while (1) {
648 goto not_found; 616 ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino,
617 cur_offset, 0);
618 BUG_ON(ret < 0);
619 if (ret > 0 && path->slots[0] > 0 && check_prev) {
620 leaf = path->nodes[0];
621 btrfs_item_key_to_cpu(leaf, &found_key,
622 path->slots[0] - 1);
623 if (found_key.objectid == inode->i_ino &&
624 found_key.type == BTRFS_EXTENT_DATA_KEY)
625 path->slots[0]--;
626 }
627 check_prev = 0;
628next_slot:
629 leaf = path->nodes[0];
630 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
631 ret = btrfs_next_leaf(root, path);
632 if (ret < 0)
633 BUG_ON(1);
634 if (ret > 0)
635 break;
636 leaf = path->nodes[0];
637 }
649 638
650 if (loops && start != extent_start) 639 nocow = 0;
651 goto not_found; 640 disk_bytenr = 0;
641 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
652 642
653 if (start < extent_start || start >= extent_end) 643 if (found_key.objectid > inode->i_ino ||
654 goto not_found; 644 found_key.type > BTRFS_EXTENT_DATA_KEY ||
645 found_key.offset > end)
646 break;
655 647
656 bytenr = btrfs_file_extent_disk_bytenr(leaf, item); 648 if (found_key.offset > cur_offset) {
657 if (bytenr == 0) 649 extent_end = found_key.offset;
658 goto not_found; 650 goto out_check;
651 }
659 652
660 if (btrfs_cross_ref_exists(trans, root, &found_key, bytenr)) 653 fi = btrfs_item_ptr(leaf, path->slots[0],
661 goto not_found; 654 struct btrfs_file_extent_item);
662 /* 655 extent_type = btrfs_file_extent_type(leaf, fi);
663 * we may be called by the resizer, make sure we're inside
664 * the limits of the FS
665 */
666 block_group = btrfs_lookup_block_group(root->fs_info,
667 bytenr);
668 if (!block_group || block_group->ro)
669 goto not_found;
670 656
671 bytenr += btrfs_file_extent_offset(leaf, item); 657 if (extent_type == BTRFS_FILE_EXTENT_REG) {
672 extent_num_bytes = min(end + 1, extent_end) - start; 658 struct btrfs_block_group_cache *block_group;
673 ret = btrfs_add_ordered_extent(inode, start, bytenr, 659 disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
674 extent_num_bytes, 660 extent_end = found_key.offset +
675 extent_num_bytes, 1, 0); 661 btrfs_file_extent_num_bytes(leaf, fi);
676 if (ret) { 662 if (extent_end <= start) {
677 err = ret; 663 path->slots[0]++;
678 goto out; 664 goto next_slot;
665 }
666 if (btrfs_file_extent_compression(leaf, fi) ||
667 btrfs_file_extent_encryption(leaf, fi) ||
668 btrfs_file_extent_other_encoding(leaf, fi))
669 goto out_check;
670 if (disk_bytenr == 0)
671 goto out_check;
672 if (btrfs_cross_ref_exist(trans, root, disk_bytenr))
673 goto out_check;
674 block_group = btrfs_lookup_block_group(root->fs_info,
675 disk_bytenr);
676 if (!block_group || block_group->ro)
677 goto out_check;
678 disk_bytenr += btrfs_file_extent_offset(leaf, fi);
679 nocow = 1;
680 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
681 extent_end = found_key.offset +
682 btrfs_file_extent_inline_len(leaf, fi);
683 extent_end = ALIGN(extent_end, root->sectorsize);
684 } else {
685 BUG_ON(1);
686 }
687out_check:
688 if (extent_end <= start) {
689 path->slots[0]++;
690 goto next_slot;
691 }
692 if (!nocow) {
693 if (cow_start == (u64)-1)
694 cow_start = cur_offset;
695 cur_offset = extent_end;
696 if (cur_offset > end)
697 break;
698 path->slots[0]++;
699 goto next_slot;
679 } 700 }
680 701
681 btrfs_release_path(root, path); 702 btrfs_release_path(root, path);
682 start = extent_end; 703 if (cow_start != (u64)-1) {
683 if (start <= end) { 704 ret = cow_file_range(inode, locked_page, cow_start,
684 loops++; 705 found_key.offset - 1, page_started);
685 goto again; 706 BUG_ON(ret);
707 cow_start = (u64)-1;
686 } 708 }
687 } else { 709
688not_found: 710 disk_bytenr += cur_offset - found_key.offset;
689 btrfs_end_transaction(trans, root); 711 num_bytes = min(end + 1, extent_end) - cur_offset;
690 btrfs_free_path(path); 712
691 return cow_file_range(inode, locked_page, start, end, 713 ret = btrfs_add_ordered_extent(inode, cur_offset, disk_bytenr,
692 page_started); 714 num_bytes, num_bytes,
715 BTRFS_ORDERED_NOCOW);
716 cur_offset = extent_end;
717 if (cur_offset > end)
718 break;
693 } 719 }
694out: 720 btrfs_release_path(root, path);
695 WARN_ON(err); 721
696 btrfs_end_transaction(trans, root); 722 if (cur_offset <= end && cow_start == (u64)-1)
723 cow_start = cur_offset;
724 if (cow_start != (u64)-1) {
725 ret = cow_file_range(inode, locked_page, cow_start, end,
726 page_started);
727 BUG_ON(ret);
728 }
729
730 ret = btrfs_end_transaction(trans, root);
731 BUG_ON(ret);
697 btrfs_free_path(path); 732 btrfs_free_path(path);
698 return err; 733 return 0;
699} 734}
700 735
701/* 736/*
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index fd3c8b5676c1..7f915d478399 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -112,6 +112,7 @@ static noinline int create_subvol(struct btrfs_root *root,
112 btrfs_set_root_level(&root_item, 0); 112 btrfs_set_root_level(&root_item, 0);
113 btrfs_set_root_refs(&root_item, 1); 113 btrfs_set_root_refs(&root_item, 1);
114 btrfs_set_root_used(&root_item, 0); 114 btrfs_set_root_used(&root_item, 0);
115 btrfs_set_root_last_snapshot(&root_item, 0);
115 116
116 memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); 117 memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress));
117 root_item.drop_level = 0; 118 root_item.drop_level = 0;
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index b5745bb96d40..e7317c8fda29 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -165,8 +165,7 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree,
165 * inserted. 165 * inserted.
166 */ 166 */
167int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, 167int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
168 u64 start, u64 len, u64 disk_len, int nocow, 168 u64 start, u64 len, u64 disk_len, int type)
169 int compressed)
170{ 169{
171 struct btrfs_ordered_inode_tree *tree; 170 struct btrfs_ordered_inode_tree *tree;
172 struct rb_node *node; 171 struct rb_node *node;
@@ -183,10 +182,8 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
183 entry->len = len; 182 entry->len = len;
184 entry->disk_len = disk_len; 183 entry->disk_len = disk_len;
185 entry->inode = inode; 184 entry->inode = inode;
186 if (nocow) 185 if (type == BTRFS_ORDERED_NOCOW || type == BTRFS_ORDERED_COMPRESSED)
187 set_bit(BTRFS_ORDERED_NOCOW, &entry->flags); 186 set_bit(type, &entry->flags);
188 if (compressed)
189 set_bit(BTRFS_ORDERED_COMPRESSED, &entry->flags);
190 187
191 /* one ref for the tree */ 188 /* one ref for the tree */
192 atomic_set(&entry->refs, 1); 189 atomic_set(&entry->refs, 1);
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index 1ef464145d22..e6d9bc54c2b1 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -132,8 +132,7 @@ int btrfs_remove_ordered_extent(struct inode *inode,
132int btrfs_dec_test_ordered_pending(struct inode *inode, 132int btrfs_dec_test_ordered_pending(struct inode *inode,
133 u64 file_offset, u64 io_size); 133 u64 file_offset, u64 io_size);
134int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, 134int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
135 u64 start, u64 len, u64 disk_len, int nocow, 135 u64 start, u64 len, u64 disk_len, int type);
136 int compressed);
137int btrfs_add_ordered_sum(struct inode *inode, 136int btrfs_add_ordered_sum(struct inode *inode,
138 struct btrfs_ordered_extent *entry, 137 struct btrfs_ordered_extent *entry,
139 struct btrfs_ordered_sum *sum); 138 struct btrfs_ordered_sum *sum);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 968b84f17a19..e72a013d24bf 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -763,6 +763,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
763 if (ret) 763 if (ret)
764 goto fail; 764 goto fail;
765 765
766 btrfs_record_root_in_trans(root);
767 btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
766 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); 768 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
767 769
768 key.objectid = objectid; 770 key.objectid = objectid;