diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-11-30 10:09:33 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | 00f5c795fca47d038fedd3f0c9311da3be710c9f (patch) | |
tree | 98e6a349ddfa115b4f0577f3c6e1e24fca2fac59 | |
parent | ca6646264b7dab662d84435441164bb2a8e8885a (diff) |
btrfs_drop_extents: make sure the item is getting smaller before truncate
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r-- | fs/btrfs/ctree.h | 2 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 8 | ||||
-rw-r--r-- | fs/btrfs/file.c | 30 |
3 files changed, 24 insertions, 16 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 56b977ffe918..b29b911dd825 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1037,7 +1037,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end); | |||
1037 | extern struct file_operations btrfs_file_operations; | 1037 | extern struct file_operations btrfs_file_operations; |
1038 | int btrfs_drop_extents(struct btrfs_trans_handle *trans, | 1038 | int btrfs_drop_extents(struct btrfs_trans_handle *trans, |
1039 | struct btrfs_root *root, struct inode *inode, | 1039 | struct btrfs_root *root, struct inode *inode, |
1040 | u64 start, u64 end, u64 inline_end, u64 *hint_block); | 1040 | u64 start, u64 end, u64 inline_limit, u64 *hint_block); |
1041 | /* tree-defrag.c */ | 1041 | /* tree-defrag.c */ |
1042 | int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | 1042 | int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, |
1043 | struct btrfs_root *root, int cache_only); | 1043 | struct btrfs_root *root, int cache_only); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 3c00f967eccb..55abdf997ca5 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -45,6 +45,9 @@ static int cache_block_group(struct btrfs_root *root, | |||
45 | u64 first_free; | 45 | u64 first_free; |
46 | int found = 0; | 46 | int found = 0; |
47 | 47 | ||
48 | if (!block_group) | ||
49 | return 0; | ||
50 | |||
48 | root = root->fs_info->extent_root; | 51 | root = root->fs_info->extent_root; |
49 | free_space_cache = &root->fs_info->free_space_cache; | 52 | free_space_cache = &root->fs_info->free_space_cache; |
50 | 53 | ||
@@ -168,6 +171,11 @@ static u64 find_search_start(struct btrfs_root *root, | |||
168 | u64 cache_miss = 0; | 171 | u64 cache_miss = 0; |
169 | int wrapped = 0; | 172 | int wrapped = 0; |
170 | 173 | ||
174 | if (!cache) { | ||
175 | cache = btrfs_lookup_block_group(root->fs_info, search_start); | ||
176 | if (!cache) | ||
177 | return search_start; | ||
178 | } | ||
171 | again: | 179 | again: |
172 | ret = cache_block_group(root, cache); | 180 | ret = cache_block_group(root, cache); |
173 | if (ret) | 181 | if (ret) |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index ba624ae16e61..b0d637787264 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -377,23 +377,23 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end) | |||
377 | */ | 377 | */ |
378 | int btrfs_drop_extents(struct btrfs_trans_handle *trans, | 378 | int btrfs_drop_extents(struct btrfs_trans_handle *trans, |
379 | struct btrfs_root *root, struct inode *inode, | 379 | struct btrfs_root *root, struct inode *inode, |
380 | u64 start, u64 end, u64 inline_end, u64 *hint_byte) | 380 | u64 start, u64 end, u64 inline_limit, u64 *hint_byte) |
381 | { | 381 | { |
382 | int ret; | 382 | u64 extent_end = 0; |
383 | struct btrfs_key key; | 383 | u64 search_start = start; |
384 | struct extent_buffer *leaf; | 384 | struct extent_buffer *leaf; |
385 | int slot; | ||
386 | struct btrfs_file_extent_item *extent; | 385 | struct btrfs_file_extent_item *extent; |
387 | u64 extent_end = 0; | ||
388 | int keep; | ||
389 | struct btrfs_file_extent_item old; | ||
390 | struct btrfs_path *path; | 386 | struct btrfs_path *path; |
391 | u64 search_start = start; | 387 | struct btrfs_key key; |
388 | struct btrfs_file_extent_item old; | ||
389 | int keep; | ||
390 | int slot; | ||
392 | int bookend; | 391 | int bookend; |
393 | int found_type; | 392 | int found_type; |
394 | int found_extent; | 393 | int found_extent; |
395 | int found_inline; | 394 | int found_inline; |
396 | int recow; | 395 | int recow; |
396 | int ret; | ||
397 | 397 | ||
398 | btrfs_drop_extent_cache(inode, start, end - 1); | 398 | btrfs_drop_extent_cache(inode, start, end - 1); |
399 | 399 | ||
@@ -502,7 +502,7 @@ next_slot: | |||
502 | } | 502 | } |
503 | bookend = 1; | 503 | bookend = 1; |
504 | if (found_inline && start <= key.offset && | 504 | if (found_inline && start <= key.offset && |
505 | inline_end < extent_end) | 505 | inline_limit < extent_end) |
506 | keep = 1; | 506 | keep = 1; |
507 | } | 507 | } |
508 | /* truncate existing extent */ | 508 | /* truncate existing extent */ |
@@ -526,12 +526,12 @@ next_slot: | |||
526 | btrfs_set_file_extent_num_bytes(leaf, extent, | 526 | btrfs_set_file_extent_num_bytes(leaf, extent, |
527 | new_num); | 527 | new_num); |
528 | btrfs_mark_buffer_dirty(leaf); | 528 | btrfs_mark_buffer_dirty(leaf); |
529 | } else if (end > extent_end && | 529 | } else if (key.offset < inline_limit && |
530 | key.offset < inline_end && | 530 | (end > extent_end) && |
531 | inline_end < extent_end) { | 531 | (inline_limit < extent_end)) { |
532 | u32 new_size; | 532 | u32 new_size; |
533 | new_size = btrfs_file_extent_calc_inline_size( | 533 | new_size = btrfs_file_extent_calc_inline_size( |
534 | inline_end - key.offset); | 534 | inline_limit - key.offset); |
535 | btrfs_truncate_item(trans, root, path, | 535 | btrfs_truncate_item(trans, root, path, |
536 | new_size, 1); | 536 | new_size, 1); |
537 | } | 537 | } |
@@ -575,10 +575,10 @@ next_slot: | |||
575 | continue; | 575 | continue; |
576 | } | 576 | } |
577 | if (bookend && found_inline && start <= key.offset && | 577 | if (bookend && found_inline && start <= key.offset && |
578 | inline_end < extent_end) { | 578 | inline_limit < extent_end && key.offset <= inline_limit) { |
579 | u32 new_size; | 579 | u32 new_size; |
580 | new_size = btrfs_file_extent_calc_inline_size( | 580 | new_size = btrfs_file_extent_calc_inline_size( |
581 | extent_end - inline_end); | 581 | extent_end - inline_limit); |
582 | btrfs_truncate_item(trans, root, path, new_size, 0); | 582 | btrfs_truncate_item(trans, root, path, new_size, 0); |
583 | } | 583 | } |
584 | /* create bookend, splitting the extent in two */ | 584 | /* create bookend, splitting the extent in two */ |