* Allocate a new location for this segment, and create the zio_t's to * read from the old location and write to the new location. */
| 946 | * read from the old location and write to the new location. |
| 947 | */ |
| 948 | static int |
| 949 | spa_vdev_copy_segment(vdev_t *vd, range_tree_t *segs, |
| 950 | uint64_t maxalloc, uint64_t txg, |
| 951 | vdev_copy_arg_t *vca, zio_alloc_list_t *zal) |
| 952 | { |
| 953 | metaslab_group_t *mg = vd->vdev_mg; |
| 954 | spa_t *spa = vd->vdev_spa; |
| 955 | spa_vdev_removal_t *svr = spa->spa_vdev_removal; |
| 956 | vdev_indirect_mapping_entry_t *entry; |
| 957 | dva_t dst = {{ 0 }}; |
| 958 | uint64_t start = range_tree_min(segs); |
| 959 | ASSERT0(P2PHASE(start, 1 << spa->spa_min_ashift)); |
| 960 | |
| 961 | ASSERT3U(maxalloc, <=, SPA_MAXBLOCKSIZE); |
| 962 | ASSERT0(P2PHASE(maxalloc, 1 << spa->spa_min_ashift)); |
| 963 | |
| 964 | uint64_t size = range_tree_span(segs); |
| 965 | if (range_tree_span(segs) > maxalloc) { |
| 966 | /* |
| 967 | * We can't allocate all the segments. Prefer to end |
| 968 | * the allocation at the end of a segment, thus avoiding |
| 969 | * additional split blocks. |
| 970 | */ |
| 971 | range_seg_max_t search; |
| 972 | zfs_btree_index_t where; |
| 973 | rs_set_start(&search, segs, start + maxalloc); |
| 974 | rs_set_end(&search, segs, start + maxalloc); |
| 975 | (void) zfs_btree_find(&segs->rt_root, &search, &where); |
| 976 | range_seg_t *rs = zfs_btree_prev(&segs->rt_root, &where, |
| 977 | &where); |
| 978 | if (rs != NULL) { |
| 979 | size = rs_get_end(rs, segs) - start; |
| 980 | } else { |
| 981 | /* |
| 982 | * There are no segments that end before maxalloc. |
| 983 | * I.e. the first segment is larger than maxalloc, |
| 984 | * so we must split it. |
| 985 | */ |
| 986 | size = maxalloc; |
| 987 | } |
| 988 | } |
| 989 | ASSERT3U(size, <=, maxalloc); |
| 990 | ASSERT0(P2PHASE(size, 1 << spa->spa_min_ashift)); |
| 991 | |
| 992 | /* |
| 993 | * An allocation class might not have any remaining vdevs or space |
| 994 | */ |
| 995 | metaslab_class_t *mc = mg->mg_class; |
| 996 | if (mc->mc_groups == 0) |
| 997 | mc = spa_normal_class(spa); |
| 998 | int error = metaslab_alloc_dva(spa, mc, size, &dst, 0, NULL, txg, 0, |
| 999 | zal, 0); |
| 1000 | if (error == ENOSPC && mc != spa_normal_class(spa)) { |
| 1001 | error = metaslab_alloc_dva(spa, spa_normal_class(spa), size, |
| 1002 | &dst, 0, NULL, txg, 0, zal, 0); |
| 1003 | } |
| 1004 | if (error != 0) |
| 1005 | return (error); |
no test coverage detected