* Update the on-disk state of a manual TRIM. This is called to request * that a TRIM be started/suspended/canceled, or to change one of the * TRIM options (partial, secure, rate). */
| 266 | * TRIM options (partial, secure, rate). |
| 267 | */ |
| 268 | static void |
| 269 | vdev_trim_change_state(vdev_t *vd, vdev_trim_state_t new_state, |
| 270 | uint64_t rate, boolean_t partial, boolean_t secure) |
| 271 | { |
| 272 | ASSERT(MUTEX_HELD(&vd->vdev_trim_lock)); |
| 273 | spa_t *spa = vd->vdev_spa; |
| 274 | |
| 275 | if (new_state == vd->vdev_trim_state) |
| 276 | return; |
| 277 | |
| 278 | /* |
| 279 | * Copy the vd's guid, this will be freed by the sync task. |
| 280 | */ |
| 281 | uint64_t *guid = kmem_zalloc(sizeof (uint64_t), KM_SLEEP); |
| 282 | *guid = vd->vdev_guid; |
| 283 | |
| 284 | /* |
| 285 | * If we're suspending, then preserve the original start time. |
| 286 | */ |
| 287 | if (vd->vdev_trim_state != VDEV_TRIM_SUSPENDED) { |
| 288 | vd->vdev_trim_action_time = gethrestime_sec(); |
| 289 | } |
| 290 | |
| 291 | /* |
| 292 | * If we're activating, then preserve the requested rate and trim |
| 293 | * method. Setting the last offset and rate to UINT64_MAX is used |
| 294 | * as a sentinel to indicate they should be reset to default values. |
| 295 | */ |
| 296 | if (new_state == VDEV_TRIM_ACTIVE) { |
| 297 | if (vd->vdev_trim_state == VDEV_TRIM_COMPLETE || |
| 298 | vd->vdev_trim_state == VDEV_TRIM_CANCELED) { |
| 299 | vd->vdev_trim_last_offset = UINT64_MAX; |
| 300 | vd->vdev_trim_rate = UINT64_MAX; |
| 301 | vd->vdev_trim_partial = UINT64_MAX; |
| 302 | vd->vdev_trim_secure = UINT64_MAX; |
| 303 | } |
| 304 | |
| 305 | if (rate != 0) |
| 306 | vd->vdev_trim_rate = rate; |
| 307 | |
| 308 | if (partial != 0) |
| 309 | vd->vdev_trim_partial = partial; |
| 310 | |
| 311 | if (secure != 0) |
| 312 | vd->vdev_trim_secure = secure; |
| 313 | } |
| 314 | |
| 315 | vdev_trim_state_t old_state = vd->vdev_trim_state; |
| 316 | boolean_t resumed = (old_state == VDEV_TRIM_SUSPENDED); |
| 317 | vd->vdev_trim_state = new_state; |
| 318 | |
| 319 | dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir); |
| 320 | VERIFY0(dmu_tx_assign(tx, TXG_WAIT)); |
| 321 | dsl_sync_task_nowait(spa_get_dsl(spa), vdev_trim_zap_update_sync, |
| 322 | guid, tx); |
| 323 | |
| 324 | switch (new_state) { |
| 325 | case VDEV_TRIM_ACTIVE: |
no test coverage detected