Deleted Added
full compact
dbuf.c (308082) dbuf.c (321524)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 35 unchanged lines hidden (view full) ---

44#include <sys/sa_impl.h>
45#include <sys/zfeature.h>
46#include <sys/blkptr.h>
47#include <sys/range_tree.h>
48#include <sys/callb.h>
49
50uint_t zfs_dbuf_evict_key;
51
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 35 unchanged lines hidden (view full) ---

44#include <sys/sa_impl.h>
45#include <sys/zfeature.h>
46#include <sys/blkptr.h>
47#include <sys/range_tree.h>
48#include <sys/callb.h>
49
50uint_t zfs_dbuf_evict_key;
51
52/*
53 * Number of times that zfs_free_range() took the slow path while doing
54 * a zfs receive. A nonzero value indicates a potential performance problem.
55 */
56uint64_t zfs_free_range_recv_miss;
57
58static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
59static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx);
60
61#ifndef __lint
62extern inline void dmu_buf_init_user(dmu_buf_user_t *dbu,
63 dmu_buf_evict_func_t *evict_func, dmu_buf_t **clear_on_evict_dbufp);
64#endif /* ! __lint */
65

--- 1149 unchanged lines hidden (view full) ---

1215 */
1216 arc_release(dr->dt.dl.dr_data, db);
1217}
1218
1219/*
1220 * Evict (if its unreferenced) or clear (if its referenced) any level-0
1221 * data blocks in the free range, so that any future readers will find
1222 * empty blocks.
52static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
53static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx);
54
55#ifndef __lint
56extern inline void dmu_buf_init_user(dmu_buf_user_t *dbu,
57 dmu_buf_evict_func_t *evict_func, dmu_buf_t **clear_on_evict_dbufp);
58#endif /* ! __lint */
59

--- 1149 unchanged lines hidden (view full) ---

