diff options
author | David Sterba <dsterba@suse.cz> | 2011-05-05 07:13:16 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.cz> | 2011-05-06 06:34:10 -0400 |
commit | 182608c8294b5fe90d7bbd4b026c82bf0a24b736 (patch) | |
tree | 5705e84960e66caa84ac059a3528a31493e35d16 /fs/btrfs/extent-tree.c | |
parent | f2a97a9dbd86eb1ef956bdf20e05c507b32beb96 (diff) |
btrfs: remove old unused commented out code
Remove code which has been #if0-ed out for a very long time and does not
seem to be related to current codebase anymore.
Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 1661 |
1 files changed, 1 insertions, 1660 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index fba1348cb2a0..b457f195636e 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2522,126 +2522,6 @@ out: | |||
2522 | return ret; | 2522 | return ret; |
2523 | } | 2523 | } |
2524 | 2524 | ||
2525 | #if 0 | ||
2526 | int btrfs_cache_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | ||
2527 | struct extent_buffer *buf, u32 nr_extents) | ||
2528 | { | ||
2529 | struct btrfs_key key; | ||
2530 | struct btrfs_file_extent_item *fi; | ||
2531 | u64 root_gen; | ||
2532 | u32 nritems; | ||
2533 | int i; | ||
2534 | int level; | ||
2535 | int ret = 0; | ||
2536 | int shared = 0; | ||
2537 | |||
2538 | if (!root->ref_cows) | ||
2539 | return 0; | ||
2540 | |||
2541 | if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { | ||
2542 | shared = 0; | ||
2543 | root_gen = root->root_key.offset; | ||
2544 | } else { | ||
2545 | shared = 1; | ||
2546 | root_gen = trans->transid - 1; | ||
2547 | } | ||
2548 | |||
2549 | level = btrfs_header_level(buf); | ||
2550 | nritems = btrfs_header_nritems(buf); | ||
2551 | |||
2552 | if (level == 0) { | ||
2553 | struct btrfs_leaf_ref *ref; | ||
2554 | struct btrfs_extent_info *info; | ||
2555 | |||
2556 | ref = btrfs_alloc_leaf_ref(root, nr_extents); | ||
2557 | if (!ref) { | ||
2558 | ret = -ENOMEM; | ||
2559 | goto out; | ||
2560 | } | ||
2561 | |||
2562 | ref->root_gen = root_gen; | ||
2563 | ref->bytenr = buf->start; | ||
2564 | ref->owner = btrfs_header_owner(buf); | ||
2565 | ref->generation = btrfs_header_generation(buf); | ||
2566 | ref->nritems = nr_extents; | ||
2567 | info = ref->extents; | ||
2568 | |||
2569 | for (i = 0; nr_extents > 0 && i < nritems; i++) { | ||
2570 | u64 disk_bytenr; | ||
2571 | btrfs_item_key_to_cpu(buf, &key, i); | ||
2572 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | ||
2573 | continue; | ||
2574 | fi = btrfs_item_ptr(buf, i, | ||
2575 | struct btrfs_file_extent_item); | ||
2576 | if (btrfs_file_extent_type(buf, fi) == | ||
2577 | BTRFS_FILE_EXTENT_INLINE) | ||
2578 | continue; | ||
2579 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); | ||
2580 | if (disk_bytenr == 0) | ||
2581 | continue; | ||
2582 | |||
2583 | info->bytenr = disk_bytenr; | ||
2584 | info->num_bytes = | ||
2585 | btrfs_file_extent_disk_num_bytes(buf, fi); | ||
2586 | info->objectid = key.objectid; | ||
2587 | info->offset = key.offset; | ||
2588 | info++; | ||
2589 | } | ||
2590 | |||
2591 | ret = btrfs_add_leaf_ref(root, ref, shared); | ||
2592 | if (ret == -EEXIST && shared) { | ||
2593 | struct btrfs_leaf_ref *old; | ||
2594 | old = btrfs_lookup_leaf_ref(root, ref->bytenr); | ||
2595 | BUG_ON(!old); | ||
2596 | btrfs_remove_leaf_ref(root, old); | ||
2597 | btrfs_free_leaf_ref(root, old); | ||
2598 | ret = btrfs_add_leaf_ref(root, ref, shared); | ||
2599 | } | ||
2600 | WARN_ON(ret); | ||
2601 | btrfs_free_leaf_ref(root, ref); | ||
2602 | } | ||
2603 | out: | ||
2604 | return ret; | ||
2605 | } | ||
2606 | |||
2607 | /* when a block goes through cow, we update the reference counts of | ||
2608 | * everything that block points to. The internal pointers of the block | ||
2609 | * can be in just about any order, and it is likely to have clusters of | ||
2610 | * things that are close together and clusters of things that are not. | ||
2611 | * | ||
2612 | * To help reduce the seeks that come with updating all of these reference | ||
2613 | * counts, sort them by byte number before actual updates are done. | ||
2614 | * | ||
2615 | * struct refsort is used to match byte number to slot in the btree block. | ||
2616 | * we sort based on the byte number and then use the slot to actually | ||
2617 | * find the item. | ||
2618 | * | ||
2619 | * struct refsort is smaller than strcut btrfs_item and smaller than | ||
2620 | * struct btrfs_key_ptr. Since we're currently limited to the page size | ||
2621 | * for a btree block, there's no way for a kmalloc of refsorts for a | ||
2622 | * single node to be bigger than a page. | ||
2623 | */ | ||
2624 | struct refsort { | ||
2625 | u64 bytenr; | ||
2626 | u32 slot; | ||
2627 | }; | ||
2628 | |||
2629 | /* | ||
2630 | * for passing into sort() | ||
2631 | */ | ||
2632 | static int refsort_cmp(const void *a_void, const void *b_void) | ||
2633 | { | ||
2634 | const struct refsort *a = a_void; | ||
2635 | const struct refsort *b = b_void; | ||
2636 | |||
2637 | if (a->bytenr < b->bytenr) | ||
2638 | return -1; | ||
2639 | if (a->bytenr > b->bytenr) | ||
2640 | return 1; | ||
2641 | return 0; | ||
2642 | } | ||
2643 | #endif | ||
2644 | |||
2645 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | 2525 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, |
2646 | struct btrfs_root *root, | 2526 | struct btrfs_root *root, |
2647 | struct extent_buffer *buf, | 2527 | struct extent_buffer *buf, |
@@ -3223,18 +3103,6 @@ commit_trans: | |||
3223 | goto again; | 3103 | goto again; |
3224 | } | 3104 | } |
3225 | 3105 | ||
3226 | #if 0 /* I hope we never need this code again, just in case */ | ||
3227 | printk(KERN_ERR "no space left, need %llu, %llu bytes_used, " | ||
3228 | "%llu bytes_reserved, " "%llu bytes_pinned, " | ||
3229 | "%llu bytes_readonly, %llu may use %llu total\n", | ||
3230 | (unsigned long long)bytes, | ||
3231 | (unsigned long long)data_sinfo->bytes_used, | ||
3232 | (unsigned long long)data_sinfo->bytes_reserved, | ||
3233 | (unsigned long long)data_sinfo->bytes_pinned, | ||
3234 | (unsigned long long)data_sinfo->bytes_readonly, | ||
3235 | (unsigned long long)data_sinfo->bytes_may_use, | ||
3236 | (unsigned long long)data_sinfo->total_bytes); | ||
3237 | #endif | ||
3238 | return -ENOSPC; | 3106 | return -ENOSPC; |
3239 | } | 3107 | } |
3240 | data_sinfo->bytes_may_use += bytes; | 3108 | data_sinfo->bytes_may_use += bytes; |
@@ -3867,23 +3735,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info) | |||
3867 | u64 meta_used; | 3735 | u64 meta_used; |
3868 | u64 data_used; | 3736 | u64 data_used; |
3869 | int csum_size = btrfs_super_csum_size(&fs_info->super_copy); | 3737 | int csum_size = btrfs_super_csum_size(&fs_info->super_copy); |
3870 | #if 0 | ||
3871 | /* | ||
3872 | * per tree used space accounting can be inaccuracy, so we | ||
3873 | * can't rely on it. | ||
3874 | */ | ||
3875 | spin_lock(&fs_info->extent_root->accounting_lock); | ||
3876 | num_bytes = btrfs_root_used(&fs_info->extent_root->root_item); | ||
3877 | spin_unlock(&fs_info->extent_root->accounting_lock); | ||
3878 | |||
3879 | spin_lock(&fs_info->csum_root->accounting_lock); | ||
3880 | num_bytes += btrfs_root_used(&fs_info->csum_root->root_item); | ||
3881 | spin_unlock(&fs_info->csum_root->accounting_lock); | ||
3882 | 3738 | ||
3883 | spin_lock(&fs_info->tree_root->accounting_lock); | ||
3884 | num_bytes += btrfs_root_used(&fs_info->tree_root->root_item); | ||
3885 | spin_unlock(&fs_info->tree_root->accounting_lock); | ||
3886 | #endif | ||
3887 | sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA); | 3739 | sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA); |
3888 | spin_lock(&sinfo->lock); | 3740 | spin_lock(&sinfo->lock); |
3889 | data_used = sinfo->bytes_used; | 3741 | data_used = sinfo->bytes_used; |
@@ -3936,10 +3788,7 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) | |||
3936 | block_rsv->reserved = block_rsv->size; | 3788 | block_rsv->reserved = block_rsv->size; |
3937 | block_rsv->full = 1; | 3789 | block_rsv->full = 1; |
3938 | } | 3790 | } |
3939 | #if 0 | 3791 | |
3940 | printk(KERN_INFO"global block rsv size %llu reserved %llu\n", | ||
3941 | block_rsv->size, block_rsv->reserved); | ||
3942 | #endif | ||
3943 | spin_unlock(&sinfo->lock); | 3792 | spin_unlock(&sinfo->lock); |
3944 | spin_unlock(&block_rsv->lock); | 3793 | spin_unlock(&block_rsv->lock); |
3945 | } | 3794 | } |
@@ -6596,1514 +6445,6 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | |||
6596 | return ret; | 6445 | return ret; |
6597 | } | 6446 | } |
6598 | 6447 | ||
6599 | #if 0 | ||
6600 | static unsigned long calc_ra(unsigned long start, unsigned long last, | ||
6601 | unsigned long nr) | ||
6602 | { | ||
6603 | return min(last, start + nr - 1); | ||
6604 | } | ||
6605 | |||
6606 | static noinline int relocate_inode_pages(struct inode *inode, u64 start, | ||
6607 | u64 len) | ||
6608 | { | ||
6609 | u64 page_start; | ||
6610 | u64 page_end; | ||
6611 | unsigned long first_index; | ||
6612 | unsigned long last_index; | ||
6613 | unsigned long i; | ||
6614 | struct page *page; | ||
6615 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | ||
6616 | struct file_ra_state *ra; | ||
6617 | struct btrfs_ordered_extent *ordered; | ||
6618 | unsigned int total_read = 0; | ||
6619 | unsigned int total_dirty = 0; | ||
6620 | int ret = 0; | ||
6621 | |||
6622 | ra = kzalloc(sizeof(*ra), GFP_NOFS); | ||
6623 | if (!ra) | ||
6624 | return -ENOMEM; | ||
6625 | |||
6626 | mutex_lock(&inode->i_mutex); | ||
6627 | first_index = start >> PAGE_CACHE_SHIFT; | ||
6628 | last_index = (start + len - 1) >> PAGE_CACHE_SHIFT; | ||
6629 | |||
6630 | /* make sure the dirty trick played by the caller work */ | ||
6631 | ret = invalidate_inode_pages2_range(inode->i_mapping, | ||
6632 | first_index, last_index); | ||
6633 | if (ret) | ||
6634 | goto out_unlock; | ||
6635 | |||
6636 | file_ra_state_init(ra, inode->i_mapping); | ||
6637 | |||
6638 | for (i = first_index ; i <= last_index; i++) { | ||
6639 | if (total_read % ra->ra_pages == 0) { | ||
6640 | btrfs_force_ra(inode->i_mapping, ra, NULL, i, | ||
6641 | calc_ra(i, last_index, ra->ra_pages)); | ||
6642 | } | ||
6643 | total_read++; | ||
6644 | again: | ||
6645 | if (((u64)i << PAGE_CACHE_SHIFT) > i_size_read(inode)) | ||
6646 | BUG_ON(1); | ||
6647 | page = grab_cache_page(inode->i_mapping, i); | ||
6648 | if (!page) { | ||
6649 | ret = -ENOMEM; | ||
6650 | goto out_unlock; | ||
6651 | } | ||
6652 | if (!PageUptodate(page)) { | ||
6653 | btrfs_readpage(NULL, page); | ||
6654 | lock_page(page); | ||
6655 | if (!PageUptodate(page)) { | ||
6656 | unlock_page(page); | ||
6657 | page_cache_release(page); | ||
6658 | ret = -EIO; | ||
6659 | goto out_unlock; | ||
6660 | } | ||
6661 | } | ||
6662 | wait_on_page_writeback(page); | ||
6663 | |||
6664 | page_start = (u64)page->index << PAGE_CACHE_SHIFT; | ||
6665 | page_end = page_start + PAGE_CACHE_SIZE - 1; | ||
6666 | lock_extent(io_tree, page_start, page_end, GFP_NOFS); | ||
6667 | |||
6668 | ordered = btrfs_lookup_ordered_extent(inode, page_start); | ||
6669 | if (ordered) { | ||
6670 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | ||
6671 | unlock_page(page); | ||
6672 | page_cache_release(page); | ||
6673 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
6674 | btrfs_put_ordered_extent(ordered); | ||
6675 | goto again; | ||
6676 | } | ||
6677 | set_page_extent_mapped(page); | ||
6678 | |||
6679 | if (i == first_index) | ||
6680 | set_extent_bits(io_tree, page_start, page_end, | ||
6681 | EXTENT_BOUNDARY, GFP_NOFS); | ||
6682 | btrfs_set_extent_delalloc(inode, page_start, page_end); | ||
6683 | |||
6684 | set_page_dirty(page); | ||
6685 | total_dirty++; | ||
6686 | |||
6687 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | ||
6688 | unlock_page(page); | ||
6689 | page_cache_release(page); | ||
6690 | } | ||
6691 | |||
6692 | out_unlock: | ||
6693 | kfree(ra); | ||
6694 | mutex_unlock(&inode->i_mutex); | ||
6695 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, total_dirty); | ||
6696 | return ret; | ||
6697 | } | ||
6698 | |||
6699 | static noinline int relocate_data_extent(struct inode *reloc_inode, | ||
6700 | struct btrfs_key *extent_key, | ||
6701 | u64 offset) | ||
6702 | { | ||
6703 | struct btrfs_root *root = BTRFS_I(reloc_inode)->root; | ||
6704 | struct extent_map_tree *em_tree = &BTRFS_I(reloc_inode)->extent_tree; | ||
6705 | struct extent_map *em; | ||
6706 | u64 start = extent_key->objectid - offset; | ||
6707 | u64 end = start + extent_key->offset - 1; | ||
6708 | |||
6709 | em = alloc_extent_map(); | ||
6710 | BUG_ON(!em); | ||
6711 | |||
6712 | em->start = start; | ||
6713 | em->len = extent_key->offset; | ||
6714 | em->block_len = extent_key->offset; | ||
6715 | em->block_start = extent_key->objectid; | ||
6716 | em->bdev = root->fs_info->fs_devices->latest_bdev; | ||
6717 | set_bit(EXTENT_FLAG_PINNED, &em->flags); | ||
6718 | |||
6719 | /* setup extent map to cheat btrfs_readpage */ | ||
6720 | lock_extent(&BTRFS_I(reloc_inode)->io_tree, start, end, GFP_NOFS); | ||
6721 | while (1) { | ||
6722 | int ret; | ||
6723 | write_lock(&em_tree->lock); | ||
6724 | ret = add_extent_mapping(em_tree, em); | ||
6725 | write_unlock(&em_tree->lock); | ||
6726 | if (ret != -EEXIST) { | ||
6727 | free_extent_map(em); | ||
6728 | break; | ||
6729 | } | ||
6730 | btrfs_drop_extent_cache(reloc_inode, start, end, 0); | ||
6731 | } | ||
6732 | unlock_extent(&BTRFS_I(reloc_inode)->io_tree, start, end, GFP_NOFS); | ||
6733 | |||
6734 | return relocate_inode_pages(reloc_inode, start, extent_key->offset); | ||
6735 | } | ||
6736 | |||
6737 | struct btrfs_ref_path { | ||
6738 | u64 extent_start; | ||
6739 | u64 nodes[BTRFS_MAX_LEVEL]; | ||
6740 | u64 root_objectid; | ||
6741 | u64 root_generation; | ||
6742 | u64 owner_objectid; | ||
6743 | u32 num_refs; | ||
6744 | int lowest_level; | ||
6745 | int current_level; | ||
6746 | int shared_level; | ||
6747 | |||
6748 | struct btrfs_key node_keys[BTRFS_MAX_LEVEL]; | ||
6749 | u64 new_nodes[BTRFS_MAX_LEVEL]; | ||
6750 | }; | ||
6751 | |||
6752 | struct disk_extent { | ||
6753 | u64 ram_bytes; | ||
6754 | u64 disk_bytenr; | ||
6755 | u64 disk_num_bytes; | ||
6756 | u64 offset; | ||
6757 | u64 num_bytes; | ||
6758 | u8 compression; | ||
6759 | u8 encryption; | ||
6760 | u16 other_encoding; | ||
6761 | }; | ||
6762 | |||
6763 | static int is_cowonly_root(u64 root_objectid) | ||
6764 | { | ||
6765 | if (root_objectid == BTRFS_ROOT_TREE_OBJECTID || | ||
6766 | root_objectid == BTRFS_EXTENT_TREE_OBJECTID || | ||
6767 | root_objectid == BTRFS_CHUNK_TREE_OBJECTID || | ||
6768 | root_objectid == BTRFS_DEV_TREE_OBJECTID || | ||
6769 | root_objectid == BTRFS_TREE_LOG_OBJECTID || | ||
6770 | root_objectid == BTRFS_CSUM_TREE_OBJECTID) | ||
6771 | return 1; | ||
6772 | return 0; | ||
6773 | } | ||
6774 | |||
6775 | static noinline int __next_ref_path(struct btrfs_trans_handle *trans, | ||
6776 | struct btrfs_root *extent_root, | ||
6777 | struct btrfs_ref_path *ref_path, | ||
6778 | int first_time) | ||
6779 | { | ||
6780 | struct extent_buffer *leaf; | ||
6781 | struct btrfs_path *path; | ||
6782 | struct btrfs_extent_ref *ref; | ||
6783 | struct btrfs_key key; | ||
6784 | struct btrfs_key found_key; | ||
6785 | u64 bytenr; | ||
6786 | u32 nritems; | ||
6787 | int level; | ||
6788 | int ret = 1; | ||
6789 | |||
6790 | path = btrfs_alloc_path(); | ||
6791 | if (!path) | ||
6792 | return -ENOMEM; | ||
6793 | |||
6794 | if (first_time) { | ||
6795 | ref_path->lowest_level = -1; | ||
6796 | ref_path->current_level = -1; | ||
6797 | ref_path->shared_level = -1; | ||
6798 | goto walk_up; | ||
6799 | } | ||
6800 | walk_down: | ||
6801 | level = ref_path->current_level - 1; | ||
6802 | while (level >= -1) { | ||
6803 | u64 parent; | ||
6804 | if (level < ref_path->lowest_level) | ||
6805 | break; | ||
6806 | |||
6807 | if (level >= 0) | ||
6808 | bytenr = ref_path->nodes[level]; | ||
6809 | else | ||
6810 | bytenr = ref_path->extent_start; | ||
6811 | BUG_ON(bytenr == 0); | ||
6812 | |||
6813 | parent = ref_path->nodes[level + 1]; | ||
6814 | ref_path->nodes[level + 1] = 0; | ||
6815 | ref_path->current_level = level; | ||
6816 | BUG_ON(parent == 0); | ||
6817 | |||
6818 | key.objectid = bytenr; | ||
6819 | key.offset = parent + 1; | ||
6820 | key.type = BTRFS_EXTENT_REF_KEY; | ||
6821 | |||
6822 | ret = btrfs_search_slot(trans, extent_root, &key, path, 0, 0); | ||
6823 | if (ret < 0) | ||
6824 | goto out; | ||
6825 | BUG_ON(ret == 0); | ||
6826 | |||
6827 | leaf = path->nodes[0]; | ||
6828 | nritems = btrfs_header_nritems(leaf); | ||
6829 | if (path->slots[0] >= nritems) { | ||
6830 | ret = btrfs_next_leaf(extent_root, path); | ||
6831 | if (ret < 0) | ||
6832 | goto out; | ||
6833 | if (ret > 0) | ||
6834 | goto next; | ||
6835 | leaf = path->nodes[0]; | ||
6836 | } | ||
6837 | |||
6838 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | ||
6839 | if (found_key.objectid == bytenr && | ||
6840 | found_key.type == BTRFS_EXTENT_REF_KEY) { | ||
6841 | if (level < ref_path->shared_level) | ||
6842 | ref_path->shared_level = level; | ||
6843 | goto found; | ||
6844 | } | ||
6845 | next: | ||
6846 | level--; | ||
6847 | btrfs_release_path(extent_root, path); | ||
6848 | cond_resched(); | ||
6849 | } | ||
6850 | /* reached lowest level */ | ||
6851 | ret = 1; | ||
6852 | goto out; | ||
6853 | walk_up: | ||
6854 | level = ref_path->current_level; | ||
6855 | while (level < BTRFS_MAX_LEVEL - 1) { | ||
6856 | u64 ref_objectid; | ||
6857 | |||
6858 | if (level >= 0) | ||
6859 | bytenr = ref_path->nodes[level]; | ||
6860 | else | ||
6861 | bytenr = ref_path->extent_start; | ||
6862 | |||
6863 | BUG_ON(bytenr == 0); | ||
6864 | |||
6865 | key.objectid = bytenr; | ||
6866 | key.offset = 0; | ||
6867 | key.type = BTRFS_EXTENT_REF_KEY; | ||
6868 | |||
6869 | ret = btrfs_search_slot(trans, extent_root, &key, path, 0, 0); | ||
6870 | if (ret < 0) | ||
6871 | goto out; | ||
6872 | |||
6873 | leaf = path->nodes[0]; | ||
6874 | nritems = btrfs_header_nritems(leaf); | ||
6875 | if (path->slots[0] >= nritems) { | ||
6876 | ret = btrfs_next_leaf(extent_root, path); | ||
6877 | if (ret < 0) | ||
6878 | goto out; | ||
6879 | if (ret > 0) { | ||
6880 | /* the extent was freed by someone */ | ||
6881 | if (ref_path->lowest_level == level) | ||
6882 | goto out; | ||
6883 | btrfs_release_path(extent_root, path); | ||
6884 | goto walk_down; | ||
6885 | } | ||
6886 | leaf = path->nodes[0]; | ||
6887 | } | ||
6888 | |||
6889 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | ||
6890 | if (found_key.objectid != bytenr || | ||
6891 | found_key.type != BTRFS_EXTENT_REF_KEY) { | ||
6892 | /* the extent was freed by someone */ | ||
6893 | if (ref_path->lowest_level == level) { | ||
6894 | ret = 1; | ||
6895 | goto out; | ||
6896 | } | ||
6897 | btrfs_release_path(extent_root, path); | ||
6898 | goto walk_down; | ||
6899 | } | ||
6900 | found: | ||
6901 | ref = btrfs_item_ptr(leaf, path->slots[0], | ||
6902 | struct btrfs_extent_ref); | ||
6903 | ref_objectid = btrfs_ref_objectid(leaf, ref); | ||
6904 | if (ref_objectid < BTRFS_FIRST_FREE_OBJECTID) { | ||
6905 | if (first_time) { | ||
6906 | level = (int)ref_objectid; | ||
6907 | BUG_ON(level >= BTRFS_MAX_LEVEL); | ||
6908 | ref_path->lowest_level = level; | ||
6909 | ref_path->current_level = level; | ||
6910 | ref_path->nodes[level] = bytenr; | ||
6911 | } else { | ||
6912 | WARN_ON(ref_objectid != level); | ||
6913 | } | ||
6914 | } else { | ||
6915 | WARN_ON(level != -1); | ||
6916 | } | ||
6917 | first_time = 0; | ||
6918 | |||
6919 | if (ref_path->lowest_level == level) { | ||
6920 | ref_path->owner_objectid = ref_objectid; | ||
6921 | ref_path->num_refs = btrfs_ref_num_refs(leaf, ref); | ||
6922 | } | ||
6923 | |||
6924 | /* | ||
6925 | * the block is tree root or the block isn't in reference | ||
6926 | * counted tree. | ||
6927 | */ | ||
6928 | if (found_key.objectid == found_key.offset || | ||
6929 | is_cowonly_root(btrfs_ref_root(leaf, ref))) { | ||
6930 | ref_path->root_objectid = btrfs_ref_root(leaf, ref); | ||
6931 | ref_path->root_generation = | ||
6932 | btrfs_ref_generation(leaf, ref); | ||
6933 | if (level < 0) { | ||
6934 | /* special reference from the tree log */ | ||
6935 | ref_path->nodes[0] = found_key.offset; | ||
6936 | ref_path->current_level = 0; | ||
6937 | } | ||
6938 | ret = 0; | ||
6939 | goto out; | ||
6940 | } | ||
6941 | |||
6942 | level++; | ||
6943 | BUG_ON(ref_path->nodes[level] != 0); | ||
6944 | ref_path->nodes[level] = found_key.offset; | ||
6945 | ref_path->current_level = level; | ||
6946 | |||
6947 | /* | ||
6948 | * the reference was created in the running transaction, | ||
6949 | * no need to continue walking up. | ||
6950 | */ | ||
6951 | if (btrfs_ref_generation(leaf, ref) == trans->transid) { | ||
6952 | ref_path->root_objectid = btrfs_ref_root(leaf, ref); | ||
6953 | ref_path->root_generation = | ||
6954 | btrfs_ref_generation(leaf, ref); | ||
6955 | ret = 0; | ||
6956 | goto out; | ||
6957 | } | ||
6958 | |||
6959 | btrfs_release_path(extent_root, path); | ||
6960 | cond_resched(); | ||
6961 | } | ||
6962 | /* reached max tree level, but no tree root found. */ | ||
6963 | BUG(); | ||
6964 | out: | ||
6965 | btrfs_free_path(path); | ||
6966 | return ret; | ||
6967 | } | ||
6968 | |||
6969 | static int btrfs_first_ref_path(struct btrfs_trans_handle *trans, | ||
6970 | struct btrfs_root *extent_root, | ||
6971 | struct btrfs_ref_path *ref_path, | ||
6972 | u64 extent_start) | ||
6973 | { | ||
6974 | memset(ref_path, 0, sizeof(*ref_path)); | ||
6975 | ref_path->extent_start = extent_start; | ||
6976 | |||
6977 | return __next_ref_path(trans, extent_root, ref_path, 1); | ||
6978 | } | ||
6979 | |||
6980 | static int btrfs_next_ref_path(struct btrfs_trans_handle *trans, | ||
6981 | struct btrfs_root *extent_root, | ||
6982 | struct btrfs_ref_path *ref_path) | ||
6983 | { | ||
6984 | return __next_ref_path(trans, extent_root, ref_path, 0); | ||
6985 | } | ||
6986 | |||
6987 | static noinline int get_new_locations(struct inode *reloc_inode, | ||
6988 | struct btrfs_key *extent_key, | ||
6989 | u64 offset, int no_fragment, | ||
6990 | struct disk_extent **extents, | ||
6991 | int *nr_extents) | ||
6992 | { | ||
6993 | struct btrfs_root *root = BTRFS_I(reloc_inode)->root; | ||
6994 | struct btrfs_path *path; | ||
6995 | struct btrfs_file_extent_item *fi; | ||
6996 | struct extent_buffer *leaf; | ||
6997 | struct disk_extent *exts = *extents; | ||
6998 | struct btrfs_key found_key; | ||
6999 | u64 cur_pos; | ||
7000 | u64 last_byte; | ||
7001 | u32 nritems; | ||
7002 | int nr = 0; | ||
7003 | int max = *nr_extents; | ||
7004 | int ret; | ||
7005 | |||
7006 | WARN_ON(!no_fragment && *extents); | ||
7007 | if (!exts) { | ||
7008 | max = 1; | ||
7009 | exts = kmalloc(sizeof(*exts) * max, GFP_NOFS); | ||
7010 | if (!exts) | ||
7011 | return -ENOMEM; | ||
7012 | } | ||
7013 | |||
7014 | path = btrfs_alloc_path(); | ||
7015 | if (!path) { | ||
7016 | if (exts != *extents) | ||
7017 | kfree(exts); | ||
7018 | return -ENOMEM; | ||
7019 | } | ||
7020 | |||
7021 | cur_pos = extent_key->objectid - offset; | ||
7022 | last_byte = extent_key->objectid + extent_key->offset; | ||
7023 | ret = btrfs_lookup_file_extent(NULL, root, path, reloc_inode->i_ino, | ||
7024 | cur_pos, 0); | ||
7025 | if (ret < 0) | ||
7026 | goto out; | ||
7027 | if (ret > 0) { | ||
7028 | ret = -ENOENT; | ||
7029 | goto out; | ||
7030 | } | ||
7031 | |||
7032 | while (1) { | ||
7033 | leaf = path->nodes[0]; | ||
7034 | nritems = btrfs_header_nritems(leaf); | ||
7035 | if (path->slots[0] >= nritems) { | ||
7036 | ret = btrfs_next_leaf(root, path); | ||
7037 | if (ret < 0) | ||
7038 | goto out; | ||
7039 | if (ret > 0) | ||
7040 | break; | ||
7041 | leaf = path->nodes[0]; | ||
7042 | } | ||
7043 | |||
7044 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | ||
7045 | if (found_key.offset != cur_pos || | ||
7046 | found_key.type != BTRFS_EXTENT_DATA_KEY || | ||
7047 | found_key.objectid != reloc_inode->i_ino) | ||
7048 | break; | ||
7049 | |||
7050 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
7051 | struct btrfs_file_extent_item); | ||
7052 | if (btrfs_file_extent_type(leaf, fi) != | ||
7053 | BTRFS_FILE_EXTENT_REG || | ||
7054 | btrfs_file_extent_disk_bytenr(leaf, fi) == 0) | ||
7055 | break; | ||
7056 | |||
7057 | if (nr == max) { | ||
7058 | struct disk_extent *old = exts; | ||
7059 | max *= 2; | ||
7060 | exts = kzalloc(sizeof(*exts) * max, GFP_NOFS); | ||
7061 | if (!exts) { | ||
7062 | ret = -ENOMEM; | ||
7063 | goto out; | ||
7064 | } | ||
7065 | memcpy(exts, old, sizeof(*exts) * nr); | ||
7066 | if (old != *extents) | ||
7067 | kfree(old); | ||
7068 | } | ||
7069 | |||
7070 | exts[nr].disk_bytenr = | ||
7071 | btrfs_file_extent_disk_bytenr(leaf, fi); | ||
7072 | exts[nr].disk_num_bytes = | ||
7073 | btrfs_file_extent_disk_num_bytes(leaf, fi); | ||
7074 | exts[nr].offset = btrfs_file_extent_offset(leaf, fi); | ||
7075 | exts[nr].num_bytes = btrfs_file_extent_num_bytes(leaf, fi); | ||
7076 | exts[nr].ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi); | ||
7077 | exts[nr].compression = btrfs_file_extent_compression(leaf, fi); | ||
7078 | exts[nr].encryption = btrfs_file_extent_encryption(leaf, fi); | ||
7079 | exts[nr].other_encoding = btrfs_file_extent_other_encoding(leaf, | ||
7080 | fi); | ||
7081 | BUG_ON(exts[nr].offset > 0); | ||
7082 | BUG_ON(exts[nr].compression || exts[nr].encryption); | ||
7083 | BUG_ON(exts[nr].num_bytes != exts[nr].disk_num_bytes); | ||
7084 | |||
7085 | cur_pos += exts[nr].num_bytes; | ||
7086 | nr++; | ||
7087 | |||
7088 | if (cur_pos + offset >= last_byte) | ||
7089 | break; | ||
7090 | |||
7091 | if (no_fragment) { | ||
7092 | ret = 1; | ||
7093 | goto out; | ||
7094 | } | ||
7095 | path->slots[0]++; | ||
7096 | } | ||
7097 | |||
7098 | BUG_ON(cur_pos + offset > last_byte); | ||
7099 | if (cur_pos + offset < last_byte) { | ||
7100 | ret = -ENOENT; | ||
7101 | goto out; | ||
7102 | } | ||
7103 | ret = 0; | ||
7104 | out: | ||
7105 | btrfs_free_path(path); | ||
7106 | if (ret) { | ||
7107 | if (exts != *extents) | ||
7108 | kfree(exts); | ||
7109 | } else { | ||
7110 | *extents = exts; | ||
7111 | *nr_extents = nr; | ||
7112 | } | ||
7113 | return ret; | ||
7114 | } | ||
7115 | |||
7116 | static noinline int replace_one_extent(struct btrfs_trans_handle *trans, | ||
7117 | struct btrfs_root *root, | ||
7118 | struct btrfs_path *path, | ||
7119 | struct btrfs_key *extent_key, | ||
7120 | struct btrfs_key *leaf_key, | ||
7121 | struct btrfs_ref_path *ref_path, | ||
7122 | struct disk_extent *new_extents, | ||
7123 | int nr_extents) | ||
7124 | { | ||
7125 | struct extent_buffer *leaf; | ||
7126 | struct btrfs_file_extent_item *fi; | ||
7127 | struct inode *inode = NULL; | ||
7128 | struct btrfs_key key; | ||
7129 | u64 lock_start = 0; | ||
7130 | u64 lock_end = 0; | ||
7131 | u64 num_bytes; | ||
7132 | u64 ext_offset; | ||
7133 | u64 search_end = (u64)-1; | ||
7134 | u32 nritems; | ||
7135 | int nr_scaned = 0; | ||
7136 | int extent_locked = 0; | ||
7137 | int extent_type; | ||
7138 | int ret; | ||
7139 | |||
7140 | memcpy(&key, leaf_key, sizeof(key)); | ||
7141 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { | ||
7142 | if (key.objectid < ref_path->owner_objectid || | ||
7143 | (key.objectid == ref_path->owner_objectid && | ||
7144 | key.type < BTRFS_EXTENT_DATA_KEY)) { | ||
7145 | key.objectid = ref_path->owner_objectid; | ||
7146 | key.type = BTRFS_EXTENT_DATA_KEY; | ||
7147 | key.offset = 0; | ||
7148 | } | ||
7149 | } | ||
7150 | |||
7151 | while (1) { | ||
7152 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); | ||
7153 | if (ret < 0) | ||
7154 | goto out; | ||
7155 | |||
7156 | leaf = path->nodes[0]; | ||
7157 | nritems = btrfs_header_nritems(leaf); | ||
7158 | next: | ||
7159 | if (extent_locked && ret > 0) { | ||
7160 | /* | ||
7161 | * the file extent item was modified by someone | ||
7162 | * before the extent got locked. | ||
7163 | */ | ||
7164 | unlock_extent(&BTRFS_I(inode)->io_tree, lock_start, | ||
7165 | lock_end, GFP_NOFS); | ||
7166 | extent_locked = 0; | ||
7167 | } | ||
7168 | |||
7169 | if (path->slots[0] >= nritems) { | ||
7170 | if (++nr_scaned > 2) | ||
7171 | break; | ||
7172 | |||
7173 | BUG_ON(extent_locked); | ||
7174 | ret = btrfs_next_leaf(root, path); | ||
7175 | if (ret < 0) | ||
7176 | goto out; | ||
7177 | if (ret > 0) | ||
7178 | break; | ||
7179 | leaf = path->nodes[0]; | ||
7180 | nritems = btrfs_header_nritems(leaf); | ||
7181 | } | ||
7182 | |||
7183 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | ||
7184 | |||
7185 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { | ||
7186 | if ((key.objectid > ref_path->owner_objectid) || | ||
7187 | (key.objectid == ref_path->owner_objectid && | ||
7188 | key.type > BTRFS_EXTENT_DATA_KEY) || | ||
7189 | key.offset >= search_end) | ||
7190 | break; | ||
7191 | } | ||
7192 | |||
7193 | if (inode && key.objectid != inode->i_ino) { | ||
7194 | BUG_ON(extent_locked); | ||
7195 | btrfs_release_path(root, path); | ||
7196 | mutex_unlock(&inode->i_mutex); | ||
7197 | iput(inode); | ||
7198 | inode = NULL; | ||
7199 | continue; | ||
7200 | } | ||
7201 | |||
7202 | if (key.type != BTRFS_EXTENT_DATA_KEY) { | ||
7203 | path->slots[0]++; | ||
7204 | ret = 1; | ||
7205 | goto next; | ||
7206 | } | ||
7207 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
7208 | struct btrfs_file_extent_item); | ||
7209 | extent_type = btrfs_file_extent_type(leaf, fi); | ||
7210 | if ((extent_type != BTRFS_FILE_EXTENT_REG && | ||
7211 | extent_type != BTRFS_FILE_EXTENT_PREALLOC) || | ||
7212 | (btrfs_file_extent_disk_bytenr(leaf, fi) != | ||
7213 | extent_key->objectid)) { | ||
7214 | path->slots[0]++; | ||
7215 | ret = 1; | ||
7216 | goto next; | ||
7217 | } | ||
7218 | |||
7219 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); | ||
7220 | ext_offset = btrfs_file_extent_offset(leaf, fi); | ||
7221 | |||
7222 | if (search_end == (u64)-1) { | ||
7223 | search_end = key.offset - ext_offset + | ||
7224 | btrfs_file_extent_ram_bytes(leaf, fi); | ||
7225 | } | ||
7226 | |||
7227 | if (!extent_locked) { | ||
7228 | lock_start = key.offset; | ||
7229 | lock_end = lock_start + num_bytes - 1; | ||
7230 | } else { | ||
7231 | if (lock_start > key.offset || | ||
7232 | lock_end + 1 < key.offset + num_bytes) { | ||
7233 | unlock_extent(&BTRFS_I(inode)->io_tree, | ||
7234 | lock_start, lock_end, GFP_NOFS); | ||
7235 | extent_locked = 0; | ||
7236 | } | ||
7237 | } | ||
7238 | |||
7239 | if (!inode) { | ||
7240 | btrfs_release_path(root, path); | ||
7241 | |||
7242 | inode = btrfs_iget_locked(root->fs_info->sb, | ||
7243 | key.objectid, root); | ||
7244 | if (inode->i_state & I_NEW) { | ||
7245 | BTRFS_I(inode)->root = root; | ||
7246 | BTRFS_I(inode)->location.objectid = | ||
7247 | key.objectid; | ||
7248 | BTRFS_I(inode)->location.type = | ||
7249 | BTRFS_INODE_ITEM_KEY; | ||
7250 | BTRFS_I(inode)->location.offset = 0; | ||
7251 | btrfs_read_locked_inode(inode); | ||
7252 | unlock_new_inode(inode); | ||
7253 | } | ||
7254 | /* | ||
7255 | * some code call btrfs_commit_transaction while | ||
7256 | * holding the i_mutex, so we can't use mutex_lock | ||
7257 | * here. | ||
7258 | */ | ||
7259 | if (is_bad_inode(inode) || | ||
7260 | !mutex_trylock(&inode->i_mutex)) { | ||
7261 | iput(inode); | ||
7262 | inode = NULL; | ||
7263 | key.offset = (u64)-1; | ||
7264 | goto skip; | ||
7265 | } | ||
7266 | } | ||
7267 | |||
7268 | if (!extent_locked) { | ||
7269 | struct btrfs_ordered_extent *ordered; | ||
7270 | |||
7271 | btrfs_release_path(root, path); | ||
7272 | |||
7273 | lock_extent(&BTRFS_I(inode)->io_tree, lock_start, | ||
7274 | lock_end, GFP_NOFS); | ||
7275 | ordered = btrfs_lookup_first_ordered_extent(inode, | ||
7276 | lock_end); | ||
7277 | if (ordered && | ||
7278 | ordered->file_offset <= lock_end && | ||
7279 | ordered->file_offset + ordered->len > lock_start) { | ||
7280 | unlock_extent(&BTRFS_I(inode)->io_tree, | ||
7281 | lock_start, lock_end, GFP_NOFS); | ||
7282 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
7283 | btrfs_put_ordered_extent(ordered); | ||
7284 | key.offset += num_bytes; | ||
7285 | goto skip; | ||
7286 | } | ||
7287 | if (ordered) | ||
7288 | btrfs_put_ordered_extent(ordered); | ||
7289 | |||
7290 | extent_locked = 1; | ||
7291 | continue; | ||
7292 | } | ||
7293 | |||
7294 | if (nr_extents == 1) { | ||
7295 | /* update extent pointer in place */ | ||
7296 | btrfs_set_file_extent_disk_bytenr(leaf, fi, | ||
7297 | new_extents[0].disk_bytenr); | ||
7298 | btrfs_set_file_extent_disk_num_bytes(leaf, fi, | ||
7299 | new_extents[0].disk_num_bytes); | ||
7300 | btrfs_mark_buffer_dirty(leaf); | ||
7301 | |||
7302 | btrfs_drop_extent_cache(inode, key.offset, | ||
7303 | key.offset + num_bytes - 1, 0); | ||
7304 | |||
7305 | ret = btrfs_inc_extent_ref(trans, root, | ||
7306 | new_extents[0].disk_bytenr, | ||
7307 | new_extents[0].disk_num_bytes, | ||
7308 | leaf->start, | ||
7309 | root->root_key.objectid, | ||
7310 | trans->transid, | ||
7311 | key.objectid); | ||
7312 | BUG_ON(ret); | ||
7313 | |||
7314 | ret = btrfs_free_extent(trans, root, | ||
7315 | extent_key->objectid, | ||
7316 | extent_key->offset, | ||
7317 | leaf->start, | ||
7318 | btrfs_header_owner(leaf), | ||
7319 | btrfs_header_generation(leaf), | ||
7320 | key.objectid, 0); | ||
7321 | BUG_ON(ret); | ||
7322 | |||
7323 | btrfs_release_path(root, path); | ||
7324 | key.offset += num_bytes; | ||
7325 | } else { | ||
7326 | BUG_ON(1); | ||
7327 | #if 0 | ||
7328 | u64 alloc_hint; | ||
7329 | u64 extent_len; | ||
7330 | int i; | ||
7331 | /* | ||
7332 | * drop old extent pointer at first, then insert the | ||
7333 | * new pointers one bye one | ||
7334 | */ | ||
7335 | btrfs_release_path(root, path); | ||
7336 | ret = btrfs_drop_extents(trans, root, inode, key.offset, | ||
7337 | key.offset + num_bytes, | ||
7338 | key.offset, &alloc_hint); | ||
7339 | BUG_ON(ret); | ||
7340 | |||
7341 | for (i = 0; i < nr_extents; i++) { | ||
7342 | if (ext_offset >= new_extents[i].num_bytes) { | ||
7343 | ext_offset -= new_extents[i].num_bytes; | ||
7344 | continue; | ||
7345 | } | ||
7346 | extent_len = min(new_extents[i].num_bytes - | ||
7347 | ext_offset, num_bytes); | ||
7348 | |||
7349 | ret = btrfs_insert_empty_item(trans, root, | ||
7350 | path, &key, | ||
7351 | sizeof(*fi)); | ||
7352 | BUG_ON(ret); | ||
7353 | |||
7354 | leaf = path->nodes[0]; | ||
7355 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
7356 | struct btrfs_file_extent_item); | ||
7357 | btrfs_set_file_extent_generation(leaf, fi, | ||
7358 | trans->transid); | ||
7359 | btrfs_set_file_extent_type(leaf, fi, | ||
7360 | BTRFS_FILE_EXTENT_REG); | ||
7361 | btrfs_set_file_extent_disk_bytenr(leaf, fi, | ||
7362 | new_extents[i].disk_bytenr); | ||
7363 | btrfs_set_file_extent_disk_num_bytes(leaf, fi, | ||
7364 | new_extents[i].disk_num_bytes); | ||
7365 | btrfs_set_file_extent_ram_bytes(leaf, fi, | ||
7366 | new_extents[i].ram_bytes); | ||
7367 | |||
7368 | btrfs_set_file_extent_compression(leaf, fi, | ||
7369 | new_extents[i].compression); | ||
7370 | btrfs_set_file_extent_encryption(leaf, fi, | ||
7371 | new_extents[i].encryption); | ||
7372 | btrfs_set_file_extent_other_encoding(leaf, fi, | ||
7373 | new_extents[i].other_encoding); | ||
7374 | |||
7375 | btrfs_set_file_extent_num_bytes(leaf, fi, | ||
7376 | extent_len); | ||
7377 | ext_offset += new_extents[i].offset; | ||
7378 | btrfs_set_file_extent_offset(leaf, fi, | ||
7379 | ext_offset); | ||
7380 | btrfs_mark_buffer_dirty(leaf); | ||
7381 | |||
7382 | btrfs_drop_extent_cache(inode, key.offset, | ||
7383 | key.offset + extent_len - 1, 0); | ||
7384 | |||
7385 | ret = btrfs_inc_extent_ref(trans, root, | ||
7386 | new_extents[i].disk_bytenr, | ||
7387 | new_extents[i].disk_num_bytes, | ||
7388 | leaf->start, | ||
7389 | root->root_key.objectid, | ||
7390 | trans->transid, key.objectid); | ||
7391 | BUG_ON(ret); | ||
7392 | btrfs_release_path(root, path); | ||
7393 | |||
7394 | inode_add_bytes(inode, extent_len); | ||
7395 | |||
7396 | ext_offset = 0; | ||
7397 | num_bytes -= extent_len; | ||
7398 | key.offset += extent_len; | ||
7399 | |||
7400 | if (num_bytes == 0) | ||
7401 | break; | ||
7402 | } | ||
7403 | BUG_ON(i >= nr_extents); | ||
7404 | #endif | ||
7405 | } | ||
7406 | |||
7407 | if (extent_locked) { | ||
7408 | unlock_extent(&BTRFS_I(inode)->io_tree, lock_start, | ||
7409 | lock_end, GFP_NOFS); | ||
7410 | extent_locked = 0; | ||
7411 | } | ||
7412 | skip: | ||
7413 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS && | ||
7414 | key.offset >= search_end) | ||
7415 | break; | ||
7416 | |||
7417 | cond_resched(); | ||
7418 | } | ||
7419 | ret = 0; | ||
7420 | out: | ||
7421 | btrfs_release_path(root, path); | ||
7422 | if (inode) { | ||
7423 | mutex_unlock(&inode->i_mutex); | ||
7424 | if (extent_locked) { | ||
7425 | unlock_extent(&BTRFS_I(inode)->io_tree, lock_start, | ||
7426 | lock_end, GFP_NOFS); | ||
7427 | } | ||
7428 | iput(inode); | ||
7429 | } | ||
7430 | return ret; | ||
7431 | } | ||
7432 | |||
7433 | int btrfs_reloc_tree_cache_ref(struct btrfs_trans_handle *trans, | ||
7434 | struct btrfs_root *root, | ||
7435 | struct extent_buffer *buf, u64 orig_start) | ||
7436 | { | ||
7437 | int level; | ||
7438 | int ret; | ||
7439 | |||
7440 | BUG_ON(btrfs_header_generation(buf) != trans->transid); | ||
7441 | BUG_ON(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID); | ||
7442 | |||
7443 | level = btrfs_header_level(buf); | ||
7444 | if (level == 0) { | ||
7445 | struct btrfs_leaf_ref *ref; | ||
7446 | struct btrfs_leaf_ref *orig_ref; | ||
7447 | |||
7448 | orig_ref = btrfs_lookup_leaf_ref(root, orig_start); | ||
7449 | if (!orig_ref) | ||
7450 | return -ENOENT; | ||
7451 | |||
7452 | ref = btrfs_alloc_leaf_ref(root, orig_ref->nritems); | ||
7453 | if (!ref) { | ||
7454 | btrfs_free_leaf_ref(root, orig_ref); | ||
7455 | return -ENOMEM; | ||
7456 | } | ||
7457 | |||
7458 | ref->nritems = orig_ref->nritems; | ||
7459 | memcpy(ref->extents, orig_ref->extents, | ||
7460 | sizeof(ref->extents[0]) * ref->nritems); | ||
7461 | |||
7462 | btrfs_free_leaf_ref(root, orig_ref); | ||
7463 | |||
7464 | ref->root_gen = trans->transid; | ||
7465 | ref->bytenr = buf->start; | ||
7466 | ref->owner = btrfs_header_owner(buf); | ||
7467 | ref->generation = btrfs_header_generation(buf); | ||
7468 | |||
7469 | ret = btrfs_add_leaf_ref(root, ref, 0); | ||
7470 | WARN_ON(ret); | ||
7471 | btrfs_free_leaf_ref(root, ref); | ||
7472 | } | ||
7473 | return 0; | ||
7474 | } | ||
7475 | |||
7476 | static noinline int invalidate_extent_cache(struct btrfs_root *root, | ||
7477 | struct extent_buffer *leaf, | ||
7478 | struct btrfs_block_group_cache *group, | ||
7479 | struct btrfs_root *target_root) | ||
7480 | { | ||
7481 | struct btrfs_key key; | ||
7482 | struct inode *inode = NULL; | ||
7483 | struct btrfs_file_extent_item *fi; | ||
7484 | struct extent_state *cached_state = NULL; | ||
7485 | u64 num_bytes; | ||
7486 | u64 skip_objectid = 0; | ||
7487 | u32 nritems; | ||
7488 | u32 i; | ||
7489 | |||
7490 | nritems = btrfs_header_nritems(leaf); | ||
7491 | for (i = 0; i < nritems; i++) { | ||
7492 | btrfs_item_key_to_cpu(leaf, &key, i); | ||
7493 | if (key.objectid == skip_objectid || | ||
7494 | key.type != BTRFS_EXTENT_DATA_KEY) | ||
7495 | continue; | ||
7496 | fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); | ||
7497 | if (btrfs_file_extent_type(leaf, fi) == | ||
7498 | BTRFS_FILE_EXTENT_INLINE) | ||
7499 | continue; | ||
7500 | if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0) | ||
7501 | continue; | ||
7502 | if (!inode || inode->i_ino != key.objectid) { | ||
7503 | iput(inode); | ||
7504 | inode = btrfs_ilookup(target_root->fs_info->sb, | ||
7505 | key.objectid, target_root, 1); | ||
7506 | } | ||
7507 | if (!inode) { | ||
7508 | skip_objectid = key.objectid; | ||
7509 | continue; | ||
7510 | } | ||
7511 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); | ||
7512 | |||
7513 | lock_extent_bits(&BTRFS_I(inode)->io_tree, key.offset, | ||
7514 | key.offset + num_bytes - 1, 0, &cached_state, | ||
7515 | GFP_NOFS); | ||
7516 | btrfs_drop_extent_cache(inode, key.offset, | ||
7517 | key.offset + num_bytes - 1, 1); | ||
7518 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, key.offset, | ||
7519 | key.offset + num_bytes - 1, &cached_state, | ||
7520 | GFP_NOFS); | ||
7521 | cond_resched(); | ||
7522 | } | ||
7523 | iput(inode); | ||
7524 | return 0; | ||
7525 | } | ||
7526 | |||
7527 | static noinline int replace_extents_in_leaf(struct btrfs_trans_handle *trans, | ||
7528 | struct btrfs_root *root, | ||
7529 | struct extent_buffer *leaf, | ||
7530 | struct btrfs_block_group_cache *group, | ||
7531 | struct inode *reloc_inode) | ||
7532 | { | ||
7533 | struct btrfs_key key; | ||
7534 | struct btrfs_key extent_key; | ||
7535 | struct btrfs_file_extent_item *fi; | ||
7536 | struct btrfs_leaf_ref *ref; | ||
7537 | struct disk_extent *new_extent; | ||
7538 | u64 bytenr; | ||
7539 | u64 num_bytes; | ||
7540 | u32 nritems; | ||
7541 | u32 i; | ||
7542 | int ext_index; | ||
7543 | int nr_extent; | ||
7544 | int ret; | ||
7545 | |||
7546 | new_extent = kmalloc(sizeof(*new_extent), GFP_NOFS); | ||
7547 | if (!new_extent) | ||
7548 | return -ENOMEM; | ||
7549 | |||
7550 | ref = btrfs_lookup_leaf_ref(root, leaf->start); | ||
7551 | BUG_ON(!ref); | ||
7552 | |||
7553 | ext_index = -1; | ||
7554 | nritems = btrfs_header_nritems(leaf); | ||
7555 | for (i = 0; i < nritems; i++) { | ||
7556 | btrfs_item_key_to_cpu(leaf, &key, i); | ||
7557 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | ||
7558 | continue; | ||
7559 | fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); | ||
7560 | if (btrfs_file_extent_type(leaf, fi) == | ||
7561 | BTRFS_FILE_EXTENT_INLINE) | ||
7562 | continue; | ||
7563 | bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); | ||
7564 | num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); | ||
7565 | if (bytenr == 0) | ||
7566 | continue; | ||
7567 | |||
7568 | ext_index++; | ||
7569 | if (bytenr >= group->key.objectid + group->key.offset || | ||
7570 | bytenr + num_bytes <= group->key.objectid) | ||
7571 | continue; | ||
7572 | |||
7573 | extent_key.objectid = bytenr; | ||
7574 | extent_key.offset = num_bytes; | ||
7575 | extent_key.type = BTRFS_EXTENT_ITEM_KEY; | ||
7576 | nr_extent = 1; | ||
7577 | ret = get_new_locations(reloc_inode, &extent_key, | ||
7578 | group->key.objectid, 1, | ||
7579 | &new_extent, &nr_extent); | ||
7580 | if (ret > 0) | ||
7581 | continue; | ||
7582 | BUG_ON(ret < 0); | ||
7583 | |||
7584 | BUG_ON(ref->extents[ext_index].bytenr != bytenr); | ||
7585 | BUG_ON(ref->extents[ext_index].num_bytes != num_bytes); | ||
7586 | ref->extents[ext_index].bytenr = new_extent->disk_bytenr; | ||
7587 | ref->extents[ext_index].num_bytes = new_extent->disk_num_bytes; | ||
7588 | |||
7589 | btrfs_set_file_extent_disk_bytenr(leaf, fi, | ||
7590 | new_extent->disk_bytenr); | ||
7591 | btrfs_set_file_extent_disk_num_bytes(leaf, fi, | ||
7592 | new_extent->disk_num_bytes); | ||
7593 | btrfs_mark_buffer_dirty(leaf); | ||
7594 | |||
7595 | ret = btrfs_inc_extent_ref(trans, root, | ||
7596 | new_extent->disk_bytenr, | ||
7597 | new_extent->disk_num_bytes, | ||
7598 | leaf->start, | ||
7599 | root->root_key.objectid, | ||
7600 | trans->transid, key.objectid); | ||
7601 | BUG_ON(ret); | ||
7602 | |||
7603 | ret = btrfs_free_extent(trans, root, | ||
7604 | bytenr, num_bytes, leaf->start, | ||
7605 | btrfs_header_owner(leaf), | ||
7606 | btrfs_header_generation(leaf), | ||
7607 | key.objectid, 0); | ||
7608 | BUG_ON(ret); | ||
7609 | cond_resched(); | ||
7610 | } | ||
7611 | kfree(new_extent); | ||
7612 | BUG_ON(ext_index + 1 != ref->nritems); | ||
7613 | btrfs_free_leaf_ref(root, ref); | ||
7614 | return 0; | ||
7615 | } | ||
7616 | |||
7617 | int btrfs_free_reloc_root(struct btrfs_trans_handle *trans, | ||
7618 | struct btrfs_root *root) | ||
7619 | { | ||
7620 | struct btrfs_root *reloc_root; | ||
7621 | int ret; | ||
7622 | |||
7623 | if (root->reloc_root) { | ||
7624 | reloc_root = root->reloc_root; | ||
7625 | root->reloc_root = NULL; | ||
7626 | list_add(&reloc_root->dead_list, | ||
7627 | &root->fs_info->dead_reloc_roots); | ||
7628 | |||
7629 | btrfs_set_root_bytenr(&reloc_root->root_item, | ||
7630 | reloc_root->node->start); | ||
7631 | btrfs_set_root_level(&root->root_item, | ||
7632 | btrfs_header_level(reloc_root->node)); | ||
7633 | memset(&reloc_root->root_item.drop_progress, 0, | ||
7634 | sizeof(struct btrfs_disk_key)); | ||
7635 | reloc_root->root_item.drop_level = 0; | ||
7636 | |||
7637 | ret = btrfs_update_root(trans, root->fs_info->tree_root, | ||
7638 | &reloc_root->root_key, | ||
7639 | &reloc_root->root_item); | ||
7640 | BUG_ON(ret); | ||
7641 | } | ||
7642 | return 0; | ||
7643 | } | ||
7644 | |||
7645 | int btrfs_drop_dead_reloc_roots(struct btrfs_root *root) | ||
7646 | { | ||
7647 | struct btrfs_trans_handle *trans; | ||
7648 | struct btrfs_root *reloc_root; | ||
7649 | struct btrfs_root *prev_root = NULL; | ||
7650 | struct list_head dead_roots; | ||
7651 | int ret; | ||
7652 | unsigned long nr; | ||
7653 | |||
7654 | INIT_LIST_HEAD(&dead_roots); | ||
7655 | list_splice_init(&root->fs_info->dead_reloc_roots, &dead_roots); | ||
7656 | |||
7657 | while (!list_empty(&dead_roots)) { | ||
7658 | reloc_root = list_entry(dead_roots.prev, | ||
7659 | struct btrfs_root, dead_list); | ||
7660 | list_del_init(&reloc_root->dead_list); | ||
7661 | |||
7662 | BUG_ON(reloc_root->commit_root != NULL); | ||
7663 | while (1) { | ||
7664 | trans = btrfs_join_transaction(root, 1); | ||
7665 | BUG_ON(IS_ERR(trans)); | ||
7666 | |||
7667 | mutex_lock(&root->fs_info->drop_mutex); | ||
7668 | ret = btrfs_drop_snapshot(trans, reloc_root); | ||
7669 | if (ret != -EAGAIN) | ||
7670 | break; | ||
7671 | mutex_unlock(&root->fs_info->drop_mutex); | ||
7672 | |||
7673 | nr = trans->blocks_used; | ||
7674 | ret = btrfs_end_transaction(trans, root); | ||
7675 | BUG_ON(ret); | ||
7676 | btrfs_btree_balance_dirty(root, nr); | ||
7677 | } | ||
7678 | |||
7679 | free_extent_buffer(reloc_root->node); | ||
7680 | |||
7681 | ret = btrfs_del_root(trans, root->fs_info->tree_root, | ||
7682 | &reloc_root->root_key); | ||
7683 | BUG_ON(ret); | ||
7684 | mutex_unlock(&root->fs_info->drop_mutex); | ||
7685 | |||
7686 | nr = trans->blocks_used; | ||
7687 | ret = btrfs_end_transaction(trans, root); | ||
7688 | BUG_ON(ret); | ||
7689 | btrfs_btree_balance_dirty(root, nr); | ||
7690 | |||
7691 | kfree(prev_root); | ||
7692 | prev_root = reloc_root; | ||
7693 | } | ||
7694 | if (prev_root) { | ||
7695 | btrfs_remove_leaf_refs(prev_root, (u64)-1, 0); | ||
7696 | kfree(prev_root); | ||
7697 | } | ||
7698 | return 0; | ||
7699 | } | ||
7700 | |||
7701 | int btrfs_add_dead_reloc_root(struct btrfs_root *root) | ||
7702 | { | ||
7703 | list_add(&root->dead_list, &root->fs_info->dead_reloc_roots); | ||
7704 | return 0; | ||
7705 | } | ||
7706 | |||
7707 | int btrfs_cleanup_reloc_trees(struct btrfs_root *root) | ||
7708 | { | ||
7709 | struct btrfs_root *reloc_root; | ||
7710 | struct btrfs_trans_handle *trans; | ||
7711 | struct btrfs_key location; | ||
7712 | int found; | ||
7713 | int ret; | ||
7714 | |||
7715 | mutex_lock(&root->fs_info->tree_reloc_mutex); | ||
7716 | ret = btrfs_find_dead_roots(root, BTRFS_TREE_RELOC_OBJECTID, NULL); | ||
7717 | BUG_ON(ret); | ||
7718 | found = !list_empty(&root->fs_info->dead_reloc_roots); | ||
7719 | mutex_unlock(&root->fs_info->tree_reloc_mutex); | ||
7720 | |||
7721 | if (found) { | ||
7722 | trans = btrfs_start_transaction(root, 1); | ||
7723 | BUG_ON(IS_ERR(trans)); | ||
7724 | ret = btrfs_commit_transaction(trans, root); | ||
7725 | BUG_ON(ret); | ||
7726 | } | ||
7727 | |||
7728 | location.objectid = BTRFS_DATA_RELOC_TREE_OBJECTID; | ||
7729 | location.offset = (u64)-1; | ||
7730 | location.type = BTRFS_ROOT_ITEM_KEY; | ||
7731 | |||
7732 | reloc_root = btrfs_read_fs_root_no_name(root->fs_info, &location); | ||
7733 | BUG_ON(!reloc_root); | ||
7734 | ret = btrfs_orphan_cleanup(reloc_root); | ||
7735 | BUG_ON(ret); | ||
7736 | return 0; | ||
7737 | } | ||
7738 | |||
7739 | static noinline int init_reloc_tree(struct btrfs_trans_handle *trans, | ||
7740 | struct btrfs_root *root) | ||
7741 | { | ||
7742 | struct btrfs_root *reloc_root; | ||
7743 | struct extent_buffer *eb; | ||
7744 | struct btrfs_root_item *root_item; | ||
7745 | struct btrfs_key root_key; | ||
7746 | int ret; | ||
7747 | |||
7748 | BUG_ON(!root->ref_cows); | ||
7749 | if (root->reloc_root) | ||
7750 | return 0; | ||
7751 | |||
7752 | root_item = kmalloc(sizeof(*root_item), GFP_NOFS); | ||
7753 | if (!root_item) | ||
7754 | return -ENOMEM; | ||
7755 | |||
7756 | ret = btrfs_copy_root(trans, root, root->commit_root, | ||
7757 | &eb, BTRFS_TREE_RELOC_OBJECTID); | ||
7758 | BUG_ON(ret); | ||
7759 | |||
7760 | root_key.objectid = BTRFS_TREE_RELOC_OBJECTID; | ||
7761 | root_key.offset = root->root_key.objectid; | ||
7762 | root_key.type = BTRFS_ROOT_ITEM_KEY; | ||
7763 | |||
7764 | memcpy(root_item, &root->root_item, sizeof(root_item)); | ||
7765 | btrfs_set_root_refs(root_item, 0); | ||
7766 | btrfs_set_root_bytenr(root_item, eb->start); | ||
7767 | btrfs_set_root_level(root_item, btrfs_header_level(eb)); | ||
7768 | btrfs_set_root_generation(root_item, trans->transid); | ||
7769 | |||
7770 | btrfs_tree_unlock(eb); | ||
7771 | free_extent_buffer(eb); | ||
7772 | |||
7773 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, | ||
7774 | &root_key, root_item); | ||
7775 | BUG_ON(ret); | ||
7776 | kfree(root_item); | ||
7777 | |||
7778 | reloc_root = btrfs_read_fs_root_no_radix(root->fs_info->tree_root, | ||
7779 | &root_key); | ||
7780 | BUG_ON(IS_ERR(reloc_root)); | ||
7781 | reloc_root->last_trans = trans->transid; | ||
7782 | reloc_root->commit_root = NULL; | ||
7783 | reloc_root->ref_tree = &root->fs_info->reloc_ref_tree; | ||
7784 | |||
7785 | root->reloc_root = reloc_root; | ||
7786 | return 0; | ||
7787 | } | ||
7788 | |||
7789 | /* | ||
7790 | * Core function of space balance. | ||
7791 | * | ||
7792 | * The idea is using reloc trees to relocate tree blocks in reference | ||
7793 | * counted roots. There is one reloc tree for each subvol, and all | ||
7794 | * reloc trees share same root key objectid. Reloc trees are snapshots | ||
7795 | * of the latest committed roots of subvols (root->commit_root). | ||
7796 | * | ||
7797 | * To relocate a tree block referenced by a subvol, there are two steps. | ||
7798 | * COW the block through subvol's reloc tree, then update block pointer | ||
7799 | * in the subvol to point to the new block. Since all reloc trees share | ||
7800 | * same root key objectid, doing special handing for tree blocks owned | ||
7801 | * by them is easy. Once a tree block has been COWed in one reloc tree, | ||
7802 | * we can use the resulting new block directly when the same block is | ||
7803 | * required to COW again through other reloc trees. By this way, relocated | ||
7804 | * tree blocks are shared between reloc trees, so they are also shared | ||
7805 | * between subvols. | ||
7806 | */ | ||
7807 | static noinline int relocate_one_path(struct btrfs_trans_handle *trans, | ||
7808 | struct btrfs_root *root, | ||
7809 | struct btrfs_path *path, | ||
7810 | struct btrfs_key *first_key, | ||
7811 | struct btrfs_ref_path *ref_path, | ||
7812 | struct btrfs_block_group_cache *group, | ||
7813 | struct inode *reloc_inode) | ||
7814 | { | ||
7815 | struct btrfs_root *reloc_root; | ||
7816 | struct extent_buffer *eb = NULL; | ||
7817 | struct btrfs_key *keys; | ||
7818 | u64 *nodes; | ||
7819 | int level; | ||
7820 | int shared_level; | ||
7821 | int lowest_level = 0; | ||
7822 | int ret; | ||
7823 | |||
7824 | if (ref_path->owner_objectid < BTRFS_FIRST_FREE_OBJECTID) | ||
7825 | lowest_level = ref_path->owner_objectid; | ||
7826 | |||
7827 | if (!root->ref_cows) { | ||
7828 | path->lowest_level = lowest_level; | ||
7829 | ret = btrfs_search_slot(trans, root, first_key, path, 0, 1); | ||
7830 | BUG_ON(ret < 0); | ||
7831 | path->lowest_level = 0; | ||
7832 | btrfs_release_path(root, path); | ||
7833 | return 0; | ||
7834 | } | ||
7835 | |||
7836 | mutex_lock(&root->fs_info->tree_reloc_mutex); | ||
7837 | ret = init_reloc_tree(trans, root); | ||
7838 | BUG_ON(ret); | ||
7839 | reloc_root = root->reloc_root; | ||
7840 | |||
7841 | shared_level = ref_path->shared_level; | ||
7842 | ref_path->shared_level = BTRFS_MAX_LEVEL - 1; | ||
7843 | |||
7844 | keys = ref_path->node_keys; | ||
7845 | nodes = ref_path->new_nodes; | ||
7846 | memset(&keys[shared_level + 1], 0, | ||
7847 | sizeof(*keys) * (BTRFS_MAX_LEVEL - shared_level - 1)); | ||
7848 | memset(&nodes[shared_level + 1], 0, | ||
7849 | sizeof(*nodes) * (BTRFS_MAX_LEVEL - shared_level - 1)); | ||
7850 | |||
7851 | if (nodes[lowest_level] == 0) { | ||
7852 | path->lowest_level = lowest_level; | ||
7853 | ret = btrfs_search_slot(trans, reloc_root, first_key, path, | ||
7854 | 0, 1); | ||
7855 | BUG_ON(ret); | ||
7856 | for (level = lowest_level; level < BTRFS_MAX_LEVEL; level++) { | ||
7857 | eb = path->nodes[level]; | ||
7858 | if (!eb || eb == reloc_root->node) | ||
7859 | break; | ||
7860 | nodes[level] = eb->start; | ||
7861 | if (level == 0) | ||
7862 | btrfs_item_key_to_cpu(eb, &keys[level], 0); | ||
7863 | else | ||
7864 | btrfs_node_key_to_cpu(eb, &keys[level], 0); | ||
7865 | } | ||
7866 | if (nodes[0] && | ||
7867 | ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { | ||
7868 | eb = path->nodes[0]; | ||
7869 | ret = replace_extents_in_leaf(trans, reloc_root, eb, | ||
7870 | group, reloc_inode); | ||
7871 | BUG_ON(ret); | ||
7872 | } | ||
7873 | btrfs_release_path(reloc_root, path); | ||
7874 | } else { | ||
7875 | ret = btrfs_merge_path(trans, reloc_root, keys, nodes, | ||
7876 | lowest_level); | ||
7877 | BUG_ON(ret); | ||
7878 | } | ||
7879 | |||
7880 | /* | ||
7881 | * replace tree blocks in the fs tree with tree blocks in | ||
7882 | * the reloc tree. | ||
7883 | */ | ||
7884 | ret = btrfs_merge_path(trans, root, keys, nodes, lowest_level); | ||
7885 | BUG_ON(ret < 0); | ||
7886 | |||
7887 | if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { | ||
7888 | ret = btrfs_search_slot(trans, reloc_root, first_key, path, | ||
7889 | 0, 0); | ||
7890 | BUG_ON(ret); | ||
7891 | extent_buffer_get(path->nodes[0]); | ||
7892 | eb = path->nodes[0]; | ||
7893 | btrfs_release_path(reloc_root, path); | ||
7894 | ret = invalidate_extent_cache(reloc_root, eb, group, root); | ||
7895 | BUG_ON(ret); | ||
7896 | free_extent_buffer(eb); | ||
7897 | } | ||
7898 | |||
7899 | mutex_unlock(&root->fs_info->tree_reloc_mutex); | ||
7900 | path->lowest_level = 0; | ||
7901 | return 0; | ||
7902 | } | ||
7903 | |||
7904 | static noinline int relocate_tree_block(struct btrfs_trans_handle *trans, | ||
7905 | struct btrfs_root *root, | ||
7906 | struct btrfs_path *path, | ||
7907 | struct btrfs_key *first_key, | ||
7908 | struct btrfs_ref_path *ref_path) | ||
7909 | { | ||
7910 | int ret; | ||
7911 | |||
7912 | ret = relocate_one_path(trans, root, path, first_key, | ||
7913 | ref_path, NULL, NULL); | ||
7914 | BUG_ON(ret); | ||
7915 | |||
7916 | return 0; | ||
7917 | } | ||
7918 | |||
7919 | static noinline int del_extent_zero(struct btrfs_trans_handle *trans, | ||
7920 | struct btrfs_root *extent_root, | ||
7921 | struct btrfs_path *path, | ||
7922 | struct btrfs_key *extent_key) | ||
7923 | { | ||
7924 | int ret; | ||
7925 | |||
7926 | ret = btrfs_search_slot(trans, extent_root, extent_key, path, -1, 1); | ||
7927 | if (ret) | ||
7928 | goto out; | ||
7929 | ret = btrfs_del_item(trans, extent_root, path); | ||
7930 | out: | ||
7931 | btrfs_release_path(extent_root, path); | ||
7932 | return ret; | ||
7933 | } | ||
7934 | |||
7935 | static noinline struct btrfs_root *read_ref_root(struct btrfs_fs_info *fs_info, | ||
7936 | struct btrfs_ref_path *ref_path) | ||
7937 | { | ||
7938 | struct btrfs_key root_key; | ||
7939 | |||
7940 | root_key.objectid = ref_path->root_objectid; | ||
7941 | root_key.type = BTRFS_ROOT_ITEM_KEY; | ||
7942 | if (is_cowonly_root(ref_path->root_objectid)) | ||
7943 | root_key.offset = 0; | ||
7944 | else | ||
7945 | root_key.offset = (u64)-1; | ||
7946 | |||
7947 | return btrfs_read_fs_root_no_name(fs_info, &root_key); | ||
7948 | } | ||
7949 | |||
7950 | static noinline int relocate_one_extent(struct btrfs_root *extent_root, | ||
7951 | struct btrfs_path *path, | ||
7952 | struct btrfs_key *extent_key, | ||
7953 | struct btrfs_block_group_cache *group, | ||
7954 | struct inode *reloc_inode, int pass) | ||
7955 | { | ||
7956 | struct btrfs_trans_handle *trans; | ||
7957 | struct btrfs_root *found_root; | ||
7958 | struct btrfs_ref_path *ref_path = NULL; | ||
7959 | struct disk_extent *new_extents = NULL; | ||
7960 | int nr_extents = 0; | ||
7961 | int loops; | ||
7962 | int ret; | ||
7963 | int level; | ||
7964 | struct btrfs_key first_key; | ||
7965 | u64 prev_block = 0; | ||
7966 | |||
7967 | |||
7968 | trans = btrfs_start_transaction(extent_root, 1); | ||
7969 | BUG_ON(IS_ERR(trans)); | ||
7970 | |||
7971 | if (extent_key->objectid == 0) { | ||
7972 | ret = del_extent_zero(trans, extent_root, path, extent_key); | ||
7973 | goto out; | ||
7974 | } | ||
7975 | |||
7976 | ref_path = kmalloc(sizeof(*ref_path), GFP_NOFS); | ||
7977 | if (!ref_path) { | ||
7978 | ret = -ENOMEM; | ||
7979 | goto out; | ||
7980 | } | ||
7981 | |||
7982 | for (loops = 0; ; loops++) { | ||
7983 | if (loops == 0) { | ||
7984 | ret = btrfs_first_ref_path(trans, extent_root, ref_path, | ||
7985 | extent_key->objectid); | ||
7986 | } else { | ||
7987 | ret = btrfs_next_ref_path(trans, extent_root, ref_path); | ||
7988 | } | ||
7989 | if (ret < 0) | ||
7990 | goto out; | ||
7991 | if (ret > 0) | ||
7992 | break; | ||
7993 | |||
7994 | if (ref_path->root_objectid == BTRFS_TREE_LOG_OBJECTID || | ||
7995 | ref_path->root_objectid == BTRFS_TREE_RELOC_OBJECTID) | ||
7996 | continue; | ||
7997 | |||
7998 | found_root = read_ref_root(extent_root->fs_info, ref_path); | ||
7999 | BUG_ON(!found_root); | ||
8000 | /* | ||
8001 | * for reference counted tree, only process reference paths | ||
8002 | * rooted at the latest committed root. | ||
8003 | */ | ||
8004 | if (found_root->ref_cows && | ||
8005 | ref_path->root_generation != found_root->root_key.offset) | ||
8006 | continue; | ||
8007 | |||
8008 | if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { | ||
8009 | if (pass == 0) { | ||
8010 | /* | ||
8011 | * copy data extents to new locations | ||
8012 | */ | ||
8013 | u64 group_start = group->key.objectid; | ||
8014 | ret = relocate_data_extent(reloc_inode, | ||
8015 | extent_key, | ||
8016 | group_start); | ||
8017 | if (ret < 0) | ||
8018 | goto out; | ||
8019 | break; | ||
8020 | } | ||
8021 | level = 0; | ||
8022 | } else { | ||
8023 | level = ref_path->owner_objectid; | ||
8024 | } | ||
8025 | |||
8026 | if (prev_block != ref_path->nodes[level]) { | ||
8027 | struct extent_buffer *eb; | ||
8028 | u64 block_start = ref_path->nodes[level]; | ||
8029 | u64 block_size = btrfs_level_size(found_root, level); | ||
8030 | |||
8031 | eb = read_tree_block(found_root, block_start, | ||
8032 | block_size, 0); | ||
8033 | if (!eb) { | ||
8034 | ret = -EIO; | ||
8035 | goto out; | ||
8036 | } | ||
8037 | btrfs_tree_lock(eb); | ||
8038 | BUG_ON(level != btrfs_header_level(eb)); | ||
8039 | |||
8040 | if (level == 0) | ||
8041 | btrfs_item_key_to_cpu(eb, &first_key, 0); | ||
8042 | else | ||
8043 | btrfs_node_key_to_cpu(eb, &first_key, 0); | ||
8044 | |||
8045 | btrfs_tree_unlock(eb); | ||
8046 | free_extent_buffer(eb); | ||
8047 | prev_block = block_start; | ||
8048 | } | ||
8049 | |||
8050 | mutex_lock(&extent_root->fs_info->trans_mutex); | ||
8051 | btrfs_record_root_in_trans(found_root); | ||
8052 | mutex_unlock(&extent_root->fs_info->trans_mutex); | ||
8053 | if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { | ||
8054 | /* | ||
8055 | * try to update data extent references while | ||
8056 | * keeping metadata shared between snapshots. | ||
8057 | */ | ||
8058 | if (pass == 1) { | ||
8059 | ret = relocate_one_path(trans, found_root, | ||
8060 | path, &first_key, ref_path, | ||
8061 | group, reloc_inode); | ||
8062 | if (ret < 0) | ||
8063 | goto out; | ||
8064 | continue; | ||
8065 | } | ||
8066 | /* | ||
8067 | * use fallback method to process the remaining | ||
8068 | * references. | ||
8069 | */ | ||
8070 | if (!new_extents) { | ||
8071 | u64 group_start = group->key.objectid; | ||
8072 | new_extents = kmalloc(sizeof(*new_extents), | ||
8073 | GFP_NOFS); | ||
8074 | if (!new_extents) { | ||
8075 | ret = -ENOMEM; | ||
8076 | goto out; | ||
8077 | } | ||
8078 | nr_extents = 1; | ||
8079 | ret = get_new_locations(reloc_inode, | ||
8080 | extent_key, | ||
8081 | group_start, 1, | ||
8082 | &new_extents, | ||
8083 | &nr_extents); | ||
8084 | if (ret) | ||
8085 | goto out; | ||
8086 | } | ||
8087 | ret = replace_one_extent(trans, found_root, | ||
8088 | path, extent_key, | ||
8089 | &first_key, ref_path, | ||
8090 | new_extents, nr_extents); | ||
8091 | } else { | ||
8092 | ret = relocate_tree_block(trans, found_root, path, | ||
8093 | &first_key, ref_path); | ||
8094 | } | ||
8095 | if (ret < 0) | ||
8096 | goto out; | ||
8097 | } | ||
8098 | ret = 0; | ||
8099 | out: | ||
8100 | btrfs_end_transaction(trans, extent_root); | ||
8101 | kfree(new_extents); | ||
8102 | kfree(ref_path); | ||
8103 | return ret; | ||
8104 | } | ||
8105 | #endif | ||
8106 | |||
8107 | static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) | 6448 | static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) |
8108 | { | 6449 | { |
8109 | u64 num_devices; | 6450 | u64 num_devices; |