aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent-tree.c256
1 files changed, 91 insertions, 165 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 2c214781fee..daff751ea6e 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2556,14 +2556,10 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
2556 struct btrfs_root *root = orig_root->fs_info->extent_root; 2556 struct btrfs_root *root = orig_root->fs_info->extent_root;
2557 u64 total_needed = num_bytes; 2557 u64 total_needed = num_bytes;
2558 u64 *last_ptr = NULL; 2558 u64 *last_ptr = NULL;
2559 u64 last_wanted = 0;
2560 struct btrfs_block_group_cache *block_group = NULL; 2559 struct btrfs_block_group_cache *block_group = NULL;
2561 int chunk_alloc_done = 0;
2562 int empty_cluster = 2 * 1024 * 1024; 2560 int empty_cluster = 2 * 1024 * 1024;
2563 int allowed_chunk_alloc = 0; 2561 int allowed_chunk_alloc = 0;
2564 struct list_head *head = NULL, *cur = NULL; 2562 int using_hint = 0;
2565 int loop = 0;
2566 int extra_loop = 0;
2567 struct btrfs_space_info *space_info; 2563 struct btrfs_space_info *space_info;
2568 2564
2569 WARN_ON(num_bytes < root->sectorsize); 2565 WARN_ON(num_bytes < root->sectorsize);
@@ -2571,6 +2567,8 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
2571 ins->objectid = 0; 2567 ins->objectid = 0;
2572 ins->offset = 0; 2568 ins->offset = 0;
2573 2569
2570 space_info = __find_space_info(root->fs_info, data);
2571
2574 if (orig_root->ref_cows || empty_size) 2572 if (orig_root->ref_cows || empty_size)
2575 allowed_chunk_alloc = 1; 2573 allowed_chunk_alloc = 1;
2576 2574
@@ -2584,10 +2582,9 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
2584 last_ptr = &root->fs_info->last_data_alloc; 2582 last_ptr = &root->fs_info->last_data_alloc;
2585 2583
2586 if (last_ptr) { 2584 if (last_ptr) {
2587 if (*last_ptr) { 2585 if (*last_ptr)
2588 hint_byte = *last_ptr; 2586 hint_byte = *last_ptr;
2589 last_wanted = *last_ptr; 2587 else
2590 } else
2591 empty_size += empty_cluster; 2588 empty_size += empty_cluster;
2592 } else { 2589 } else {
2593 empty_cluster = 0; 2590 empty_cluster = 0;
@@ -2595,187 +2592,125 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
2595 search_start = max(search_start, first_logical_byte(root, 0)); 2592 search_start = max(search_start, first_logical_byte(root, 0));
2596 search_start = max(search_start, hint_byte); 2593 search_start = max(search_start, hint_byte);
2597 2594
2598 if (last_wanted && search_start != last_wanted) { 2595 if (search_start == hint_byte) {
2599 last_wanted = 0; 2596 using_hint = 1;
2597 block_group = btrfs_lookup_block_group(root->fs_info,
2598 search_start);
2599 if (block_group && block_group_bits(block_group, data)) {
2600 total_needed += empty_size;
2601 down_read(&space_info->groups_sem);
2602 goto have_block_group;
2603 } else if (block_group) {
2604 put_block_group(block_group);
2605 }
2606
2600 empty_size += empty_cluster; 2607 empty_size += empty_cluster;
2608 using_hint = 0;
2601 } 2609 }
2602 2610
2603 total_needed += empty_size; 2611search:
2604 block_group = btrfs_lookup_block_group(root->fs_info, search_start);
2605 if (!block_group)
2606 block_group = btrfs_lookup_first_block_group(root->fs_info,
2607 search_start);
2608 space_info = __find_space_info(root->fs_info, data);
2609
2610 down_read(&space_info->groups_sem); 2612 down_read(&space_info->groups_sem);
2611 while (1) { 2613 list_for_each_entry(block_group, &space_info->block_groups, list) {
2612 struct btrfs_free_space *free_space; 2614 struct btrfs_free_space *free_space;
2613 /*
2614 * the only way this happens if our hint points to a block
2615 * group thats not of the proper type, while looping this
2616 * should never happen
2617 */
2618 if (empty_size)
2619 extra_loop = 1;
2620 2615
2621 if (!block_group) 2616 atomic_inc(&block_group->count);
2622 goto new_group_no_lock; 2617 search_start = block_group->key.objectid;
2623 2618
2619have_block_group:
2624 if (unlikely(!block_group->cached)) { 2620 if (unlikely(!block_group->cached)) {
2625 mutex_lock(&block_group->cache_mutex); 2621 mutex_lock(&block_group->cache_mutex);
2626 ret = cache_block_group(root, block_group); 2622 ret = cache_block_group(root, block_group);
2627 mutex_unlock(&block_group->cache_mutex); 2623 mutex_unlock(&block_group->cache_mutex);
2628 if (ret) 2624 if (ret) {
2625 put_block_group(block_group);
2629 break; 2626 break;
2627 }
2630 } 2628 }
2631 2629
2632 mutex_lock(&block_group->alloc_mutex); 2630 mutex_lock(&block_group->alloc_mutex);
2633 if (unlikely(!block_group_bits(block_group, data)))
2634 goto new_group;
2635 2631
2636 if (unlikely(block_group->ro)) 2632 if (unlikely(block_group->ro))
2637 goto new_group; 2633 goto loop;
2638 2634
2639 free_space = btrfs_find_free_space(block_group, search_start, 2635 free_space = btrfs_find_free_space(block_group, search_start,
2640 total_needed); 2636 total_needed);
2641 if (free_space) { 2637 if (!free_space)
2642 u64 start = block_group->key.objectid; 2638 goto loop;
2643 u64 end = block_group->key.objectid +
2644 block_group->key.offset;
2645 2639
2646 search_start = stripe_align(root, free_space->offset); 2640 search_start = stripe_align(root, free_space->offset);
2647 2641
2648 /* move on to the next group */ 2642 /* move on to the next group */
2649 if (search_start + num_bytes >= search_end) 2643 if (search_start + num_bytes >= search_end)
2650 goto new_group; 2644 goto loop;
2651 2645
2652 /* move on to the next group */ 2646 /* move on to the next group */
2653 if (search_start + num_bytes > end) 2647 if (search_start + num_bytes >
2654 goto new_group; 2648 block_group->key.objectid + block_group->key.offset)
2649 goto loop;
2655 2650
2656 if (last_wanted && search_start != last_wanted) { 2651 if (using_hint && search_start > hint_byte)
2657 total_needed += empty_cluster; 2652 goto loop;
2658 empty_size += empty_cluster;
2659 last_wanted = 0;
2660 /*
2661 * if search_start is still in this block group
2662 * then we just re-search this block group
2663 */
2664 if (search_start >= start &&
2665 search_start < end) {
2666 mutex_unlock(&block_group->alloc_mutex);
2667 continue;
2668 }
2669 2653
2670 /* else we go to the next block group */ 2654 if (exclude_nr > 0 &&
2671 goto new_group; 2655 (search_start + num_bytes > exclude_start &&
2672 } 2656 search_start < exclude_start + exclude_nr)) {
2657 search_start = exclude_start + exclude_nr;
2673 2658
2674 if (exclude_nr > 0 && 2659 /*
2675 (search_start + num_bytes > exclude_start && 2660 * if search_start is still in this block group
2676 search_start < exclude_start + exclude_nr)) { 2661 * then we just re-search this block group
2677 search_start = exclude_start + exclude_nr; 2662 */
2678 /* 2663 if (search_start >= block_group->key.objectid &&
2679 * if search_start is still in this block group 2664 search_start < (block_group->key.objectid +
2680 * then we just re-search this block group 2665 block_group->key.offset)) {
2681 */ 2666 mutex_unlock(&block_group->alloc_mutex);
2682 if (search_start >= start && 2667 goto have_block_group;
2683 search_start < end) {
2684 mutex_unlock(&block_group->alloc_mutex);
2685 last_wanted = 0;
2686 continue;
2687 }
2688
2689 /* else we go to the next block group */
2690 goto new_group;
2691 } 2668 }
2669 goto loop;
2670 }
2692 2671
2693 ins->objectid = search_start; 2672 ins->objectid = search_start;
2694 ins->offset = num_bytes; 2673 ins->offset = num_bytes;
2695 2674
2696 btrfs_remove_free_space_lock(block_group, search_start, 2675 btrfs_remove_free_space_lock(block_group, search_start,
2697 num_bytes); 2676 num_bytes);
2698 /* we are all good, lets return */ 2677 /* we are all good, lets return */
2699 mutex_unlock(&block_group->alloc_mutex); 2678 mutex_unlock(&block_group->alloc_mutex);
2700 break; 2679 break;
2701 } 2680loop:
2702new_group:
2703 mutex_unlock(&block_group->alloc_mutex); 2681 mutex_unlock(&block_group->alloc_mutex);
2704 put_block_group(block_group); 2682 put_block_group(block_group);
2705 block_group = NULL; 2683 if (using_hint) {
2706new_group_no_lock: 2684 empty_size += empty_cluster;
2707 /* don't try to compare new allocations against the 2685 total_needed += empty_cluster;
2708 * last allocation any more 2686 using_hint = 0;
2709 */ 2687 up_read(&space_info->groups_sem);
2710 last_wanted = 0; 2688 goto search;
2711
2712 /*
2713 * Here's how this works.
2714 * loop == 0: we were searching a block group via a hint
2715 * and didn't find anything, so we start at
2716 * the head of the block groups and keep searching
2717 * loop == 1: we're searching through all of the block groups
2718 * if we hit the head again we have searched
2719 * all of the block groups for this space and we
2720 * need to try and allocate, if we cant error out.
2721 * loop == 2: we allocated more space and are looping through
2722 * all of the block groups again.
2723 */
2724 if (loop == 0) {
2725 head = &space_info->block_groups;
2726 cur = head->next;
2727 loop++;
2728 } else if (loop == 1 && cur == head) {
2729 int keep_going;
2730
2731 /* at this point we give up on the empty_size
2732 * allocations and just try to allocate the min
2733 * space.
2734 *
2735 * The extra_loop field was set if an empty_size
2736 * allocation was attempted above, and if this
2737 * is try we need to try the loop again without
2738 * the additional empty_size.
2739 */
2740 total_needed -= empty_size;
2741 empty_size = 0;
2742 keep_going = extra_loop;
2743 loop++;
2744
2745 if (allowed_chunk_alloc && !chunk_alloc_done) {
2746 up_read(&space_info->groups_sem);
2747 ret = do_chunk_alloc(trans, root, num_bytes +
2748 2 * 1024 * 1024, data, 1);
2749 down_read(&space_info->groups_sem);
2750 if (ret < 0)
2751 goto loop_check;
2752 head = &space_info->block_groups;
2753 /*
2754 * we've allocated a new chunk, keep
2755 * trying
2756 */
2757 keep_going = 1;
2758 chunk_alloc_done = 1;
2759 } else if (!allowed_chunk_alloc) {
2760 space_info->force_alloc = 1;
2761 }
2762loop_check:
2763 if (keep_going) {
2764 cur = head->next;
2765 extra_loop = 0;
2766 } else {
2767 break;
2768 }
2769 } else if (cur == head) {
2770 break;
2771 } 2689 }
2690 }
2691 up_read(&space_info->groups_sem);
2772 2692
2773 block_group = list_entry(cur, struct btrfs_block_group_cache, 2693 if (!ins->objectid && (empty_size || allowed_chunk_alloc)) {
2774 list); 2694 int try_again = empty_size;
2775 atomic_inc(&block_group->count);
2776 2695
2777 search_start = block_group->key.objectid; 2696 total_needed -= empty_size;
2778 cur = cur->next; 2697 empty_size = 0;
2698
2699 if (allowed_chunk_alloc) {
2700 ret = do_chunk_alloc(trans, root, num_bytes +
2701 2 * 1024 * 1024, data, 1);
2702 if (!ret)
2703 try_again = 1;
2704 allowed_chunk_alloc = 0;
2705 } else {
2706 space_info->force_alloc = 1;
2707 }
2708
2709 if (try_again)
2710 goto search;
2711 ret = -ENOSPC;
2712 } else if (!ins->objectid) {
2713 ret = -ENOSPC;
2779 } 2714 }
2780 2715
2781 /* we found what we needed */ 2716 /* we found what we needed */
@@ -2785,19 +2720,10 @@ loop_check:
2785 2720
2786 if (last_ptr) 2721 if (last_ptr)
2787 *last_ptr = ins->objectid + ins->offset; 2722 *last_ptr = ins->objectid + ins->offset;
2723 put_block_group(block_group);
2788 ret = 0; 2724 ret = 0;
2789 } else if (!ret) {
2790 printk(KERN_ERR "btrfs searching for %llu bytes, "
2791 "num_bytes %llu, loop %d, allowed_alloc %d\n",
2792 (unsigned long long)total_needed,
2793 (unsigned long long)num_bytes,
2794 loop, allowed_chunk_alloc);
2795 ret = -ENOSPC;
2796 } 2725 }
2797 if (block_group)
2798 put_block_group(block_group);
2799 2726
2800 up_read(&space_info->groups_sem);
2801 return ret; 2727 return ret;
2802} 2728}
2803 2729