aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent-tree.c20
-rw-r--r--fs/btrfs/inode.c8
2 files changed, 23 insertions, 5 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 30a5094fffa7..db996f0edf0b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -731,6 +731,7 @@ u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
731 u64 found_owner; 731 u64 found_owner;
732 u64 root_objectid = root->root_key.objectid; 732 u64 root_objectid = root->root_key.objectid;
733 u32 total_count = 0; 733 u32 total_count = 0;
734 u32 extent_refs;
734 u32 cur_count; 735 u32 cur_count;
735 u32 nritems; 736 u32 nritems;
736 int ret; 737 int ret;
@@ -767,6 +768,7 @@ again:
767 } 768 }
768 769
769 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); 770 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item);
771 extent_refs = btrfs_extent_refs(l, item);
770 while (1) { 772 while (1) {
771 l = path->nodes[0]; 773 l = path->nodes[0];
772 nritems = btrfs_header_nritems(l); 774 nritems = btrfs_header_nritems(l);
@@ -800,10 +802,28 @@ again:
800 total_count = 2; 802 total_count = 2;
801 goto out; 803 goto out;
802 } 804 }
805 /*
806 * nasty. we don't count a reference held by
807 * the running transaction. This allows nodatacow
808 * to avoid cow most of the time
809 */
810 if (found_owner >= BTRFS_FIRST_FREE_OBJECTID &&
811 btrfs_ref_generation(l, ref_item) ==
812 root->fs_info->generation) {
813 extent_refs--;
814 }
803 } 815 }
804 total_count = 1; 816 total_count = 1;
805 path->slots[0]++; 817 path->slots[0]++;
806 } 818 }
819 /*
820 * if there is more than one reference against a data extent,
821 * we have to assume the other ref is another snapshot
822 */
823 if (level == -1 && extent_refs > 1) {
824 total_count = 2;
825 goto out;
826 }
807 if (cur_count == 0) { 827 if (cur_count == 0) {
808 total_count = 0; 828 total_count = 0;
809 goto out; 829 goto out;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1bf37d15b174..a492fd238c88 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -207,9 +207,8 @@ again:
207 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 207 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
208 found_type = btrfs_key_type(&found_key); 208 found_type = btrfs_key_type(&found_key);
209 if (found_key.objectid != inode->i_ino || 209 if (found_key.objectid != inode->i_ino ||
210 found_type != BTRFS_EXTENT_DATA_KEY) { 210 found_type != BTRFS_EXTENT_DATA_KEY)
211 goto not_found; 211 goto not_found;
212 }
213 212
214 found_type = btrfs_file_extent_type(leaf, item); 213 found_type = btrfs_file_extent_type(leaf, item);
215 extent_start = found_key.offset; 214 extent_start = found_key.offset;
@@ -245,7 +244,6 @@ again:
245 if (!block_group || block_group->ro) 244 if (!block_group || block_group->ro)
246 goto not_found; 245 goto not_found;
247 246
248
249 start = extent_end; 247 start = extent_end;
250 } else { 248 } else {
251 goto not_found; 249 goto not_found;
@@ -260,8 +258,8 @@ loop:
260 goto again; 258 goto again;
261 259
262not_found: 260not_found:
263 cow_file_range(inode, start, cow_end); 261 cow_file_range(inode, start, end);
264 start = cow_end + 1; 262 start = end + 1;
265 goto loop; 263 goto loop;
266} 264}
267 265