Factor out dbuf_sync_bonus
Factor the portion of dbuf_sync_leaf() responsible for handling bonus buffers out in to its own dbuf_sync_bonus() helper function. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Matt Ahrens <matt@delphix.com> Signed-off-by: Matt Macy <mmacy@FreeBSD.org> Closes #9909
This commit is contained in:
parent
818d4a87fd
commit
fa3922df75
|
@ -150,6 +150,7 @@ dbuf_stats_t dbuf_stats = {
|
|||
|
||||
static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
|
||||
static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx);
|
||||
static void dbuf_sync_leaf_verify_bonus_dnode(dbuf_dirty_record_t *dr);
|
||||
|
||||
extern inline void dmu_buf_init_user(dmu_buf_user_t *dbu,
|
||||
dmu_buf_evict_func_t *evict_func_sync,
|
||||
|
@ -2210,6 +2211,30 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
|||
return (dr);
|
||||
}
|
||||
|
||||
static void
|
||||
dbuf_undirty_bonus(dbuf_dirty_record_t *dr)
|
||||
{
|
||||
dmu_buf_impl_t *db = dr->dr_dbuf;
|
||||
|
||||
if (dr->dt.dl.dr_data != db->db.db_data) {
|
||||
struct dnode *dn = DB_DNODE(db);
|
||||
int max_bonuslen = DN_SLOTS_TO_BONUSLEN(dn->dn_num_slots);
|
||||
|
||||
kmem_free(dr->dt.dl.dr_data, max_bonuslen);
|
||||
arc_space_return(max_bonuslen, ARC_SPACE_BONUS);
|
||||
}
|
||||
db->db_data_pending = NULL;
|
||||
ASSERT(list_next(&db->db_dirty_records, dr) == NULL);
|
||||
list_remove(&db->db_dirty_records, dr);
|
||||
if (dr->dr_dbuf->db_level != 0) {
|
||||
mutex_destroy(&dr->dt.di.dr_mtx);
|
||||
list_destroy(&dr->dt.di.dr_children);
|
||||
}
|
||||
kmem_free(dr, sizeof (dbuf_dirty_record_t));
|
||||
ASSERT3U(db->db_dirtycnt, >, 0);
|
||||
db->db_dirtycnt -= 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Undirty a buffer in the transaction group referenced by the given
|
||||
* transaction. Return whether this evicted the dbuf.
|
||||
|
@ -3741,6 +3766,30 @@ dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dbuf_sync_bonus(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
||||
{
|
||||
dmu_buf_impl_t *db = dr->dr_dbuf;
|
||||
void *data = dr->dt.dl.dr_data;
|
||||
|
||||
ASSERT0(db->db_level);
|
||||
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||
ASSERT(DB_DNODE_HELD(db));
|
||||
ASSERT(db->db_blkid == DMU_BONUS_BLKID);
|
||||
ASSERT(data != NULL);
|
||||
|
||||
dnode_t *dn = DB_DNODE(db);
|
||||
ASSERT3U(DN_MAX_BONUS_LEN(dn->dn_phys), <=,
|
||||
DN_SLOTS_TO_BONUSLEN(dn->dn_phys->dn_extra_slots + 1));
|
||||
bcopy(data, DN_BONUS(dn->dn_phys), DN_MAX_BONUS_LEN(dn->dn_phys));
|
||||
DB_DNODE_EXIT(db);
|
||||
|
||||
dbuf_sync_leaf_verify_bonus_dnode(dr);
|
||||
|
||||
dbuf_undirty_bonus(dr);
|
||||
dbuf_rele_and_unlock(db, (void *)(uintptr_t)tx->tx_txg, B_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* When syncing out a blocks of dnodes, adjust the block to deal with
|
||||
* encryption. Normally, we make sure the block is decrypted before writing
|
||||
|
@ -3835,7 +3884,6 @@ dbuf_sync_indirect(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
|||
zio_nowait(zio);
|
||||
}
|
||||
|
||||
#ifdef ZFS_DEBUG
|
||||
/*
|
||||
* Verify that the size of the data in our bonus buffer does not exceed
|
||||
* its recorded size.
|
||||
|
@ -3852,6 +3900,7 @@ dbuf_sync_indirect(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
|||
static void
|
||||
dbuf_sync_leaf_verify_bonus_dnode(dbuf_dirty_record_t *dr)
|
||||
{
|
||||
#ifdef ZFS_DEBUG
|
||||
dnode_t *dn = DB_DNODE(dr->dr_dbuf);
|
||||
|
||||
/*
|
||||
|
@ -3872,8 +3921,8 @@ dbuf_sync_leaf_verify_bonus_dnode(dbuf_dirty_record_t *dr)
|
|||
/* ensure that everything is zero after our data */
|
||||
for (; datap_end < datap_max; datap_end++)
|
||||
ASSERT(*datap_end == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* dbuf_sync_leaf() is called recursively from dbuf_sync_list() so it is
|
||||
|
@ -3941,36 +3990,8 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
|||
* be called).
|
||||
*/
|
||||
if (db->db_blkid == DMU_BONUS_BLKID) {
|
||||
ASSERT(*datap != NULL);
|
||||
ASSERT0(db->db_level);
|
||||
ASSERT3U(DN_MAX_BONUS_LEN(dn->dn_phys), <=,
|
||||
DN_SLOTS_TO_BONUSLEN(dn->dn_phys->dn_extra_slots + 1));
|
||||
bcopy(*datap, DN_BONUS(dn->dn_phys),
|
||||
DN_MAX_BONUS_LEN(dn->dn_phys));
|
||||
DB_DNODE_EXIT(db);
|
||||
|
||||
#ifdef ZFS_DEBUG
|
||||
dbuf_sync_leaf_verify_bonus_dnode(dr);
|
||||
#endif
|
||||
|
||||
if (*datap != db->db.db_data) {
|
||||
int slots = DB_DNODE(db)->dn_num_slots;
|
||||
int bonuslen = DN_SLOTS_TO_BONUSLEN(slots);
|
||||
kmem_free(*datap, bonuslen);
|
||||
arc_space_return(bonuslen, ARC_SPACE_BONUS);
|
||||
}
|
||||
db->db_data_pending = NULL;
|
||||
ASSERT(list_next(&db->db_dirty_records, dr) == NULL);
|
||||
ASSERT(dr->dr_dbuf == db);
|
||||
list_remove(&db->db_dirty_records, dr);
|
||||
if (dr->dr_dbuf->db_level != 0) {
|
||||
mutex_destroy(&dr->dt.di.dr_mtx);
|
||||
list_destroy(&dr->dt.di.dr_children);
|
||||
}
|
||||
kmem_free(dr, sizeof (dbuf_dirty_record_t));
|
||||
ASSERT(db->db_dirtycnt > 0);
|
||||
db->db_dirtycnt -= 1;
|
||||
dbuf_rele_and_unlock(db, (void *)(uintptr_t)txg, B_FALSE);
|
||||
dbuf_sync_bonus(dr, tx);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue