diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 0c8cc35a8b97..337221ecca27 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -368,6 +368,8 @@ int noinline btrfs_drop_extents(struct btrfs_trans_handle *trans, | |||
368 | u64 search_start = start; | 368 | u64 search_start = start; |
369 | u64 leaf_start; | 369 | u64 leaf_start; |
370 | u64 ram_bytes = 0; | 370 | u64 ram_bytes = 0; |
371 | u64 orig_parent = 0; | ||
372 | u64 disk_bytenr = 0; | ||
371 | u8 compression; | 373 | u8 compression; |
372 | u8 encryption; | 374 | u8 encryption; |
373 | u16 other_encoding = 0; | 375 | u16 other_encoding = 0; |
@@ -500,17 +502,31 @@ next_slot: | |||
500 | keep = 1; | 502 | keep = 1; |
501 | } | 503 | } |
502 | 504 | ||
503 | if (bookend && found_extent && locked_end < extent_end) { | 505 | if (bookend && found_extent) { |
504 | ret = try_lock_extent(&BTRFS_I(inode)->io_tree, | 506 | if (locked_end < extent_end) { |
505 | locked_end, extent_end - 1, GFP_NOFS); | 507 | ret = try_lock_extent(&BTRFS_I(inode)->io_tree, |
506 | if (!ret) { | 508 | locked_end, extent_end - 1, |
507 | btrfs_release_path(root, path); | 509 | GFP_NOFS); |
508 | lock_extent(&BTRFS_I(inode)->io_tree, | 510 | if (!ret) { |
509 | locked_end, extent_end - 1, GFP_NOFS); | 511 | btrfs_release_path(root, path); |
512 | lock_extent(&BTRFS_I(inode)->io_tree, | ||
513 | locked_end, extent_end - 1, | ||
514 | GFP_NOFS); | ||
515 | locked_end = extent_end; | ||
516 | continue; | ||
517 | } | ||
510 | locked_end = extent_end; | 518 | locked_end = extent_end; |
511 | continue; | ||
512 | } | 519 | } |
513 | locked_end = extent_end; | 520 | orig_parent = path->nodes[0]->start; |
521 | disk_bytenr = le64_to_cpu(old.disk_bytenr); | ||
522 | if (disk_bytenr != 0) { | ||
523 | ret = btrfs_inc_extent_ref(trans, root, | ||
524 | disk_bytenr, | ||
525 | le64_to_cpu(old.disk_num_bytes), | ||
526 | orig_parent, root->root_key.objectid, | ||
527 | trans->transid, inode->i_ino); | ||
528 | BUG_ON(ret); | ||
529 | } | ||
514 | } | 530 | } |
515 | 531 | ||
516 | if (found_inline) { | 532 | if (found_inline) { |
@@ -537,8 +553,12 @@ next_slot: | |||
537 | inode_sub_bytes(inode, old_num - | 553 | inode_sub_bytes(inode, old_num - |
538 | new_num); | 554 | new_num); |
539 | } | 555 | } |
540 | btrfs_set_file_extent_num_bytes(leaf, extent, | 556 | if (!compression && !encryption) { |
541 | new_num); | 557 | btrfs_set_file_extent_ram_bytes(leaf, |
558 | extent, new_num); | ||
559 | } | ||
560 | btrfs_set_file_extent_num_bytes(leaf, | ||
561 | extent, new_num); | ||
542 | btrfs_mark_buffer_dirty(leaf); | 562 | btrfs_mark_buffer_dirty(leaf); |
543 | } else if (key.offset < inline_limit && | 563 | } else if (key.offset < inline_limit && |
544 | (end > extent_end) && | 564 | (end > extent_end) && |
@@ -582,11 +602,11 @@ next_slot: | |||
582 | } | 602 | } |
583 | /* create bookend, splitting the extent in two */ | 603 | /* create bookend, splitting the extent in two */ |
584 | if (bookend && found_extent) { | 604 | if (bookend && found_extent) { |
585 | u64 disk_bytenr; | ||
586 | struct btrfs_key ins; | 605 | struct btrfs_key ins; |
587 | ins.objectid = inode->i_ino; | 606 | ins.objectid = inode->i_ino; |
588 | ins.offset = end; | 607 | ins.offset = end; |
589 | btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); | 608 | btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); |
609 | |||
590 | btrfs_release_path(root, path); | 610 | btrfs_release_path(root, path); |
591 | ret = btrfs_insert_empty_item(trans, root, path, &ins, | 611 | ret = btrfs_insert_empty_item(trans, root, path, &ins, |
592 | sizeof(*extent)); | 612 | sizeof(*extent)); |
@@ -623,14 +643,13 @@ next_slot: | |||
623 | 643 | ||
624 | btrfs_mark_buffer_dirty(path->nodes[0]); | 644 | btrfs_mark_buffer_dirty(path->nodes[0]); |
625 | 645 | ||
626 | disk_bytenr = le64_to_cpu(old.disk_bytenr); | ||
627 | if (disk_bytenr != 0) { | 646 | if (disk_bytenr != 0) { |
628 | ret = btrfs_inc_extent_ref(trans, root, | 647 | ret = btrfs_update_extent_ref(trans, root, |
629 | disk_bytenr, | 648 | disk_bytenr, orig_parent, |
630 | le64_to_cpu(old.disk_num_bytes), | 649 | leaf->start, |
631 | leaf->start, | ||
632 | root->root_key.objectid, | 650 | root->root_key.objectid, |
633 | trans->transid, ins.objectid); | 651 | trans->transid, ins.objectid); |
652 | |||
634 | BUG_ON(ret); | 653 | BUG_ON(ret); |
635 | } | 654 | } |
636 | btrfs_release_path(root, path); | 655 | btrfs_release_path(root, path); |