diff options
author | George Melikov <[email protected]> | 2017-01-27 02:15:48 +0300 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-01-26 15:15:48 -0800 |
commit | 9c9531cb6f085174e90d1262aba177ffb8b88753 (patch) | |
tree | 09446b2275a449dc7b191e7865780adbbae10b42 /module/zfs/dbuf.c | |
parent | 39efbde7c551ae0edcd57db3aab28fd7f2d29d18 (diff) |
OpenZFS 7500 - Simplify dbuf_free_range by removing dn_unlisted_l0_blkid
Authored by: Stephen Blinick <[email protected]>
Reviewed by: Matthew Ahrens <[email protected]>
Reviewed by: Dan Kimmel <[email protected]>
Approved by: Gordon Ross <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Ported-by: George Melikov <[email protected]>
OpenZFS-issue: https://www.illumos.org/issues/7500
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/653af1b
Closes #5639
Diffstat (limited to 'module/zfs/dbuf.c')
-rw-r--r-- | module/zfs/dbuf.c | 39 |
1 files changed, 4 insertions, 35 deletions
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 907a84941..ebb95ddb8 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -74,11 +74,6 @@ static void __dbuf_hold_impl_init(struct dbuf_hold_impl_data *dh, static int __dbuf_hold_impl(struct dbuf_hold_impl_data *dh); uint_t zfs_dbuf_evict_key; -/* - * Number of times that zfs_free_range() took the slow path while doing - * a zfs receive. A nonzero value indicates a potential performance problem. - */ -uint64_t zfs_free_range_recv_miss; static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx); static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx); @@ -1340,9 +1335,6 @@ dbuf_unoverride(dbuf_dirty_record_t *dr) * Evict (if its unreferenced) or clear (if its referenced) any level-0 * data blocks in the free range, so that any future readers will find * empty blocks. - * - * This is a no-op if the dataset is in the middle of an incremental - * receive; see comment below for details. */ void dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid, @@ -1352,10 +1344,9 @@ dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid, dmu_buf_impl_t *db, *db_next; uint64_t txg = tx->tx_txg; avl_index_t where; - boolean_t freespill = - (start_blkid == DMU_SPILL_BLKID || end_blkid == DMU_SPILL_BLKID); - if (end_blkid > dn->dn_maxblkid && !freespill) + if (end_blkid > dn->dn_maxblkid && + !(start_blkid == DMU_SPILL_BLKID || end_blkid == DMU_SPILL_BLKID)) end_blkid = dn->dn_maxblkid; dprintf_dnode(dn, "start=%llu end=%llu\n", start_blkid, end_blkid); @@ -1365,28 +1356,9 @@ dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid, db_search->db_state = DB_SEARCH; mutex_enter(&dn->dn_dbufs_mtx); - if (start_blkid >= dn->dn_unlisted_l0_blkid && !freespill) { - /* There can't be any dbufs in this range; no need to search. */ -#ifdef DEBUG - db = avl_find(&dn->dn_dbufs, db_search, &where); - ASSERT3P(db, ==, NULL); - db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER); - ASSERT(db == NULL || db->db_level > 0); -#endif - goto out; - } else if (dmu_objset_is_receiving(dn->dn_objset)) { - /* - * If we are receiving, we expect there to be no dbufs in - * the range to be freed, because receive modifies each - * block at most once, and in offset order. If this is - * not the case, it can lead to performance problems, - * so note that we unexpectedly took the slow path. - */ - atomic_inc_64(&zfs_free_range_recv_miss); - } - db = avl_find(&dn->dn_dbufs, db_search, &where); ASSERT3P(db, ==, NULL); + db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER); for (; db != NULL; db = db_next) { @@ -1459,7 +1431,6 @@ dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid, mutex_exit(&db->db_mtx); } -out: kmem_free(db_search, sizeof (dmu_buf_impl_t)); mutex_exit(&dn->dn_dbufs_mtx); } @@ -2416,9 +2387,7 @@ dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid, return (odb); } avl_add(&dn->dn_dbufs, db); - if (db->db_level == 0 && db->db_blkid >= - dn->dn_unlisted_l0_blkid) - dn->dn_unlisted_l0_blkid = db->db_blkid + 1; + db->db_state = DB_UNCACHED; mutex_exit(&dn->dn_dbufs_mtx); arc_space_consume(sizeof (dmu_buf_impl_t), ARC_SPACE_DBUF); |