diff --git a/.topmsg b/.topmsg index 9fa80353b8..7980cebd4d 100644 --- a/.topmsg +++ b/.topmsg @@ -5,4 +5,9 @@ Remove all instances of list handling where the API is not used and instead list data members are directly accessed. Doing this sort of thing is bad for portability. +Additionally, ensure that list_link_init() is called on newly +created list nodes. This ensures the node is properly initialized +and does not rely on the assumption that zero'ing the list_node_t +via kmem_zalloc() is the same as proper initialization. + Signed-off-by: Brian Behlendorf diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index d04610317a..f5f5daa3e4 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -1018,6 +1018,7 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx) * transaction group won't leak out when we sync the older txg. */ dr = kmem_zalloc(sizeof (dbuf_dirty_record_t), KM_SLEEP); + list_link_init(&dr->dr_dirty_node); if (db->db_level == 0) { void *data_old = db->db_buf; diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c index e77834d60d..45ba90a6d6 100644 --- a/module/zfs/dnode.c +++ b/module/zfs/dnode.c @@ -280,6 +280,13 @@ dnode_create(objset_impl_t *os, dnode_phys_t *dnp, dmu_buf_impl_t *db, dn->dn_dbuf = db; dn->dn_phys = dnp; + list_link_init(&dn->dn_link); + { + int i; + for (i = 0; i < TXG_SIZE; i++) + list_link_init(&dn->dn_dirty_link[i]); + } + if (dnp->dn_datablkszsec) dnode_setdblksz(dn, dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT); dn->dn_indblkshift = dnp->dn_indblkshift; diff --git a/module/zfs/include/sys/dbuf.h b/module/zfs/include/sys/dbuf.h index 75ce27264e..bea71f06f1 100644 --- a/module/zfs/include/sys/dbuf.h +++ b/module/zfs/include/sys/dbuf.h @@ -85,9 +85,6 @@ struct dmu_tx; * etc. */ -#define LIST_LINK_INACTIVE(link) \ - ((link)->list_next == NULL && (link)->list_prev == NULL) - struct dmu_buf_impl; typedef enum override_states {