mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 11:19:32 +03:00
Illumos 6288 - dmu_buf_will_dirty could be faster
6288 dmu_buf_will_dirty could be faster Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Paul Dagnelie <pcd@delphix.com> Reviewed by: Justin Gibbs <gibbs@scsiguy.com> Reviewed by: Richard Elling <Richard.Elling@RichardElling.com> Approved by: Robert Mustacchi <rm@joyent.com> References: https://www.illumos.org/issues/6288 https://github.com/illumos/illumos-gate/commit/0f2e7d0 Porting notes: - [module/zfs/dbuf.c] - Fix 'warning: ISO C90 forbids mixed declarations and code' by moving 'dbuf_dirty_record_t *dr' to start of code block. Ported-by: kernelOfTruth kerneloftruth@gmail.com Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
parent
2e8efe1bef
commit
5a28a9737a
@ -1182,6 +1182,32 @@ dbuf_release_bp(dmu_buf_impl_t *db)
|
|||||||
(void) arc_release(db->db_buf, db);
|
(void) arc_release(db->db_buf, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We already have a dirty record for this TXG, and we are being
|
||||||
|
* dirtied again.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
dbuf_redirty(dbuf_dirty_record_t *dr)
|
||||||
|
{
|
||||||
|
dmu_buf_impl_t *db = dr->dr_dbuf;
|
||||||
|
|
||||||
|
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||||
|
|
||||||
|
if (db->db_level == 0 && db->db_blkid != DMU_BONUS_BLKID) {
|
||||||
|
/*
|
||||||
|
* If this buffer has already been written out,
|
||||||
|
* we now need to reset its state.
|
||||||
|
*/
|
||||||
|
dbuf_unoverride(dr);
|
||||||
|
if (db->db.db_object != DMU_META_DNODE_OBJECT &&
|
||||||
|
db->db_state != DB_NOFILL) {
|
||||||
|
/* Already released on initial dirty, so just thaw. */
|
||||||
|
ASSERT(arc_released(db->db_buf));
|
||||||
|
arc_buf_thaw(db->db_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dbuf_dirty_record_t *
|
dbuf_dirty_record_t *
|
||||||
dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
@ -1254,16 +1280,7 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
|||||||
if (dr && dr->dr_txg == tx->tx_txg) {
|
if (dr && dr->dr_txg == tx->tx_txg) {
|
||||||
DB_DNODE_EXIT(db);
|
DB_DNODE_EXIT(db);
|
||||||
|
|
||||||
if (db->db_level == 0 && db->db_blkid != DMU_BONUS_BLKID) {
|
dbuf_redirty(dr);
|
||||||
/*
|
|
||||||
* If this buffer has already been written out,
|
|
||||||
* we now need to reset its state.
|
|
||||||
*/
|
|
||||||
dbuf_unoverride(dr);
|
|
||||||
if (db->db.db_object != DMU_META_DNODE_OBJECT &&
|
|
||||||
db->db_state != DB_NOFILL)
|
|
||||||
arc_buf_thaw(db->db_buf);
|
|
||||||
}
|
|
||||||
mutex_exit(&db->db_mtx);
|
mutex_exit(&db->db_mtx);
|
||||||
return (dr);
|
return (dr);
|
||||||
}
|
}
|
||||||
@ -1564,10 +1581,35 @@ dmu_buf_will_dirty(dmu_buf_t *db_fake, dmu_tx_t *tx)
|
|||||||
{
|
{
|
||||||
dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
|
dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
|
||||||
int rf = DB_RF_MUST_SUCCEED | DB_RF_NOPREFETCH;
|
int rf = DB_RF_MUST_SUCCEED | DB_RF_NOPREFETCH;
|
||||||
|
dbuf_dirty_record_t *dr;
|
||||||
|
|
||||||
ASSERT(tx->tx_txg != 0);
|
ASSERT(tx->tx_txg != 0);
|
||||||
ASSERT(!refcount_is_zero(&db->db_holds));
|
ASSERT(!refcount_is_zero(&db->db_holds));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Quick check for dirtyness. For already dirty blocks, this
|
||||||
|
* reduces runtime of this function by >90%, and overall performance
|
||||||
|
* by 50% for some workloads (e.g. file deletion with indirect blocks
|
||||||
|
* cached).
|
||||||
|
*/
|
||||||
|
mutex_enter(&db->db_mtx);
|
||||||
|
|
||||||
|
for (dr = db->db_last_dirty;
|
||||||
|
dr != NULL && dr->dr_txg >= tx->tx_txg; dr = dr->dr_next) {
|
||||||
|
/*
|
||||||
|
* It's possible that it is already dirty but not cached,
|
||||||
|
* because there are some calls to dbuf_dirty() that don't
|
||||||
|
* go through dmu_buf_will_dirty().
|
||||||
|
*/
|
||||||
|
if (dr->dr_txg == tx->tx_txg && db->db_state == DB_CACHED) {
|
||||||
|
/* This dbuf is already dirty and cached. */
|
||||||
|
dbuf_redirty(dr);
|
||||||
|
mutex_exit(&db->db_mtx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_exit(&db->db_mtx);
|
||||||
|
|
||||||
DB_DNODE_ENTER(db);
|
DB_DNODE_ENTER(db);
|
||||||
if (RW_WRITE_HELD(&DB_DNODE(db)->dn_struct_rwlock))
|
if (RW_WRITE_HELD(&DB_DNODE(db)->dn_struct_rwlock))
|
||||||
rf |= DB_RF_HAVESTRUCT;
|
rf |= DB_RF_HAVESTRUCT;
|
||||||
|
Loading…
Reference in New Issue
Block a user