1209 */
1210 arc_release(dr->dt.dl.dr_data, db);
1211}
1212
1213/*
1214 * Evict (if its unreferenced) or clear (if its referenced) any level-0
1215 * data blocks in the free range, so that any future readers will find
1216 * empty blocks.
1223 *
1224 * This is a no-op if the dataset is in the middle of an incremental
1225 * receive; see comment below for details.
1226 */
1227void
1228dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
1229 dmu_tx_t *tx)
1230{
1231 dmu_buf_impl_t db_search;
1232 dmu_buf_impl_t *db, *db_next;
1233 uint64_t txg = tx->tx_txg;
1234 avl_index_t where;
1217 */
1218void
1219dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
1220 dmu_tx_t *tx)
1221{
1222 dmu_buf_impl_t db_search;
1223 dmu_buf_impl_t *db, *db_next;
1224 uint64_t txg = tx->tx_txg;
1225 avl_index_t where;
1235 boolean_t freespill =
1236 (start_blkid == DMU_SPILL_BLKID || end_blkid == DMU_SPILL_BLKID);
1237
1226
1238 if (end_blkid > dn->dn_maxblkid && !freespill)
1227 if (end_blkid > dn->dn_maxblkid &&
1228 !(start_blkid == DMU_SPILL_BLKID || end_blkid == DMU_SPILL_BLKID))
1239 end_blkid = dn->dn_maxblkid;
1240 dprintf_dnode(dn, "start=%llu end=%llu\n", start_blkid, end_blkid);
1241
1242 db_search.db_level = 0;
1243 db_search.db_blkid = start_blkid;
1244 db_search.db_state = DB_SEARCH;
1245
1246 mutex_enter(&dn->dn_dbufs_mtx);
1229 end_blkid = dn->dn_maxblkid;
1230 dprintf_dnode(dn, "start=%llu end=%llu\n", start_blkid, end_blkid);
1231
1232 db_search.db_level = 0;
1233 db_search.db_blkid = start_blkid;
1234 db_search.db_state = DB_SEARCH;
1235
1236 mutex_enter(&dn->dn_dbufs_mtx);
1247 if (start_blkid >= dn->dn_unlisted_l0_blkid && !freespill) {
1248 /* There can't be any dbufs in this range; no need to search. */
1249#ifdef DEBUG
1250 db = avl_find(&dn->dn_dbufs, &db_search, &where);
1251 ASSERT3P(db, ==, NULL);
1252 db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
1253 ASSERT(db == NULL || db->db_level > 0);
1254#endif
1255 mutex_exit(&dn->dn_dbufs_mtx);
1256 return;
1257 } else if (dmu_objset_is_receiving(dn->dn_objset)) {
1258 /*
1259 * If we are receiving, we expect there to be no dbufs in
1260 * the range to be freed, because receive modifies each
1261 * block at most once, and in offset order. If this is
1262 * not the case, it can lead to performance problems,
1263 * so note that we unexpectedly took the slow path.
1264 */
1265 atomic_inc_64(&zfs_free_range_recv_miss);
1266 }
1267
1268 db = avl_find(&dn->dn_dbufs, &db_search, &where);
1269 ASSERT3P(db, ==, NULL);
1237 db = avl_find(&dn->dn_dbufs, &db_search, &where);
1238 ASSERT3P(db, ==, NULL);
1239
1270 db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
1271
1272 for (; db != NULL; db = db_next) {
1273 db_next = AVL_NEXT(&dn->dn_dbufs, db);
1274 ASSERT(db->db_blkid != DMU_BONUS_BLKID);
1275
1276 if (db->db_level != 0 || db->db_blkid > end_blkid) {
1277 break;

--- 1000 unchanged lines hidden (view full) ---

2278 db->db_state = DB_EVICTING;
2279 if ((odb = dbuf_hash_insert(db)) != NULL) {
2280 /* someone else inserted it first */
2281 kmem_cache_free(dbuf_kmem_cache, db);
2282 mutex_exit(&dn->dn_dbufs_mtx);
2283 return (odb);
2284 }
2285 avl_add(&dn->dn_dbufs, db);
1240 db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
1241
1242 for (; db != NULL; db = db_next) {
1243 db_next = AVL_NEXT(&dn->dn_dbufs, db);
1244 ASSERT(db->db_blkid != DMU_BONUS_BLKID);
1245
1246 if (db->db_level != 0 || db->db_blkid > end_blkid) {
1247 break;

--- 1000 unchanged lines hidden (view full) ---

2248 db->db_state = DB_EVICTING;
2249 if ((odb = dbuf_hash_insert(db)) != NULL) {
2250 /* someone else inserted it first */
2251 kmem_cache_free(dbuf_kmem_cache, db);
2252 mutex_exit(&dn->dn_dbufs_mtx);
2253 return (odb);
2254 }
2255 avl_add(&dn->dn_dbufs, db);
2286 if (db->db_level == 0 && db->db_blkid >=
2287 dn->dn_unlisted_l0_blkid)
2288 dn->dn_unlisted_l0_blkid = db->db_blkid + 1;
2256
2289 db->db_state = DB_UNCACHED;
2290 mutex_exit(&dn->dn_dbufs_mtx);
2291 arc_space_consume(sizeof (dmu_buf_impl_t), ARC_SPACE_OTHER);
2292
2293 if (parent && parent != dn->dn_dbuf)
2294 dbuf_add_ref(parent, db);
2295
2296 ASSERT(dn->dn_object == DMU_META_DNODE_OBJECT ||

--- 1321 unchanged lines hidden ---
2257 db->db_state = DB_UNCACHED;
2258 mutex_exit(&dn->dn_dbufs_mtx);
2259 arc_space_consume(sizeof (dmu_buf_impl_t), ARC_SPACE_OTHER);
2260
2261 if (parent && parent != dn->dn_dbuf)
2262 dbuf_add_ref(parent, db);
2263
2264 ASSERT(dn->dn_object == DMU_META_DNODE_OBJECT ||

--- 1321 unchanged lines hidden ---