unit/mock_dmu: track dnode refcount changes

The thing under test will be taking and releasing dnode refs/holds. By
counting them and exposing the current count, we can assert in test
cleanup that we haven't missed releasing any, especially in cases where
the hold is held across multiple test steps.

Sponsored-by: TrueNAS
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Rob Norris <rob.norris@truenas.com>
Closes #18603
This commit is contained in:
Rob Norris
2026-05-29 14:38:48 +10:00
committed by Brian Behlendorf
parent efda1093ff
commit 8f933f53e2
2 changed files with 21 additions and 2 deletions
+18 -2
View File
@@ -28,6 +28,7 @@
#include <sys/zfeature.h>
#include "mock_dmu.h"
#include "unit.h"
/*
* A mock dbuf. A real dmu_buf_t (first for casting) plus the attached user
@@ -48,6 +49,7 @@ typedef struct mock_dbuf mock_dbuf_t;
*/
struct mock_dnode {
dnode_t mdn_dn;
uint64_t mdn_refcount;
size_t mdn_blksize;
size_t mdn_nblocks;
mock_dbuf_t **mdn_blocks;
@@ -110,6 +112,7 @@ mock_dnode_create(size_t blksize, dmu_object_type_t type)
ASSERT(IS_P2ALIGNED(blksize, 512));
mock_dnode_t *mdn = kmem_zalloc(sizeof (mock_dnode_t), KM_SLEEP);
mdn->mdn_refcount = 1;
mdn->mdn_dn.dn_type = type;
mdn->mdn_dn.dn_object = 1; /* arbitrary non-zero object number */
mdn->mdn_blksize = blksize;
@@ -156,6 +159,12 @@ mock_dnode_block_data(mock_dnode_t *mdn, uint64_t blkid)
return (mdn->mdn_blocks[blkid]->mdb_db.db_data);
}
uint64_t
mock_dnode_refcount(mock_dnode_t *mdn)
{
return (mdn->mdn_refcount);
}
/* Mock transaction */
mock_dmu_tx_t *
@@ -258,14 +267,21 @@ dmu_object_set_blocksize(objset_t *os, uint64_t object, uint64_t size,
boolean_t
dnode_add_ref(dnode_t *dn, const void *tag)
{
(void) dn; (void) tag;
(void) tag;
mock_dnode_t *mdn = (mock_dnode_t *)dn;
if (mdn->mdn_refcount == 0)
return (B_FALSE);
mdn->mdn_refcount++;
return (B_TRUE);
}
void
dnode_rele(dnode_t *dn, const void *tag)
{
(void) dn; (void) tag;
(void) tag;
mock_dnode_t *mdn = (mock_dnode_t *)dn;
unit_gt(mdn->mdn_refcount, 0);
mdn->mdn_refcount--;
}
/*
+3
View File
@@ -40,6 +40,9 @@ size_t mock_dnode_block_count(mock_dnode_t *mdn);
/* Returns a pointer to the data under the given block id. */
const void *mock_dnode_block_data(mock_dnode_t *mdn, uint64_t blkid);
/* Returns the current dnode ref (hold) count. */
uint64_t mock_dnode_refcount(mock_dnode_t *mdn);
/* Create/destroy a mock transaction handle. */
mock_dmu_tx_t *mock_tx_create(void);
void mock_tx_destroy(mock_dmu_tx_t *tx);