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

Function dnode_next_offset_level

freebsd/contrib/openzfs/module/zfs/dnode.c:2363–2491  ·  view source on GitHub ↗

* Scans a block at the indicated "level" looking for a hole or data, * depending on 'flags'. * * If level > 0, then we are scanning an indirect block looking at its * pointers. If level == 0, then we are looking at a block of dnodes. * * If we don't find what we are looking for in the block, we return ESRCH. * Otherwise, return with *offset pointing to the beginning (if searching * forwar

Source from the content-addressed store, hash-verified

2361 * level.
2362 */
2363static int
2364dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
2365 int lvl, uint64_t blkfill, uint64_t txg)
2366{
2367 dmu_buf_impl_t *db = NULL;
2368 void *data = NULL;
2369 uint64_t epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT;
2370 uint64_t epb = 1ULL << epbs;
2371 uint64_t minfill, maxfill;
2372 boolean_t hole;
2373 int i, inc, error, span;
2374
2375 ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock));
2376
2377 hole = ((flags & DNODE_FIND_HOLE) != 0);
2378 inc = (flags & DNODE_FIND_BACKWARDS) ? -1 : 1;
2379 ASSERT(txg == 0 || !hole);
2380
2381 if (lvl == dn->dn_phys->dn_nlevels) {
2382 error = 0;
2383 epb = dn->dn_phys->dn_nblkptr;
2384 data = dn->dn_phys->dn_blkptr;
2385 } else {
2386 uint64_t blkid = dbuf_whichblock(dn, lvl, *offset);
2387 error = dbuf_hold_impl(dn, lvl, blkid, TRUE, FALSE, FTAG, &db);
2388 if (error) {
2389 if (error != ENOENT)
2390 return (error);
2391 if (hole)
2392 return (0);
2393 /*
2394 * This can only happen when we are searching up
2395 * the block tree for data. We don't really need to
2396 * adjust the offset, as we will just end up looking
2397 * at the pointer to this block in its parent, and its
2398 * going to be unallocated, so we will skip over it.
2399 */
2400 return (SET_ERROR(ESRCH));
2401 }
2402 error = dbuf_read(db, NULL,
2403 DB_RF_CANFAIL | DB_RF_HAVESTRUCT |
2404 DB_RF_NO_DECRYPT | DB_RF_NOPREFETCH);
2405 if (error) {
2406 dbuf_rele(db, FTAG);
2407 return (error);
2408 }
2409 data = db->db.db_data;
2410 rw_enter(&db->db_rwlock, RW_READER);
2411 }
2412
2413 if (db != NULL && txg != 0 && (db->db_blkptr == NULL ||
2414 db->db_blkptr->blk_birth <= txg ||
2415 BP_IS_HOLE(db->db_blkptr))) {
2416 /*
2417 * This can only happen when we are searching up the tree
2418 * and these conditions mean that we need to keep climbing.
2419 */
2420 error = SET_ERROR(ESRCH);

Callers 1

dnode_next_offsetFunction · 0.85

Calls 7

RW_LOCK_HELDFunction · 0.85
dbuf_whichblockFunction · 0.85
dbuf_hold_implFunction · 0.85
dbuf_readFunction · 0.85
dbuf_releFunction · 0.85
rw_enterFunction · 0.85
rw_exitFunction · 0.85

Tested by

no test coverage detected