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 --- |