| 2940 | } |
| 2941 | |
| 2942 | static dmu_buf_impl_t * |
| 2943 | dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid, |
| 2944 | dmu_buf_impl_t *parent, blkptr_t *blkptr) |
| 2945 | { |
| 2946 | objset_t *os = dn->dn_objset; |
| 2947 | dmu_buf_impl_t *db, *odb; |
| 2948 | |
| 2949 | ASSERT(RW_LOCK_HELD(&dn->dn_struct_rwlock)); |
| 2950 | ASSERT(dn->dn_type != DMU_OT_NONE); |
| 2951 | |
| 2952 | db = kmem_cache_alloc(dbuf_kmem_cache, KM_SLEEP); |
| 2953 | |
| 2954 | list_create(&db->db_dirty_records, sizeof (dbuf_dirty_record_t), |
| 2955 | offsetof(dbuf_dirty_record_t, dr_dbuf_node)); |
| 2956 | |
| 2957 | db->db_objset = os; |
| 2958 | db->db.db_object = dn->dn_object; |
| 2959 | db->db_level = level; |
| 2960 | db->db_blkid = blkid; |
| 2961 | db->db_dirtycnt = 0; |
| 2962 | db->db_dnode_handle = dn->dn_handle; |
| 2963 | db->db_parent = parent; |
| 2964 | db->db_blkptr = blkptr; |
| 2965 | |
| 2966 | db->db_user = NULL; |
| 2967 | db->db_user_immediate_evict = FALSE; |
| 2968 | db->db_freed_in_flight = FALSE; |
| 2969 | db->db_pending_evict = FALSE; |
| 2970 | |
| 2971 | if (blkid == DMU_BONUS_BLKID) { |
| 2972 | ASSERT3P(parent, ==, dn->dn_dbuf); |
| 2973 | db->db.db_size = DN_SLOTS_TO_BONUSLEN(dn->dn_num_slots) - |
| 2974 | (dn->dn_nblkptr-1) * sizeof (blkptr_t); |
| 2975 | ASSERT3U(db->db.db_size, >=, dn->dn_bonuslen); |
| 2976 | db->db.db_offset = DMU_BONUS_BLKID; |
| 2977 | db->db_state = DB_UNCACHED; |
| 2978 | DTRACE_SET_STATE(db, "bonus buffer created"); |
| 2979 | db->db_caching_status = DB_NO_CACHE; |
| 2980 | /* the bonus dbuf is not placed in the hash table */ |
| 2981 | arc_space_consume(sizeof (dmu_buf_impl_t), ARC_SPACE_DBUF); |
| 2982 | return (db); |
| 2983 | } else if (blkid == DMU_SPILL_BLKID) { |
| 2984 | db->db.db_size = (blkptr != NULL) ? |
| 2985 | BP_GET_LSIZE(blkptr) : SPA_MINBLOCKSIZE; |
| 2986 | db->db.db_offset = 0; |
| 2987 | } else { |
| 2988 | int blocksize = |
| 2989 | db->db_level ? 1 << dn->dn_indblkshift : dn->dn_datablksz; |
| 2990 | db->db.db_size = blocksize; |
| 2991 | db->db.db_offset = db->db_blkid * blocksize; |
| 2992 | } |
| 2993 | |
| 2994 | /* |
| 2995 | * Hold the dn_dbufs_mtx while we get the new dbuf |
| 2996 | * in the hash table *and* added to the dbufs list. |
| 2997 | * This prevents a possible deadlock with someone |
| 2998 | * trying to look up this dbuf before it's added to the |
| 2999 | * dn_dbufs list. |
no test coverage detected