aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-01-08 15:46:31 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:59 -0400
commitc31f8830f0dfd31e7e196b85ca1b39aef8b77d57 (patch)
tree2ee8038af3d28460dd9004ab69d48d301c0a76b8 /fs/btrfs/inode.c
parentb0331a4c4c339ba7786472b137d6ece9e7f810ec (diff)
Btrfs: online shrinking fixes
While shrinking the FS, the allocation functions need to make sure they don't try to allocate bytes past the end of the FS. nodatacow needed an extra check to force cows when the existing extents are past the end of the FS. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c15
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);
162again: 164again:
@@ -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 }