* Read data from the cache. Returns B_TRUE cache hit, B_FALSE on miss. */
| 248 | * Read data from the cache. Returns B_TRUE cache hit, B_FALSE on miss. |
| 249 | */ |
| 250 | boolean_t |
| 251 | vdev_cache_read(zio_t *zio) |
| 252 | { |
| 253 | vdev_cache_t *vc = &zio->io_vd->vdev_cache; |
| 254 | vdev_cache_entry_t *ve, *ve_search; |
| 255 | uint64_t cache_offset = P2ALIGN(zio->io_offset, VCBS); |
| 256 | zio_t *fio; |
| 257 | uint64_t cache_phase __maybe_unused = P2PHASE(zio->io_offset, VCBS); |
| 258 | |
| 259 | ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ); |
| 260 | |
| 261 | if (zio->io_flags & ZIO_FLAG_DONT_CACHE) |
| 262 | return (B_FALSE); |
| 263 | |
| 264 | if (zio->io_size > zfs_vdev_cache_max) |
| 265 | return (B_FALSE); |
| 266 | |
| 267 | /* |
| 268 | * If the I/O straddles two or more cache blocks, don't cache it. |
| 269 | */ |
| 270 | if (P2BOUNDARY(zio->io_offset, zio->io_size, VCBS)) |
| 271 | return (B_FALSE); |
| 272 | |
| 273 | ASSERT3U(cache_phase + zio->io_size, <=, VCBS); |
| 274 | |
| 275 | mutex_enter(&vc->vc_lock); |
| 276 | |
| 277 | ve_search = kmem_alloc(sizeof (vdev_cache_entry_t), KM_SLEEP); |
| 278 | ve_search->ve_offset = cache_offset; |
| 279 | ve = avl_find(&vc->vc_offset_tree, ve_search, NULL); |
| 280 | kmem_free(ve_search, sizeof (vdev_cache_entry_t)); |
| 281 | |
| 282 | if (ve != NULL) { |
| 283 | if (ve->ve_missed_update) { |
| 284 | mutex_exit(&vc->vc_lock); |
| 285 | return (B_FALSE); |
| 286 | } |
| 287 | |
| 288 | if ((fio = ve->ve_fill_io) != NULL) { |
| 289 | zio_vdev_io_bypass(zio); |
| 290 | zio_add_child(zio, fio); |
| 291 | mutex_exit(&vc->vc_lock); |
| 292 | VDCSTAT_BUMP(vdc_stat_delegations); |
| 293 | return (B_TRUE); |
| 294 | } |
| 295 | |
| 296 | vdev_cache_hit(vc, ve, zio); |
| 297 | zio_vdev_io_bypass(zio); |
| 298 | |
| 299 | mutex_exit(&vc->vc_lock); |
| 300 | VDCSTAT_BUMP(vdc_stat_hits); |
| 301 | return (B_TRUE); |
| 302 | } |
| 303 | |
| 304 | ve = vdev_cache_allocate(zio); |
| 305 | |
| 306 | if (ve == NULL) { |
| 307 | mutex_exit(&vc->vc_lock); |
no test coverage detected