diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 700879ed64cf..283af7a676a3 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -34,23 +34,24 @@ | |||
34 | #include "locking.h" | 34 | #include "locking.h" |
35 | #include "free-space-cache.h" | 35 | #include "free-space-cache.h" |
36 | 36 | ||
37 | /* control flags for do_chunk_alloc's force field | 37 | /* |
38 | * control flags for do_chunk_alloc's force field | ||
38 | * CHUNK_ALLOC_NO_FORCE means to only allocate a chunk | 39 | * CHUNK_ALLOC_NO_FORCE means to only allocate a chunk |
39 | * if we really need one. | 40 | * if we really need one. |
40 | * | 41 | * |
41 | * CHUNK_ALLOC_FORCE means it must try to allocate one | ||
42 | * | ||
43 | * CHUNK_ALLOC_LIMITED means to only try and allocate one | 42 | * CHUNK_ALLOC_LIMITED means to only try and allocate one |
44 | * if we have very few chunks already allocated. This is | 43 | * if we have very few chunks already allocated. This is |
45 | * used as part of the clustering code to help make sure | 44 | * used as part of the clustering code to help make sure |
46 | * we have a good pool of storage to cluster in, without | 45 | * we have a good pool of storage to cluster in, without |
47 | * filling the FS with empty chunks | 46 | * filling the FS with empty chunks |
48 | * | 47 | * |
48 | * CHUNK_ALLOC_FORCE means it must try to allocate one | ||
49 | * | ||
49 | */ | 50 | */ |
50 | enum { | 51 | enum { |
51 | CHUNK_ALLOC_NO_FORCE = 0, | 52 | CHUNK_ALLOC_NO_FORCE = 0, |
52 | CHUNK_ALLOC_FORCE = 1, | 53 | CHUNK_ALLOC_LIMITED = 1, |
53 | CHUNK_ALLOC_LIMITED = 2, | 54 | CHUNK_ALLOC_FORCE = 2, |
54 | }; | 55 | }; |
55 | 56 | ||
56 | /* | 57 | /* |
@@ -3414,7 +3415,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
3414 | 3415 | ||
3415 | again: | 3416 | again: |
3416 | spin_lock(&space_info->lock); | 3417 | spin_lock(&space_info->lock); |
3417 | if (space_info->force_alloc) | 3418 | if (force < space_info->force_alloc) |
3418 | force = space_info->force_alloc; | 3419 | force = space_info->force_alloc; |
3419 | if (space_info->full) { | 3420 | if (space_info->full) { |
3420 | spin_unlock(&space_info->lock); | 3421 | spin_unlock(&space_info->lock); |
@@ -5794,6 +5795,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
5794 | u64 search_end, struct btrfs_key *ins, | 5795 | u64 search_end, struct btrfs_key *ins, |
5795 | u64 data) | 5796 | u64 data) |
5796 | { | 5797 | { |
5798 | bool final_tried = false; | ||
5797 | int ret; | 5799 | int ret; |
5798 | u64 search_start = 0; | 5800 | u64 search_start = 0; |
5799 | 5801 | ||
@@ -5813,22 +5815,25 @@ again: | |||
5813 | search_start, search_end, hint_byte, | 5815 | search_start, search_end, hint_byte, |
5814 | ins, data); | 5816 | ins, data); |
5815 | 5817 | ||
5816 | if (ret == -ENOSPC && num_bytes > min_alloc_size) { | 5818 | if (ret == -ENOSPC) { |
5817 | num_bytes = num_bytes >> 1; | 5819 | if (!final_tried) { |
5818 | num_bytes = num_bytes & ~(root->sectorsize - 1); | 5820 | num_bytes = num_bytes >> 1; |
5819 | num_bytes = max(num_bytes, min_alloc_size); | 5821 | num_bytes = num_bytes & ~(root->sectorsize - 1); |
5820 | do_chunk_alloc(trans, root->fs_info->extent_root, | 5822 | num_bytes = max(num_bytes, min_alloc_size); |
5821 | num_bytes, data, CHUNK_ALLOC_FORCE); | 5823 | do_chunk_alloc(trans, root->fs_info->extent_root, |
5822 | goto again; | 5824 | num_bytes, data, CHUNK_ALLOC_FORCE); |
5823 | } | 5825 | if (num_bytes == min_alloc_size) |
5824 | if (ret == -ENOSPC && btrfs_test_opt(root, ENOSPC_DEBUG)) { | 5826 | final_tried = true; |
5825 | struct btrfs_space_info *sinfo; | 5827 | goto again; |
5826 | 5828 | } else if (btrfs_test_opt(root, ENOSPC_DEBUG)) { | |
5827 | sinfo = __find_space_info(root->fs_info, data); | 5829 | struct btrfs_space_info *sinfo; |
5828 | printk(KERN_ERR "btrfs allocation failed flags %llu, " | 5830 | |
5829 | "wanted %llu\n", (unsigned long long)data, | 5831 | sinfo = __find_space_info(root->fs_info, data); |
5830 | (unsigned long long)num_bytes); | 5832 | printk(KERN_ERR "btrfs allocation failed flags %llu, " |
5831 | dump_space_info(sinfo, num_bytes, 1); | 5833 | "wanted %llu\n", (unsigned long long)data, |
5834 | (unsigned long long)num_bytes); | ||
5835 | dump_space_info(sinfo, num_bytes, 1); | ||
5836 | } | ||
5832 | } | 5837 | } |
5833 | 5838 | ||
5834 | trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset); | 5839 | trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset); |