summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorMatthew Macy <[email protected]>2020-02-07 14:22:29 -0800
committerGitHub <[email protected]>2020-02-07 14:22:29 -0800
commitfa3922df75d722724dd51819cb49da0418d054f5 (patch)
treec6b9230d766aa783d25c42108815f7d51739e02e /module/zfs
parent818d4a87fd59ddbacc8ae0c8b67eb1577ca9b069 (diff)
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 <[email protected]> Reviewed-by: Matt Ahrens <[email protected]> Signed-off-by: Matt Macy <[email protected]> Closes #9909
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/dbuf.c83
1 files changed, 52 insertions, 31 deletions
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c
index 04fc2f7cd..02478605f 100644
--- a/module/zfs/dbuf.c
+++ b/module/zfs/dbuf.c
@@ -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;
}