* Returns with db_holds incremented, and db_mtx not held. * Note: dn_struct_rwlock must be held. */
| 3391 | * Note: dn_struct_rwlock must be held. |
| 3392 | */ |
| 3393 | int |
| 3394 | dbuf_hold_impl(dnode_t *dn, uint8_t level, uint64_t blkid, |
| 3395 | boolean_t fail_sparse, boolean_t fail_uncached, |
| 3396 | void *tag, dmu_buf_impl_t **dbp) |
| 3397 | { |
| 3398 | dmu_buf_impl_t *db, *parent = NULL; |
| 3399 | |
| 3400 | /* If the pool has been created, verify the tx_sync_lock is not held */ |
| 3401 | spa_t *spa = dn->dn_objset->os_spa; |
| 3402 | dsl_pool_t *dp = spa->spa_dsl_pool; |
| 3403 | if (dp != NULL) { |
| 3404 | ASSERT(!MUTEX_HELD(&dp->dp_tx.tx_sync_lock)); |
| 3405 | } |
| 3406 | |
| 3407 | ASSERT(blkid != DMU_BONUS_BLKID); |
| 3408 | ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock)); |
| 3409 | ASSERT3U(dn->dn_nlevels, >, level); |
| 3410 | |
| 3411 | *dbp = NULL; |
| 3412 | |
| 3413 | /* dbuf_find() returns with db_mtx held */ |
| 3414 | db = dbuf_find(dn->dn_objset, dn->dn_object, level, blkid); |
| 3415 | |
| 3416 | if (db == NULL) { |
| 3417 | blkptr_t *bp = NULL; |
| 3418 | int err; |
| 3419 | |
| 3420 | if (fail_uncached) |
| 3421 | return (SET_ERROR(ENOENT)); |
| 3422 | |
| 3423 | ASSERT3P(parent, ==, NULL); |
| 3424 | err = dbuf_findbp(dn, level, blkid, fail_sparse, &parent, &bp); |
| 3425 | if (fail_sparse) { |
| 3426 | if (err == 0 && bp && BP_IS_HOLE(bp)) |
| 3427 | err = SET_ERROR(ENOENT); |
| 3428 | if (err) { |
| 3429 | if (parent) |
| 3430 | dbuf_rele(parent, NULL); |
| 3431 | return (err); |
| 3432 | } |
| 3433 | } |
| 3434 | if (err && err != ENOENT) |
| 3435 | return (err); |
| 3436 | db = dbuf_create(dn, level, blkid, parent, bp); |
| 3437 | } |
| 3438 | |
| 3439 | if (fail_uncached && db->db_state != DB_CACHED) { |
| 3440 | mutex_exit(&db->db_mtx); |
| 3441 | return (SET_ERROR(ENOENT)); |
| 3442 | } |
| 3443 | |
| 3444 | if (db->db_buf != NULL) { |
| 3445 | arc_buf_access(db->db_buf); |
| 3446 | ASSERT3P(db->db.db_data, ==, db->db_buf->b_data); |
| 3447 | } |
| 3448 | |
| 3449 | ASSERT(db->db_buf == NULL || arc_referenced(db->db_buf)); |
| 3450 |
no test coverage detected