MCPcopy Create free account
hub / github.com/F-Stack/f-stack / dnode_rele_and_unlock

Function dnode_rele_and_unlock

freebsd/contrib/openzfs/module/zfs/dnode.c:1605–1643  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1603}
1604
1605void
1606dnode_rele_and_unlock(dnode_t *dn, void *tag, boolean_t evicting)
1607{
1608 uint64_t refs;
1609 /* Get while the hold prevents the dnode from moving. */
1610 dmu_buf_impl_t *db = dn->dn_dbuf;
1611 dnode_handle_t *dnh = dn->dn_handle;
1612
1613 refs = zfs_refcount_remove(&dn->dn_holds, tag);
1614 if (refs == 0)
1615 cv_broadcast(&dn->dn_nodnholds);
1616 mutex_exit(&dn->dn_mtx);
1617 /* dnode could get destroyed at this point, so don't use it anymore */
1618
1619 /*
1620 * It's unsafe to release the last hold on a dnode by dnode_rele() or
1621 * indirectly by dbuf_rele() while relying on the dnode handle to
1622 * prevent the dnode from moving, since releasing the last hold could
1623 * result in the dnode's parent dbuf evicting its dnode handles. For
1624 * that reason anyone calling dnode_rele() or dbuf_rele() without some
1625 * other direct or indirect hold on the dnode must first drop the dnode
1626 * handle.
1627 */
1628 ASSERT(refs > 0 || dnh->dnh_zrlock.zr_owner != curthread);
1629
1630 /* NOTE: the DNODE_DNODE does not have a dn_dbuf */
1631 if (refs == 0 && db != NULL) {
1632 /*
1633 * Another thread could add a hold to the dnode handle in
1634 * dnode_hold_impl() while holding the parent dbuf. Since the
1635 * hold on the parent dbuf prevents the handle from being
1636 * destroyed, the hold on the handle is OK. We can't yet assert
1637 * that the handle has zero references, but that will be
1638 * asserted anyway when the handle gets destroyed.
1639 */
1640 mutex_enter(&db->db_mtx);
1641 dbuf_rele_and_unlock(db, dnh, evicting);
1642 }
1643}
1644
1645/*
1646 * Test whether we can create a dnode at the specified location.

Callers 2

dbuf_destroyFunction · 0.85
dnode_releFunction · 0.85

Calls 5

zfs_refcount_removeFunction · 0.85
cv_broadcastFunction · 0.85
mutex_exitFunction · 0.85
mutex_enterFunction · 0.85
dbuf_rele_and_unlockFunction · 0.85

Tested by

no test coverage detected