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:
committed by
Brian Behlendorf
parent
efda1093ff
commit
8f933f53e2
+18
-2
@@ -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--;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user