diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2cb2dd32407e..281757007ddb 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -148,6 +148,7 @@ static int run_delalloc_nocow(struct inode *inode, u64 start, u64 end) | |||
148 | u64 bytenr; | 148 | u64 bytenr; |
149 | u64 cow_end; | 149 | u64 cow_end; |
150 | u64 loops = 0; | 150 | u64 loops = 0; |
151 | u64 total_fs_bytes; | ||
151 | struct btrfs_root *root = BTRFS_I(inode)->root; | 152 | struct btrfs_root *root = BTRFS_I(inode)->root; |
152 | struct extent_buffer *leaf; | 153 | struct extent_buffer *leaf; |
153 | int found_type; | 154 | int found_type; |
@@ -157,6 +158,7 @@ static int run_delalloc_nocow(struct inode *inode, u64 start, u64 end) | |||
157 | int err; | 158 | int err; |
158 | struct btrfs_key found_key; | 159 | struct btrfs_key found_key; |
159 | 160 | ||
161 | total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); | ||
160 | path = btrfs_alloc_path(); | 162 | path = btrfs_alloc_path(); |
161 | BUG_ON(!path); | 163 | BUG_ON(!path); |
162 | again: | 164 | again: |
@@ -189,8 +191,10 @@ again: | |||
189 | found_type = btrfs_file_extent_type(leaf, item); | 191 | found_type = btrfs_file_extent_type(leaf, item); |
190 | extent_start = found_key.offset; | 192 | extent_start = found_key.offset; |
191 | if (found_type == BTRFS_FILE_EXTENT_REG) { | 193 | if (found_type == BTRFS_FILE_EXTENT_REG) { |
192 | extent_end = extent_start + | 194 | u64 extent_num_bytes; |
193 | btrfs_file_extent_num_bytes(leaf, item); | 195 | |
196 | extent_num_bytes = btrfs_file_extent_num_bytes(leaf, item); | ||
197 | extent_end = extent_start + extent_num_bytes; | ||
194 | err = 0; | 198 | err = 0; |
195 | 199 | ||
196 | if (loops && start != extent_start) | 200 | if (loops && start != extent_start) |
@@ -204,6 +208,13 @@ again: | |||
204 | if (bytenr == 0) | 208 | if (bytenr == 0) |
205 | goto not_found; | 209 | goto not_found; |
206 | 210 | ||
211 | /* | ||
212 | * we may be called by the resizer, make sure we're inside | ||
213 | * the limits of the FS | ||
214 | */ | ||
215 | if (bytenr + extent_num_bytes > total_fs_bytes) | ||
216 | goto not_found; | ||
217 | |||
207 | if (btrfs_count_snapshots_in_path(root, path, bytenr) != 1) { | 218 | if (btrfs_count_snapshots_in_path(root, path, bytenr) != 1) { |
208 | goto not_found; | 219 | goto not_found; |
209 | } | 220 | } |