aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/extent-tree.c9
-rw-r--r--fs/btrfs/inode.c13
3 files changed, 19 insertions, 5 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index f4b4677bec77..6c2c2c4e4d2a 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1325,7 +1325,7 @@ static inline struct dentry *fdentry(struct file *file) {
1325/* extent-tree.c */ 1325/* extent-tree.c */
1326u32 btrfs_count_snapshots_in_path(struct btrfs_root *root, 1326u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
1327 struct btrfs_path *count_path, 1327 struct btrfs_path *count_path,
1328 u64 first_extent); 1328 u64 expected_owner, u64 first_extent);
1329int btrfs_extent_post_op(struct btrfs_trans_handle *trans, 1329int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
1330 struct btrfs_root *root); 1330 struct btrfs_root *root);
1331int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy); 1331int 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 8e69b5acfeff..30a5094fffa7 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -721,12 +721,14 @@ out:
721 721
722u32 btrfs_count_snapshots_in_path(struct btrfs_root *root, 722u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
723 struct btrfs_path *count_path, 723 struct btrfs_path *count_path,
724 u64 expected_owner,
724 u64 first_extent) 725 u64 first_extent)
725{ 726{
726 struct btrfs_root *extent_root = root->fs_info->extent_root; 727 struct btrfs_root *extent_root = root->fs_info->extent_root;
727 struct btrfs_path *path; 728 struct btrfs_path *path;
728 u64 bytenr; 729 u64 bytenr;
729 u64 found_objectid; 730 u64 found_objectid;
731 u64 found_owner;
730 u64 root_objectid = root->root_key.objectid; 732 u64 root_objectid = root->root_key.objectid;
731 u32 total_count = 0; 733 u32 total_count = 0;
732 u32 cur_count; 734 u32 cur_count;
@@ -792,6 +794,13 @@ again:
792 total_count = 2; 794 total_count = 2;
793 goto out; 795 goto out;
794 } 796 }
797 if (level == -1) {
798 found_owner = btrfs_ref_objectid(l, ref_item);
799 if (found_owner != expected_owner) {
800 total_count = 2;
801 goto out;
802 }
803 }
795 total_count = 1; 804 total_count = 1;
796 path->slots[0]++; 805 path->slots[0]++;
797 } 806 }
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b437d3bdf95e..1bf37d15b174 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -172,6 +172,7 @@ static int run_delalloc_nocow(struct inode *inode, u64 start, u64 end)
172 u64 loops = 0; 172 u64 loops = 0;
173 u64 total_fs_bytes; 173 u64 total_fs_bytes;
174 struct btrfs_root *root = BTRFS_I(inode)->root; 174 struct btrfs_root *root = BTRFS_I(inode)->root;
175 struct btrfs_block_group_cache *block_group;
175 struct extent_buffer *leaf; 176 struct extent_buffer *leaf;
176 int found_type; 177 int found_type;
177 struct btrfs_path *path; 178 struct btrfs_path *path;
@@ -230,16 +231,20 @@ again:
230 if (bytenr == 0) 231 if (bytenr == 0)
231 goto not_found; 232 goto not_found;
232 233
234 if (btrfs_count_snapshots_in_path(root, path, inode->i_ino,
235 bytenr) != 1) {
236 goto not_found;
237 }
238
233 /* 239 /*
234 * we may be called by the resizer, make sure we're inside 240 * we may be called by the resizer, make sure we're inside
235 * the limits of the FS 241 * the limits of the FS
236 */ 242 */
237 if (bytenr + extent_num_bytes > total_fs_bytes) 243 block_group = btrfs_lookup_block_group(root->fs_info,
244 bytenr);
245 if (!block_group || block_group->ro)
238 goto not_found; 246 goto not_found;
239 247
240 if (btrfs_count_snapshots_in_path(root, path, bytenr) != 1) {
241 goto not_found;
242 }
243 248
244 start = extent_end; 249 start = extent_end;
245 } else { 250 } else {