MCPcopy Create free account
hub / github.com/F-Stack/f-stack / spa_vdev_copy_segment

Function spa_vdev_copy_segment

freebsd/contrib/openzfs/module/zfs/vdev_removal.c:948–1079  ·  view source on GitHub ↗

* 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. */

Source from the content-addressed store, hash-verified

946 * read from the old location and write to the new location.
947 */
948static int
949spa_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);

Callers 1

spa_vdev_copy_implFunction · 0.85

Calls 15

range_tree_minFunction · 0.85
range_tree_spanFunction · 0.85
rs_set_startFunction · 0.85
rs_set_endFunction · 0.85
zfs_btree_findFunction · 0.85
zfs_btree_prevFunction · 0.85
rs_get_endFunction · 0.85
spa_normal_classFunction · 0.85
metaslab_alloc_dvaFunction · 0.85
range_tree_createFunction · 0.85
zfs_btree_firstFunction · 0.85
rs_get_startFunction · 0.85

Tested by

no test coverage detected