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
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 * Copyright (c) 2013 by Delphix. All rights reserved.
25 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
26 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
27 */
28
29 #include <sys/zfs_context.h>
30 #include <sys/dmu.h>
31 #include <sys/dmu_send.h>
32 #include <sys/dmu_impl.h>
33 #include <sys/dbuf.h>
34 #include <sys/dmu_objset.h>
35 #include <sys/dsl_dataset.h>
36 #include <sys/dsl_dir.h>
37 #include <sys/dmu_tx.h>
38 #include <sys/spa.h>
39 #include <sys/zio.h>
40 #include <sys/dmu_zfetch.h>
41 #include <sys/sa.h>
42 #include <sys/sa_impl.h>
43
44 /*
45 * Number of times that zfs_free_range() took the slow path while doing
46 * a zfs receive. A nonzero value indicates a potential performance problem.
47 */
48 uint64_t zfs_free_range_recv_miss;
49
50 static void dbuf_destroy(dmu_buf_impl_t *db);
51 static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
52 static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx);
53
54 /*
55 * Global data structures and functions for the dbuf cache.
56 */
57 static kmem_cache_t *dbuf_cache;
58
59 /* ARGSUSED */
60 static int
61 dbuf_cons(void *vdb, void *unused, int kmflag)
62 {
1160 mutex_init(&dr->dt.di.dr_mtx, NULL, MUTEX_DEFAULT, NULL);
1161 list_create(&dr->dt.di.dr_children,
1162 sizeof (dbuf_dirty_record_t),
1163 offsetof(dbuf_dirty_record_t, dr_dirty_node));
1164 }
1165 if (db->db_blkid != DMU_BONUS_BLKID && os->os_dsl_dataset != NULL)
1166 dr->dr_accounted = db->db.db_size;
1167 dr->dr_dbuf = db;
1168 dr->dr_txg = tx->tx_txg;
1169 dr->dr_next = *drp;
1170 *drp = dr;
1171
1172 /*
1173 * We could have been freed_in_flight between the dbuf_noread
1174 * and dbuf_dirty. We win, as though the dbuf_noread() had
1175 * happened after the free.
1176 */
1177 if (db->db_level == 0 && db->db_blkid != DMU_BONUS_BLKID &&
1178 db->db_blkid != DMU_SPILL_BLKID) {
1179 mutex_enter(&dn->dn_mtx);
1180 dnode_clear_range(dn, db->db_blkid, 1, tx);
1181 mutex_exit(&dn->dn_mtx);
1182 db->db_freed_in_flight = FALSE;
1183 }
1184
1185 /*
1186 * This buffer is now part of this txg
1187 */
1188 dbuf_add_ref(db, (void *)(uintptr_t)tx->tx_txg);
1189 db->db_dirtycnt += 1;
1190 ASSERT3U(db->db_dirtycnt, <=, 3);
1191
1192 mutex_exit(&db->db_mtx);
1193
1194 if (db->db_blkid == DMU_BONUS_BLKID ||
1195 db->db_blkid == DMU_SPILL_BLKID) {
1196 mutex_enter(&dn->dn_mtx);
1197 ASSERT(!list_link_active(&dr->dr_dirty_node));
1198 list_insert_tail(&dn->dn_dirty_records[txgoff], dr);
1199 mutex_exit(&dn->dn_mtx);
1200 dnode_setdirty(dn, tx);
|
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
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
25 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
26 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
27 */
28
29 #include <sys/zfs_context.h>
30 #include <sys/dmu.h>
31 #include <sys/dmu_send.h>
32 #include <sys/dmu_impl.h>
33 #include <sys/dbuf.h>
34 #include <sys/dmu_objset.h>
35 #include <sys/dsl_dataset.h>
36 #include <sys/dsl_dir.h>
37 #include <sys/dmu_tx.h>
38 #include <sys/spa.h>
39 #include <sys/zio.h>
40 #include <sys/dmu_zfetch.h>
41 #include <sys/sa.h>
42 #include <sys/sa_impl.h>
43 #include <sys/range_tree.h>
44
45 /*
46 * Number of times that zfs_free_range() took the slow path while doing
47 * a zfs receive. A nonzero value indicates a potential performance problem.
48 */
49 uint64_t zfs_free_range_recv_miss;
50
51 static void dbuf_destroy(dmu_buf_impl_t *db);
52 static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
53 static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx);
54
55 /*
56 * Global data structures and functions for the dbuf cache.
57 */
58 static kmem_cache_t *dbuf_cache;
59
60 /* ARGSUSED */
61 static int
62 dbuf_cons(void *vdb, void *unused, int kmflag)
63 {
1161 mutex_init(&dr->dt.di.dr_mtx, NULL, MUTEX_DEFAULT, NULL);
1162 list_create(&dr->dt.di.dr_children,
1163 sizeof (dbuf_dirty_record_t),
1164 offsetof(dbuf_dirty_record_t, dr_dirty_node));
1165 }
1166 if (db->db_blkid != DMU_BONUS_BLKID && os->os_dsl_dataset != NULL)
1167 dr->dr_accounted = db->db.db_size;
1168 dr->dr_dbuf = db;
1169 dr->dr_txg = tx->tx_txg;
1170 dr->dr_next = *drp;
1171 *drp = dr;
1172
1173 /*
1174 * We could have been freed_in_flight between the dbuf_noread
1175 * and dbuf_dirty. We win, as though the dbuf_noread() had
1176 * happened after the free.
1177 */
1178 if (db->db_level == 0 && db->db_blkid != DMU_BONUS_BLKID &&
1179 db->db_blkid != DMU_SPILL_BLKID) {
1180 mutex_enter(&dn->dn_mtx);
1181 if (dn->dn_free_ranges[txgoff] != NULL) {
1182 range_tree_clear(dn->dn_free_ranges[txgoff],
1183 db->db_blkid, 1);
1184 }
1185 mutex_exit(&dn->dn_mtx);
1186 db->db_freed_in_flight = FALSE;
1187 }
1188
1189 /*
1190 * This buffer is now part of this txg
1191 */
1192 dbuf_add_ref(db, (void *)(uintptr_t)tx->tx_txg);
1193 db->db_dirtycnt += 1;
1194 ASSERT3U(db->db_dirtycnt, <=, 3);
1195
1196 mutex_exit(&db->db_mtx);
1197
1198 if (db->db_blkid == DMU_BONUS_BLKID ||
1199 db->db_blkid == DMU_SPILL_BLKID) {
1200 mutex_enter(&dn->dn_mtx);
1201 ASSERT(!list_link_active(&dr->dr_dirty_node));
1202 list_insert_tail(&dn->dn_dirty_records[txgoff], dr);
1203 mutex_exit(&dn->dn_mtx);
1204 dnode_setdirty(dn, tx);
|