mirror of https://github.com/openzfs/zfs.git
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 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_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,
|
extern inline void dmu_buf_init_user(dmu_buf_user_t *dbu,
|
||||||
dmu_buf_evict_func_t *evict_func_sync,
|
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);
|
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
|
* Undirty a buffer in the transaction group referenced by the given
|
||||||
* transaction. Return whether this evicted the dbuf.
|
* 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
|
* When syncing out a blocks of dnodes, adjust the block to deal with
|
||||||
* encryption. Normally, we make sure the block is decrypted before writing
|
* 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);
|
zio_nowait(zio);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ZFS_DEBUG
|
|
||||||
/*
|
/*
|
||||||
* Verify that the size of the data in our bonus buffer does not exceed
|
* Verify that the size of the data in our bonus buffer does not exceed
|
||||||
* its recorded size.
|
* its recorded size.
|
||||||
|
@ -3852,6 +3900,7 @@ dbuf_sync_indirect(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
||||||
static void
|
static void
|
||||||
dbuf_sync_leaf_verify_bonus_dnode(dbuf_dirty_record_t *dr)
|
dbuf_sync_leaf_verify_bonus_dnode(dbuf_dirty_record_t *dr)
|
||||||
{
|
{
|
||||||
|
#ifdef ZFS_DEBUG
|
||||||
dnode_t *dn = DB_DNODE(dr->dr_dbuf);
|
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 */
|
/* ensure that everything is zero after our data */
|
||||||
for (; datap_end < datap_max; datap_end++)
|
for (; datap_end < datap_max; datap_end++)
|
||||||
ASSERT(*datap_end == 0);
|
ASSERT(*datap_end == 0);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dbuf_sync_leaf() is called recursively from dbuf_sync_list() so it is
|
* 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).
|
* be called).
|
||||||
*/
|
*/
|
||||||
if (db->db_blkid == DMU_BONUS_BLKID) {
|
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);
|
ASSERT(dr->dr_dbuf == db);
|
||||||
list_remove(&db->db_dirty_records, dr);
|
dbuf_sync_bonus(dr, tx);
|
||||||
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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue