diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
| -rw-r--r-- | fs/btrfs/extent-tree.c | 53 | 
1 files changed, 39 insertions, 14 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f396aba92c57..8e8cc1111277 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -1260,7 +1260,8 @@ static int btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len,  	u64 bytes_left, end;  	u64 aligned_start = ALIGN(start, 1 << SECTOR_SHIFT); -	if (WARN_ON(start != aligned_start)) { +	/* Adjust the range to be aligned to 512B sectors if necessary. */ +	if (start != aligned_start) {  		len -= aligned_start - start;  		len = round_down(len, 1 << SECTOR_SHIFT);  		start = aligned_start; @@ -4298,6 +4299,42 @@ static int prepare_allocation_clustered(struct btrfs_fs_info *fs_info,  	return 0;  } +static int prepare_allocation_zoned(struct btrfs_fs_info *fs_info, +				    struct find_free_extent_ctl *ffe_ctl) +{ +	if (ffe_ctl->for_treelog) { +		spin_lock(&fs_info->treelog_bg_lock); +		if (fs_info->treelog_bg) +			ffe_ctl->hint_byte = fs_info->treelog_bg; +		spin_unlock(&fs_info->treelog_bg_lock); +	} else if (ffe_ctl->for_data_reloc) { +		spin_lock(&fs_info->relocation_bg_lock); +		if (fs_info->data_reloc_bg) +			ffe_ctl->hint_byte = fs_info->data_reloc_bg; +		spin_unlock(&fs_info->relocation_bg_lock); +	} else if (ffe_ctl->flags & BTRFS_BLOCK_GROUP_DATA) { +		struct btrfs_block_group *block_group; + +		spin_lock(&fs_info->zone_active_bgs_lock); +		list_for_each_entry(block_group, &fs_info->zone_active_bgs, active_bg_list) { +			/* +			 * No lock is OK here because avail is monotinically +			 * decreasing, and this is just a hint. +			 */ +			u64 avail = block_group->zone_capacity - block_group->alloc_offset; + +			if (block_group_bits(block_group, ffe_ctl->flags) && +			    avail >= ffe_ctl->num_bytes) { +				ffe_ctl->hint_byte = block_group->start; +				break; +			} +		} +		spin_unlock(&fs_info->zone_active_bgs_lock); +	} + +	return 0; +} +  static int prepare_allocation(struct btrfs_fs_info *fs_info,  			      struct find_free_extent_ctl *ffe_ctl,  			      struct btrfs_space_info *space_info, @@ -4308,19 +4345,7 @@ static int prepare_allocation(struct btrfs_fs_info *fs_info,  		return prepare_allocation_clustered(fs_info, ffe_ctl,  						    space_info, ins);  	case BTRFS_EXTENT_ALLOC_ZONED: -		if (ffe_ctl->for_treelog) { -			spin_lock(&fs_info->treelog_bg_lock); -			if (fs_info->treelog_bg) -				ffe_ctl->hint_byte = fs_info->treelog_bg; -			spin_unlock(&fs_info->treelog_bg_lock); -		} -		if (ffe_ctl->for_data_reloc) { -			spin_lock(&fs_info->relocation_bg_lock); -			if (fs_info->data_reloc_bg) -				ffe_ctl->hint_byte = fs_info->data_reloc_bg; -			spin_unlock(&fs_info->relocation_bg_lock); -		} -		return 0; +		return prepare_allocation_zoned(fs_info, ffe_ctl);  	default:  		BUG();  	}  | 
