@@ -6728,6 +6728,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6728
6728
struct btrfs_space_info * space_info ;
6729
6729
struct btrfs_fs_devices * fs_devices = root -> fs_info -> fs_devices ;
6730
6730
struct btrfs_device * device ;
6731
+ u64 min_free ;
6732
+ int index ;
6733
+ int dev_nr = 0 ;
6734
+ int dev_min = 1 ;
6731
6735
int full = 0 ;
6732
6736
int ret = 0 ;
6733
6737
@@ -6737,8 +6741,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6737
6741
if (!block_group )
6738
6742
return -1 ;
6739
6743
6744
+ min_free = btrfs_block_group_used (& block_group -> item );
6745
+
6740
6746
/* no bytes used, we're good */
6741
- if (!btrfs_block_group_used ( & block_group -> item ) )
6747
+ if (!min_free )
6742
6748
goto out ;
6743
6749
6744
6750
space_info = block_group -> space_info ;
@@ -6754,10 +6760,9 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6754
6760
* all of the extents from this block group. If we can, we're good
6755
6761
*/
6756
6762
if ((space_info -> total_bytes != block_group -> key .offset ) &&
6757
- (space_info -> bytes_used + space_info -> bytes_reserved +
6758
- space_info -> bytes_pinned + space_info -> bytes_readonly +
6759
- btrfs_block_group_used (& block_group -> item ) <
6760
- space_info -> total_bytes )) {
6763
+ (space_info -> bytes_used + space_info -> bytes_reserved +
6764
+ space_info -> bytes_pinned + space_info -> bytes_readonly +
6765
+ min_free < space_info -> total_bytes )) {
6761
6766
spin_unlock (& space_info -> lock );
6762
6767
goto out ;
6763
6768
}
@@ -6774,9 +6779,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6774
6779
if (full )
6775
6780
goto out ;
6776
6781
6782
+ /*
6783
+ * index:
6784
+ * 0: raid10
6785
+ * 1: raid1
6786
+ * 2: dup
6787
+ * 3: raid0
6788
+ * 4: single
6789
+ */
6790
+ index = get_block_group_index (block_group );
6791
+ if (index == 0 ) {
6792
+ dev_min = 4 ;
6793
+ min_free /= 2 ;
6794
+ } else if (index == 1 ) {
6795
+ dev_min = 2 ;
6796
+ } else if (index == 2 ) {
6797
+ min_free *= 2 ;
6798
+ } else if (index == 3 ) {
6799
+ dev_min = fs_devices -> rw_devices ;
6800
+ min_free /= dev_min ;
6801
+ }
6802
+
6777
6803
mutex_lock (& root -> fs_info -> chunk_mutex );
6778
6804
list_for_each_entry (device , & fs_devices -> alloc_list , dev_alloc_list ) {
6779
- u64 min_free = btrfs_block_group_used (& block_group -> item );
6780
6805
u64 dev_offset ;
6781
6806
6782
6807
/*
@@ -6787,7 +6812,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
6787
6812
ret = find_free_dev_extent (NULL , device , min_free ,
6788
6813
& dev_offset , NULL );
6789
6814
if (!ret )
6815
+ dev_nr ++ ;
6816
+
6817
+ if (dev_nr >= dev_min )
6790
6818
break ;
6819
+
6791
6820
ret = -1 ;
6792
6821
}
6793
6822
}
0 commit comments