* Called when an indirect block above our prefetch target is read in. This * will either read in the next indirect block down the tree or issue the actual * prefetch if the next block down is our target. */
| 3127 | * prefetch if the next block down is our target. |
| 3128 | */ |
| 3129 | static void |
| 3130 | dbuf_prefetch_indirect_done(zio_t *zio, const zbookmark_phys_t *zb, |
| 3131 | const blkptr_t *iobp, arc_buf_t *abuf, void *private) |
| 3132 | { |
| 3133 | dbuf_prefetch_arg_t *dpa = private; |
| 3134 | |
| 3135 | ASSERT3S(dpa->dpa_zb.zb_level, <, dpa->dpa_curlevel); |
| 3136 | ASSERT3S(dpa->dpa_curlevel, >, 0); |
| 3137 | |
| 3138 | if (abuf == NULL) { |
| 3139 | ASSERT(zio == NULL || zio->io_error != 0); |
| 3140 | return (dbuf_prefetch_fini(dpa, B_TRUE)); |
| 3141 | } |
| 3142 | ASSERT(zio == NULL || zio->io_error == 0); |
| 3143 | |
| 3144 | /* |
| 3145 | * The dpa_dnode is only valid if we are called with a NULL |
| 3146 | * zio. This indicates that the arc_read() returned without |
| 3147 | * first calling zio_read() to issue a physical read. Once |
| 3148 | * a physical read is made the dpa_dnode must be invalidated |
| 3149 | * as the locks guarding it may have been dropped. If the |
| 3150 | * dpa_dnode is still valid, then we want to add it to the dbuf |
| 3151 | * cache. To do so, we must hold the dbuf associated with the block |
| 3152 | * we just prefetched, read its contents so that we associate it |
| 3153 | * with an arc_buf_t, and then release it. |
| 3154 | */ |
| 3155 | if (zio != NULL) { |
| 3156 | ASSERT3S(BP_GET_LEVEL(zio->io_bp), ==, dpa->dpa_curlevel); |
| 3157 | if (zio->io_flags & ZIO_FLAG_RAW_COMPRESS) { |
| 3158 | ASSERT3U(BP_GET_PSIZE(zio->io_bp), ==, zio->io_size); |
| 3159 | } else { |
| 3160 | ASSERT3U(BP_GET_LSIZE(zio->io_bp), ==, zio->io_size); |
| 3161 | } |
| 3162 | ASSERT3P(zio->io_spa, ==, dpa->dpa_spa); |
| 3163 | |
| 3164 | dpa->dpa_dnode = NULL; |
| 3165 | } else if (dpa->dpa_dnode != NULL) { |
| 3166 | uint64_t curblkid = dpa->dpa_zb.zb_blkid >> |
| 3167 | (dpa->dpa_epbs * (dpa->dpa_curlevel - |
| 3168 | dpa->dpa_zb.zb_level)); |
| 3169 | dmu_buf_impl_t *db = dbuf_hold_level(dpa->dpa_dnode, |
| 3170 | dpa->dpa_curlevel, curblkid, FTAG); |
| 3171 | if (db == NULL) { |
| 3172 | arc_buf_destroy(abuf, private); |
| 3173 | return (dbuf_prefetch_fini(dpa, B_TRUE)); |
| 3174 | } |
| 3175 | (void) dbuf_read(db, NULL, |
| 3176 | DB_RF_MUST_SUCCEED | DB_RF_NOPREFETCH | DB_RF_HAVESTRUCT); |
| 3177 | dbuf_rele(db, FTAG); |
| 3178 | } |
| 3179 | |
| 3180 | dpa->dpa_curlevel--; |
| 3181 | uint64_t nextblkid = dpa->dpa_zb.zb_blkid >> |
| 3182 | (dpa->dpa_epbs * (dpa->dpa_curlevel - dpa->dpa_zb.zb_level)); |
| 3183 | blkptr_t *bp = ((blkptr_t *)abuf->b_data) + |
| 3184 | P2PHASE(nextblkid, 1ULL << dpa->dpa_epbs); |
| 3185 | |
| 3186 | ASSERT(!BP_IS_REDACTED(bp) || |
nothing calls this directly
no test coverage detected