| 3848 | } |
| 3849 | |
| 3850 | static void |
| 3851 | dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db) |
| 3852 | { |
| 3853 | /* ASSERT(dmu_tx_is_syncing(tx) */ |
| 3854 | ASSERT(MUTEX_HELD(&db->db_mtx)); |
| 3855 | |
| 3856 | if (db->db_blkptr != NULL) |
| 3857 | return; |
| 3858 | |
| 3859 | if (db->db_blkid == DMU_SPILL_BLKID) { |
| 3860 | db->db_blkptr = DN_SPILL_BLKPTR(dn->dn_phys); |
| 3861 | BP_ZERO(db->db_blkptr); |
| 3862 | return; |
| 3863 | } |
| 3864 | if (db->db_level == dn->dn_phys->dn_nlevels-1) { |
| 3865 | /* |
| 3866 | * This buffer was allocated at a time when there was |
| 3867 | * no available blkptrs from the dnode, or it was |
| 3868 | * inappropriate to hook it in (i.e., nlevels mismatch). |
| 3869 | */ |
| 3870 | ASSERT(db->db_blkid < dn->dn_phys->dn_nblkptr); |
| 3871 | ASSERT(db->db_parent == NULL); |
| 3872 | db->db_parent = dn->dn_dbuf; |
| 3873 | db->db_blkptr = &dn->dn_phys->dn_blkptr[db->db_blkid]; |
| 3874 | DBUF_VERIFY(db); |
| 3875 | } else { |
| 3876 | dmu_buf_impl_t *parent = db->db_parent; |
| 3877 | int epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT; |
| 3878 | |
| 3879 | ASSERT(dn->dn_phys->dn_nlevels > 1); |
| 3880 | if (parent == NULL) { |
| 3881 | mutex_exit(&db->db_mtx); |
| 3882 | rw_enter(&dn->dn_struct_rwlock, RW_READER); |
| 3883 | parent = dbuf_hold_level(dn, db->db_level + 1, |
| 3884 | db->db_blkid >> epbs, db); |
| 3885 | rw_exit(&dn->dn_struct_rwlock); |
| 3886 | mutex_enter(&db->db_mtx); |
| 3887 | db->db_parent = parent; |
| 3888 | } |
| 3889 | db->db_blkptr = (blkptr_t *)parent->db.db_data + |
| 3890 | (db->db_blkid & ((1ULL << epbs) - 1)); |
| 3891 | DBUF_VERIFY(db); |
| 3892 | } |
| 3893 | } |
| 3894 | |
| 3895 | static void |
| 3896 | dbuf_sync_bonus(dbuf_dirty_record_t *dr, dmu_tx_t *tx) |
no test coverage detected