| 4295 | } |
| 4296 | |
| 4297 | void |
| 4298 | vdev_stat_update(zio_t *zio, uint64_t psize) |
| 4299 | { |
| 4300 | spa_t *spa = zio->io_spa; |
| 4301 | vdev_t *rvd = spa->spa_root_vdev; |
| 4302 | vdev_t *vd = zio->io_vd ? zio->io_vd : rvd; |
| 4303 | vdev_t *pvd; |
| 4304 | uint64_t txg = zio->io_txg; |
| 4305 | vdev_stat_t *vs = &vd->vdev_stat; |
| 4306 | vdev_stat_ex_t *vsx = &vd->vdev_stat_ex; |
| 4307 | zio_type_t type = zio->io_type; |
| 4308 | int flags = zio->io_flags; |
| 4309 | |
| 4310 | /* |
| 4311 | * If this i/o is a gang leader, it didn't do any actual work. |
| 4312 | */ |
| 4313 | if (zio->io_gang_tree) |
| 4314 | return; |
| 4315 | |
| 4316 | if (zio->io_error == 0) { |
| 4317 | /* |
| 4318 | * If this is a root i/o, don't count it -- we've already |
| 4319 | * counted the top-level vdevs, and vdev_get_stats() will |
| 4320 | * aggregate them when asked. This reduces contention on |
| 4321 | * the root vdev_stat_lock and implicitly handles blocks |
| 4322 | * that compress away to holes, for which there is no i/o. |
| 4323 | * (Holes never create vdev children, so all the counters |
| 4324 | * remain zero, which is what we want.) |
| 4325 | * |
| 4326 | * Note: this only applies to successful i/o (io_error == 0) |
| 4327 | * because unlike i/o counts, errors are not additive. |
| 4328 | * When reading a ditto block, for example, failure of |
| 4329 | * one top-level vdev does not imply a root-level error. |
| 4330 | */ |
| 4331 | if (vd == rvd) |
| 4332 | return; |
| 4333 | |
| 4334 | ASSERT(vd == zio->io_vd); |
| 4335 | |
| 4336 | if (flags & ZIO_FLAG_IO_BYPASS) |
| 4337 | return; |
| 4338 | |
| 4339 | mutex_enter(&vd->vdev_stat_lock); |
| 4340 | |
| 4341 | if (flags & ZIO_FLAG_IO_REPAIR) { |
| 4342 | /* |
| 4343 | * Repair is the result of a resilver issued by the |
| 4344 | * scan thread (spa_sync). |
| 4345 | */ |
| 4346 | if (flags & ZIO_FLAG_SCAN_THREAD) { |
| 4347 | dsl_scan_t *scn = spa->spa_dsl_pool->dp_scan; |
| 4348 | dsl_scan_phys_t *scn_phys = &scn->scn_phys; |
| 4349 | uint64_t *processed = &scn_phys->scn_processed; |
| 4350 | |
| 4351 | if (vd->vdev_ops->vdev_op_leaf) |
| 4352 | atomic_add_64(processed, psize); |
| 4353 | vs->vs_scan_processed += psize; |
| 4354 | } |
no test coverage detected