diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index b8a7637e14a1..1a0510ad030c 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -364,6 +364,7 @@ int noinline btrfs_drop_extents(struct btrfs_trans_handle *trans, | |||
364 | u64 start, u64 end, u64 inline_limit, u64 *hint_byte) | 364 | u64 start, u64 end, u64 inline_limit, u64 *hint_byte) |
365 | { | 365 | { |
366 | u64 extent_end = 0; | 366 | u64 extent_end = 0; |
367 | u64 locked_end = end; | ||
367 | u64 search_start = start; | 368 | u64 search_start = start; |
368 | u64 leaf_start; | 369 | u64 leaf_start; |
369 | u64 ram_bytes = 0; | 370 | u64 ram_bytes = 0; |
@@ -479,12 +480,6 @@ next_slot: | |||
479 | goto next_slot; | 480 | goto next_slot; |
480 | } | 481 | } |
481 | 482 | ||
482 | if (found_inline) { | ||
483 | u64 mask = root->sectorsize - 1; | ||
484 | search_start = (extent_end + mask) & ~mask; | ||
485 | } else | ||
486 | search_start = extent_end; | ||
487 | |||
488 | if (end <= extent_end && start >= key.offset && found_inline) | 483 | if (end <= extent_end && start >= key.offset && found_inline) |
489 | *hint_byte = EXTENT_MAP_INLINE; | 484 | *hint_byte = EXTENT_MAP_INLINE; |
490 | 485 | ||
@@ -501,6 +496,26 @@ next_slot: | |||
501 | if (found_inline && start <= key.offset) | 496 | if (found_inline && start <= key.offset) |
502 | keep = 1; | 497 | keep = 1; |
503 | } | 498 | } |
499 | |||
500 | if (bookend && found_extent && locked_end < extent_end) { | ||
501 | ret = try_lock_extent(&BTRFS_I(inode)->io_tree, | ||
502 | locked_end, extent_end - 1, GFP_NOFS); | ||
503 | if (!ret) { | ||
504 | btrfs_release_path(root, path); | ||
505 | lock_extent(&BTRFS_I(inode)->io_tree, | ||
506 | locked_end, extent_end - 1, GFP_NOFS); | ||
507 | locked_end = extent_end; | ||
508 | continue; | ||
509 | } | ||
510 | locked_end = extent_end; | ||
511 | } | ||
512 | |||
513 | if (found_inline) { | ||
514 | u64 mask = root->sectorsize - 1; | ||
515 | search_start = (extent_end + mask) & ~mask; | ||
516 | } else | ||
517 | search_start = extent_end; | ||
518 | |||
504 | /* truncate existing extent */ | 519 | /* truncate existing extent */ |
505 | if (start > key.offset) { | 520 | if (start > key.offset) { |
506 | u64 new_num; | 521 | u64 new_num; |
@@ -638,6 +653,10 @@ next_slot: | |||
638 | } | 653 | } |
639 | out: | 654 | out: |
640 | btrfs_free_path(path); | 655 | btrfs_free_path(path); |
656 | if (locked_end > end) { | ||
657 | unlock_extent(&BTRFS_I(inode)->io_tree, end, locked_end - 1, | ||
658 | GFP_NOFS); | ||
659 | } | ||
641 | btrfs_check_file(root, inode); | 660 | btrfs_check_file(root, inode); |
642 | return ret; | 661 | return ret; |
643 | } | 662 | } |