diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-12 18:19:40 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-12 18:19:53 -0500 |
commit | 007d00d4c11b30b8fd7ff23b9d5aed3743e41f74 (patch) | |
tree | d5c307ba2ee0e2f56fbc284db21b8bccf95d8a40 /fs/btrfs/extent-tree.c | |
parent | c91043adaf50ef13609003120f3471783460fb71 (diff) | |
parent | 68d3e668d245bb8300c7c6ddbc8508ddfe352e0f (diff) |
Merge branch 'for-next/dwc3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
* 'for-next/dwc3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb: (392 commits)
usb: dwc3: ep0: fix for possible early delayed_status
usb: dwc3: gadget: fix stream enable bit
usb: dwc3: ep0: fix GetStatus handling (again)
usb: dwc3: ep0: use dwc3_request for ep0 requsts instead of usb_request
usb: dwc3: use correct hwparam register for power mgm check
usb: dwc3: omap: move to module_platform_driver
usb: dwc3: workaround: missing disconnect event
usb: dwc3: workaround: missing USB3 Reset event
usb: dwc3: workaround: U1/U2 -> U0 transiton
usb: dwc3: gadget: return early in dwc3_cleanup_done_reqs()
usb: dwc3: ep0: handle delayed_status again
usb: dwc3: ep0: push ep0state into xfernotready processing
usb: dwc3: fix sparse errors
usb: dwc3: fix few coding style problems
usb: dwc3: move generic dwc3 code from gadget into core
usb: dwc3: use a helper function for operation mode setting
usb: dwc3: ep0: don't use ep0in for transfers
usb: dwc3: ep0: use proper endianess in SetFeature for wIndex
usb: dwc3: core: drop DWC3_EVENT_BUFFERS_MAX
usb: dwc3: omap: add multiple instances support to OMAP
...
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 100 |
1 files changed, 49 insertions, 51 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f0d5718d2587..2ad813674d77 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -5107,11 +5107,11 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
5107 | struct btrfs_root *root = orig_root->fs_info->extent_root; | 5107 | struct btrfs_root *root = orig_root->fs_info->extent_root; |
5108 | struct btrfs_free_cluster *last_ptr = NULL; | 5108 | struct btrfs_free_cluster *last_ptr = NULL; |
5109 | struct btrfs_block_group_cache *block_group = NULL; | 5109 | struct btrfs_block_group_cache *block_group = NULL; |
5110 | struct btrfs_block_group_cache *used_block_group; | ||
5110 | int empty_cluster = 2 * 1024 * 1024; | 5111 | int empty_cluster = 2 * 1024 * 1024; |
5111 | int allowed_chunk_alloc = 0; | 5112 | int allowed_chunk_alloc = 0; |
5112 | int done_chunk_alloc = 0; | 5113 | int done_chunk_alloc = 0; |
5113 | struct btrfs_space_info *space_info; | 5114 | struct btrfs_space_info *space_info; |
5114 | int last_ptr_loop = 0; | ||
5115 | int loop = 0; | 5115 | int loop = 0; |
5116 | int index = 0; | 5116 | int index = 0; |
5117 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? | 5117 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? |
@@ -5173,6 +5173,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
5173 | ideal_cache: | 5173 | ideal_cache: |
5174 | block_group = btrfs_lookup_block_group(root->fs_info, | 5174 | block_group = btrfs_lookup_block_group(root->fs_info, |
5175 | search_start); | 5175 | search_start); |
5176 | used_block_group = block_group; | ||
5176 | /* | 5177 | /* |
5177 | * we don't want to use the block group if it doesn't match our | 5178 | * we don't want to use the block group if it doesn't match our |
5178 | * allocation bits, or if its not cached. | 5179 | * allocation bits, or if its not cached. |
@@ -5210,6 +5211,7 @@ search: | |||
5210 | u64 offset; | 5211 | u64 offset; |
5211 | int cached; | 5212 | int cached; |
5212 | 5213 | ||
5214 | used_block_group = block_group; | ||
5213 | btrfs_get_block_group(block_group); | 5215 | btrfs_get_block_group(block_group); |
5214 | search_start = block_group->key.objectid; | 5216 | search_start = block_group->key.objectid; |
5215 | 5217 | ||
@@ -5286,71 +5288,62 @@ alloc: | |||
5286 | spin_unlock(&block_group->free_space_ctl->tree_lock); | 5288 | spin_unlock(&block_group->free_space_ctl->tree_lock); |
5287 | 5289 | ||
5288 | /* | 5290 | /* |
5289 | * Ok we want to try and use the cluster allocator, so lets look | 5291 | * Ok we want to try and use the cluster allocator, so |
5290 | * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will | 5292 | * lets look there |
5291 | * have tried the cluster allocator plenty of times at this | ||
5292 | * point and not have found anything, so we are likely way too | ||
5293 | * fragmented for the clustering stuff to find anything, so lets | ||
5294 | * just skip it and let the allocator find whatever block it can | ||
5295 | * find | ||
5296 | */ | 5293 | */ |
5297 | if (last_ptr && loop < LOOP_NO_EMPTY_SIZE) { | 5294 | if (last_ptr) { |
5298 | /* | 5295 | /* |
5299 | * the refill lock keeps out other | 5296 | * the refill lock keeps out other |
5300 | * people trying to start a new cluster | 5297 | * people trying to start a new cluster |
5301 | */ | 5298 | */ |
5302 | spin_lock(&last_ptr->refill_lock); | 5299 | spin_lock(&last_ptr->refill_lock); |
5303 | if (!last_ptr->block_group || | 5300 | used_block_group = last_ptr->block_group; |
5304 | last_ptr->block_group->ro || | 5301 | if (used_block_group != block_group && |
5305 | !block_group_bits(last_ptr->block_group, data)) | 5302 | (!used_block_group || |
5303 | used_block_group->ro || | ||
5304 | !block_group_bits(used_block_group, data))) { | ||
5305 | used_block_group = block_group; | ||
5306 | goto refill_cluster; | 5306 | goto refill_cluster; |
5307 | } | ||
5308 | |||
5309 | if (used_block_group != block_group) | ||
5310 | btrfs_get_block_group(used_block_group); | ||
5307 | 5311 | ||
5308 | offset = btrfs_alloc_from_cluster(block_group, last_ptr, | 5312 | offset = btrfs_alloc_from_cluster(used_block_group, |
5309 | num_bytes, search_start); | 5313 | last_ptr, num_bytes, used_block_group->key.objectid); |
5310 | if (offset) { | 5314 | if (offset) { |
5311 | /* we have a block, we're done */ | 5315 | /* we have a block, we're done */ |
5312 | spin_unlock(&last_ptr->refill_lock); | 5316 | spin_unlock(&last_ptr->refill_lock); |
5313 | goto checks; | 5317 | goto checks; |
5314 | } | 5318 | } |
5315 | 5319 | ||
5316 | spin_lock(&last_ptr->lock); | 5320 | WARN_ON(last_ptr->block_group != used_block_group); |
5317 | /* | 5321 | if (used_block_group != block_group) { |
5318 | * whoops, this cluster doesn't actually point to | 5322 | btrfs_put_block_group(used_block_group); |
5319 | * this block group. Get a ref on the block | 5323 | used_block_group = block_group; |
5320 | * group is does point to and try again | ||
5321 | */ | ||
5322 | if (!last_ptr_loop && last_ptr->block_group && | ||
5323 | last_ptr->block_group != block_group && | ||
5324 | index <= | ||
5325 | get_block_group_index(last_ptr->block_group)) { | ||
5326 | |||
5327 | btrfs_put_block_group(block_group); | ||
5328 | block_group = last_ptr->block_group; | ||
5329 | btrfs_get_block_group(block_group); | ||
5330 | spin_unlock(&last_ptr->lock); | ||
5331 | spin_unlock(&last_ptr->refill_lock); | ||
5332 | |||
5333 | last_ptr_loop = 1; | ||
5334 | search_start = block_group->key.objectid; | ||
5335 | /* | ||
5336 | * we know this block group is properly | ||
5337 | * in the list because | ||
5338 | * btrfs_remove_block_group, drops the | ||
5339 | * cluster before it removes the block | ||
5340 | * group from the list | ||
5341 | */ | ||
5342 | goto have_block_group; | ||
5343 | } | 5324 | } |
5344 | spin_unlock(&last_ptr->lock); | ||
5345 | refill_cluster: | 5325 | refill_cluster: |
5326 | BUG_ON(used_block_group != block_group); | ||
5327 | /* If we are on LOOP_NO_EMPTY_SIZE, we can't | ||
5328 | * set up a new clusters, so lets just skip it | ||
5329 | * and let the allocator find whatever block | ||
5330 | * it can find. If we reach this point, we | ||
5331 | * will have tried the cluster allocator | ||
5332 | * plenty of times and not have found | ||
5333 | * anything, so we are likely way too | ||
5334 | * fragmented for the clustering stuff to find | ||
5335 | * anything. */ | ||
5336 | if (loop >= LOOP_NO_EMPTY_SIZE) { | ||
5337 | spin_unlock(&last_ptr->refill_lock); | ||
5338 | goto unclustered_alloc; | ||
5339 | } | ||
5340 | |||
5346 | /* | 5341 | /* |
5347 | * this cluster didn't work out, free it and | 5342 | * this cluster didn't work out, free it and |
5348 | * start over | 5343 | * start over |
5349 | */ | 5344 | */ |
5350 | btrfs_return_cluster_to_free_space(NULL, last_ptr); | 5345 | btrfs_return_cluster_to_free_space(NULL, last_ptr); |
5351 | 5346 | ||
5352 | last_ptr_loop = 0; | ||
5353 | |||
5354 | /* allocate a cluster in this block group */ | 5347 | /* allocate a cluster in this block group */ |
5355 | ret = btrfs_find_space_cluster(trans, root, | 5348 | ret = btrfs_find_space_cluster(trans, root, |
5356 | block_group, last_ptr, | 5349 | block_group, last_ptr, |
@@ -5390,6 +5383,7 @@ refill_cluster: | |||
5390 | goto loop; | 5383 | goto loop; |
5391 | } | 5384 | } |
5392 | 5385 | ||
5386 | unclustered_alloc: | ||
5393 | offset = btrfs_find_space_for_alloc(block_group, search_start, | 5387 | offset = btrfs_find_space_for_alloc(block_group, search_start, |
5394 | num_bytes, empty_size); | 5388 | num_bytes, empty_size); |
5395 | /* | 5389 | /* |
@@ -5416,14 +5410,14 @@ checks: | |||
5416 | search_start = stripe_align(root, offset); | 5410 | search_start = stripe_align(root, offset); |
5417 | /* move on to the next group */ | 5411 | /* move on to the next group */ |
5418 | if (search_start + num_bytes >= search_end) { | 5412 | if (search_start + num_bytes >= search_end) { |
5419 | btrfs_add_free_space(block_group, offset, num_bytes); | 5413 | btrfs_add_free_space(used_block_group, offset, num_bytes); |
5420 | goto loop; | 5414 | goto loop; |
5421 | } | 5415 | } |
5422 | 5416 | ||
5423 | /* move on to the next group */ | 5417 | /* move on to the next group */ |
5424 | if (search_start + num_bytes > | 5418 | if (search_start + num_bytes > |
5425 | block_group->key.objectid + block_group->key.offset) { | 5419 | used_block_group->key.objectid + used_block_group->key.offset) { |
5426 | btrfs_add_free_space(block_group, offset, num_bytes); | 5420 | btrfs_add_free_space(used_block_group, offset, num_bytes); |
5427 | goto loop; | 5421 | goto loop; |
5428 | } | 5422 | } |
5429 | 5423 | ||
@@ -5431,14 +5425,14 @@ checks: | |||
5431 | ins->offset = num_bytes; | 5425 | ins->offset = num_bytes; |
5432 | 5426 | ||
5433 | if (offset < search_start) | 5427 | if (offset < search_start) |
5434 | btrfs_add_free_space(block_group, offset, | 5428 | btrfs_add_free_space(used_block_group, offset, |
5435 | search_start - offset); | 5429 | search_start - offset); |
5436 | BUG_ON(offset > search_start); | 5430 | BUG_ON(offset > search_start); |
5437 | 5431 | ||
5438 | ret = btrfs_update_reserved_bytes(block_group, num_bytes, | 5432 | ret = btrfs_update_reserved_bytes(used_block_group, num_bytes, |
5439 | alloc_type); | 5433 | alloc_type); |
5440 | if (ret == -EAGAIN) { | 5434 | if (ret == -EAGAIN) { |
5441 | btrfs_add_free_space(block_group, offset, num_bytes); | 5435 | btrfs_add_free_space(used_block_group, offset, num_bytes); |
5442 | goto loop; | 5436 | goto loop; |
5443 | } | 5437 | } |
5444 | 5438 | ||
@@ -5447,15 +5441,19 @@ checks: | |||
5447 | ins->offset = num_bytes; | 5441 | ins->offset = num_bytes; |
5448 | 5442 | ||
5449 | if (offset < search_start) | 5443 | if (offset < search_start) |
5450 | btrfs_add_free_space(block_group, offset, | 5444 | btrfs_add_free_space(used_block_group, offset, |
5451 | search_start - offset); | 5445 | search_start - offset); |
5452 | BUG_ON(offset > search_start); | 5446 | BUG_ON(offset > search_start); |
5447 | if (used_block_group != block_group) | ||
5448 | btrfs_put_block_group(used_block_group); | ||
5453 | btrfs_put_block_group(block_group); | 5449 | btrfs_put_block_group(block_group); |
5454 | break; | 5450 | break; |
5455 | loop: | 5451 | loop: |
5456 | failed_cluster_refill = false; | 5452 | failed_cluster_refill = false; |
5457 | failed_alloc = false; | 5453 | failed_alloc = false; |
5458 | BUG_ON(index != get_block_group_index(block_group)); | 5454 | BUG_ON(index != get_block_group_index(block_group)); |
5455 | if (used_block_group != block_group) | ||
5456 | btrfs_put_block_group(used_block_group); | ||
5459 | btrfs_put_block_group(block_group); | 5457 | btrfs_put_block_group(block_group); |
5460 | } | 5458 | } |
5461 | up_read(&space_info->groups_sem); | 5459 | up_read(&space_info->groups_sem); |