* Issues TRIM I/Os for all ranges in the provided ta->trim_tree range tree. * Additional parameters describing how the TRIM should be performed must * be set in the trim_args structure. See the trim_args definition for * additional information. */
| 564 | * additional information. |
| 565 | */ |
| 566 | static int |
| 567 | vdev_trim_ranges(trim_args_t *ta) |
| 568 | { |
| 569 | vdev_t *vd = ta->trim_vdev; |
| 570 | zfs_btree_t *t = &ta->trim_tree->rt_root; |
| 571 | zfs_btree_index_t idx; |
| 572 | uint64_t extent_bytes_max = ta->trim_extent_bytes_max; |
| 573 | uint64_t extent_bytes_min = ta->trim_extent_bytes_min; |
| 574 | spa_t *spa = vd->vdev_spa; |
| 575 | |
| 576 | ta->trim_start_time = gethrtime(); |
| 577 | ta->trim_bytes_done = 0; |
| 578 | |
| 579 | for (range_seg_t *rs = zfs_btree_first(t, &idx); rs != NULL; |
| 580 | rs = zfs_btree_next(t, &idx, &idx)) { |
| 581 | uint64_t size = rs_get_end(rs, ta->trim_tree) - rs_get_start(rs, |
| 582 | ta->trim_tree); |
| 583 | |
| 584 | if (extent_bytes_min && size < extent_bytes_min) { |
| 585 | spa_iostats_trim_add(spa, ta->trim_type, |
| 586 | 0, 0, 1, size, 0, 0); |
| 587 | continue; |
| 588 | } |
| 589 | |
| 590 | /* Split range into legally-sized physical chunks */ |
| 591 | uint64_t writes_required = ((size - 1) / extent_bytes_max) + 1; |
| 592 | |
| 593 | for (uint64_t w = 0; w < writes_required; w++) { |
| 594 | int error; |
| 595 | |
| 596 | error = vdev_trim_range(ta, VDEV_LABEL_START_SIZE + |
| 597 | rs_get_start(rs, ta->trim_tree) + |
| 598 | (w *extent_bytes_max), MIN(size - |
| 599 | (w * extent_bytes_max), extent_bytes_max)); |
| 600 | if (error != 0) { |
| 601 | return (error); |
| 602 | } |
| 603 | } |
| 604 | } |
| 605 | |
| 606 | return (0); |
| 607 | } |
| 608 | |
| 609 | static void |
| 610 | vdev_trim_xlate_last_rs_end(void *arg, range_seg64_t *physical_rs) |
no test coverage detected