diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-10-07 15:43:04 +0100 | 
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-10-07 15:43:04 +0100 | 
| commit | a56e74f546b64be93731e42d83baf5b538cc1b11 (patch) | |
| tree | 18f6dee45d801e57ac9db2a31664b0d5c0762c50 /fs/btrfs/extent-tree.c | |
| parent | d08e2e09042bd3f7ef66a35cb4bb92794ab26bb2 (diff) | |
| parent | e4e7f10bfc4069925e99cc4b428c3434e30b6c3f (diff) | |
Merge branch 'arm-aesbs' of git://git.linaro.org/people/ardbiesheuvel/linux-arm into devel-stable
Diffstat (limited to 'fs/btrfs/extent-tree.c')
| -rw-r--r-- | fs/btrfs/extent-tree.c | 57 | 
1 files changed, 30 insertions, 27 deletions
| diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index cfb3cf711b34..d58bef130a41 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3925,7 +3925,6 @@ static int can_overcommit(struct btrfs_root *root,  	u64 space_size;  	u64 avail;  	u64 used; -	u64 to_add;  	used = space_info->bytes_used + space_info->bytes_reserved +  		space_info->bytes_pinned + space_info->bytes_readonly; @@ -3959,25 +3958,17 @@ static int can_overcommit(struct btrfs_root *root,  		       BTRFS_BLOCK_GROUP_RAID10))  		avail >>= 1; -	to_add = space_info->total_bytes; -  	/*  	 * If we aren't flushing all things, let us overcommit up to  	 * 1/2th of the space. If we can flush, don't let us overcommit  	 * too much, let it overcommit up to 1/8 of the space.  	 */  	if (flush == BTRFS_RESERVE_FLUSH_ALL) -		to_add >>= 3; +		avail >>= 3;  	else -		to_add >>= 1; - -	/* -	 * Limit the overcommit to the amount of free space we could possibly -	 * allocate for chunks. -	 */ -	to_add = min(avail, to_add); +		avail >>= 1; -	if (used + bytes < space_info->total_bytes + to_add) +	if (used + bytes < space_info->total_bytes + avail)  		return 1;  	return 0;  } @@ -4000,7 +3991,7 @@ static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root,  		 */  		btrfs_start_all_delalloc_inodes(root->fs_info, 0);  		if (!current->journal_info) -			btrfs_wait_all_ordered_extents(root->fs_info, 0); +			btrfs_wait_all_ordered_extents(root->fs_info);  	}  } @@ -4030,7 +4021,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,  	if (delalloc_bytes == 0) {  		if (trans)  			return; -		btrfs_wait_all_ordered_extents(root->fs_info, 0); +		btrfs_wait_all_ordered_extents(root->fs_info);  		return;  	} @@ -4058,7 +4049,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,  		loops++;  		if (wait_ordered && !trans) { -			btrfs_wait_all_ordered_extents(root->fs_info, 0); +			btrfs_wait_all_ordered_extents(root->fs_info);  		} else {  			time_left = schedule_timeout_killable(1);  			if (time_left) @@ -4465,7 +4456,6 @@ static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info,  			space_info->bytes_may_use -= num_bytes;  			trace_btrfs_space_reservation(fs_info, "space_info",  					space_info->flags, num_bytes, 0); -			space_info->reservation_progress++;  			spin_unlock(&space_info->lock);  		}  	} @@ -4666,7 +4656,6 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)  		sinfo->bytes_may_use -= num_bytes;  		trace_btrfs_space_reservation(fs_info, "space_info",  				      sinfo->flags, num_bytes, 0); -		sinfo->reservation_progress++;  		block_rsv->reserved = block_rsv->size;  		block_rsv->full = 1;  	} @@ -5446,7 +5435,6 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,  			space_info->bytes_readonly += num_bytes;  		cache->reserved -= num_bytes;  		space_info->bytes_reserved -= num_bytes; -		space_info->reservation_progress++;  	}  	spin_unlock(&cache->lock);  	spin_unlock(&space_info->lock); @@ -6117,10 +6105,13 @@ enum btrfs_loop_type {  /*   * walks the btree of allocated extents and find a hole of a given size.   * The key ins is changed to record the hole: - * ins->objectid == block start + * ins->objectid == start position   * ins->flags = BTRFS_EXTENT_ITEM_KEY - * ins->offset == number of blocks + * ins->offset == the size of the hole.   * Any available blocks before search_start are skipped. + * + * If there is no suitable free space, we will record the max size of + * the free space extent currently.   */  static noinline int find_free_extent(struct btrfs_root *orig_root,  				     u64 num_bytes, u64 empty_size, @@ -6133,6 +6124,7 @@ static noinline int find_free_extent(struct btrfs_root *orig_root,  	struct btrfs_block_group_cache *block_group = NULL;  	struct btrfs_block_group_cache *used_block_group;  	u64 search_start = 0; +	u64 max_extent_size = 0;  	int empty_cluster = 2 * 1024 * 1024;  	struct btrfs_space_info *space_info;  	int loop = 0; @@ -6292,7 +6284,10 @@ have_block_group:  				btrfs_get_block_group(used_block_group);  			offset = btrfs_alloc_from_cluster(used_block_group, -			  last_ptr, num_bytes, used_block_group->key.objectid); +						last_ptr, +						num_bytes, +						used_block_group->key.objectid, +						&max_extent_size);  			if (offset) {  				/* we have a block, we're done */  				spin_unlock(&last_ptr->refill_lock); @@ -6355,8 +6350,10 @@ refill_cluster:  				 * cluster  				 */  				offset = btrfs_alloc_from_cluster(block_group, -						  last_ptr, num_bytes, -						  search_start); +							last_ptr, +							num_bytes, +							search_start, +							&max_extent_size);  				if (offset) {  					/* we found one, proceed */  					spin_unlock(&last_ptr->refill_lock); @@ -6391,13 +6388,18 @@ unclustered_alloc:  		if (cached &&  		    block_group->free_space_ctl->free_space <  		    num_bytes + empty_cluster + empty_size) { +			if (block_group->free_space_ctl->free_space > +			    max_extent_size) +				max_extent_size = +					block_group->free_space_ctl->free_space;  			spin_unlock(&block_group->free_space_ctl->tree_lock);  			goto loop;  		}  		spin_unlock(&block_group->free_space_ctl->tree_lock);  		offset = btrfs_find_space_for_alloc(block_group, search_start, -						    num_bytes, empty_size); +						    num_bytes, empty_size, +						    &max_extent_size);  		/*  		 * If we didn't find a chunk, and we haven't failed on this  		 * block group before, and this block group is in the middle of @@ -6515,7 +6517,8 @@ loop:  		ret = 0;  	}  out: - +	if (ret == -ENOSPC) +		ins->offset = max_extent_size;  	return ret;  } @@ -6573,8 +6576,8 @@ again:  			       flags);  	if (ret == -ENOSPC) { -		if (!final_tried) { -			num_bytes = num_bytes >> 1; +		if (!final_tried && ins->offset) { +			num_bytes = min(num_bytes >> 1, ins->offset);  			num_bytes = round_down(num_bytes, root->sectorsize);  			num_bytes = max(num_bytes, min_alloc_size);  			if (num_bytes == min_alloc_size) | 
