MCPcopy Create free account
hub / github.com/F-Stack/f-stack / dbuf_prefetch_impl

Function dbuf_prefetch_impl

freebsd/contrib/openzfs/module/zfs/dbuf.c:3224–3358  ·  view source on GitHub ↗

* Issue prefetch reads for the given block on the given level. If the indirect * blocks above that block are not in memory, we will read them in * asynchronously. As a result, this call never blocks waiting for a read to * complete. Note that the prefetch might fail if the dataset is encrypted and * the encryption key is unmapped before the IO completes. */

Source from the content-addressed store, hash-verified

3222 * the encryption key is unmapped before the IO completes.
3223 */
3224int
3225dbuf_prefetch_impl(dnode_t *dn, int64_t level, uint64_t blkid,
3226 zio_priority_t prio, arc_flags_t aflags, dbuf_prefetch_fn cb,
3227 void *arg)
3228{
3229 blkptr_t bp;
3230 int epbs, nlevels, curlevel;
3231 uint64_t curblkid;
3232
3233 ASSERT(blkid != DMU_BONUS_BLKID);
3234 ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
3235
3236 if (blkid > dn->dn_maxblkid)
3237 goto no_issue;
3238
3239 if (level == 0 && dnode_block_freed(dn, blkid))
3240 goto no_issue;
3241
3242 /*
3243 * This dnode hasn't been written to disk yet, so there's nothing to
3244 * prefetch.
3245 */
3246 nlevels = dn->dn_phys->dn_nlevels;
3247 if (level >= nlevels || dn->dn_phys->dn_nblkptr == 0)
3248 goto no_issue;
3249
3250 epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT;
3251 if (dn->dn_phys->dn_maxblkid < blkid << (epbs * level))
3252 goto no_issue;
3253
3254 dmu_buf_impl_t *db = dbuf_find(dn->dn_objset, dn->dn_object,
3255 level, blkid);
3256 if (db != NULL) {
3257 mutex_exit(&db->db_mtx);
3258 /*
3259 * This dbuf already exists. It is either CACHED, or
3260 * (we assume) about to be read or filled.
3261 */
3262 goto no_issue;
3263 }
3264
3265 /*
3266 * Find the closest ancestor (indirect block) of the target block
3267 * that is present in the cache. In this indirect block, we will
3268 * find the bp that is at curlevel, curblkid.
3269 */
3270 curlevel = level;
3271 curblkid = blkid;
3272 while (curlevel < nlevels - 1) {
3273 int parent_level = curlevel + 1;
3274 uint64_t parent_blkid = curblkid >> epbs;
3275 dmu_buf_impl_t *db;
3276
3277 if (dbuf_hold_impl(dn, parent_level, parent_blkid,
3278 FALSE, TRUE, FTAG, &db) == 0) {
3279 blkptr_t *bpp = db->db_buf->b_data;
3280 bp = bpp[P2PHASE(curblkid, 1 << epbs)];
3281 dbuf_rele(db, FTAG);

Callers 2

dmu_zfetchFunction · 0.85
dbuf_prefetchFunction · 0.85

Calls 12

RW_LOCK_HELDFunction · 0.85
dnode_block_freedFunction · 0.85
dbuf_findFunction · 0.85
mutex_exitFunction · 0.85
dbuf_hold_implFunction · 0.85
dbuf_releFunction · 0.85
zio_rootFunction · 0.85
dmu_objset_spaFunction · 0.85
arc_readFunction · 0.85
zio_nowaitFunction · 0.85

Tested by

no test coverage detected