dmu_impl.h revision 290756
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
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 2010 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25/*
26 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
27 * Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>. All rights reserved.
28 * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
29 */
30
31#ifndef _SYS_DMU_IMPL_H
32#define	_SYS_DMU_IMPL_H
33
34#include <sys/txg_impl.h>
35#include <sys/zio.h>
36#include <sys/dnode.h>
37#include <sys/kstat.h>
38#include <sys/zfs_context.h>
39#include <sys/zfs_ioctl.h>
40
41#ifdef	__cplusplus
42extern "C" {
43#endif
44
45/*
46 * This is the locking strategy for the DMU.  Numbers in parenthesis are
47 * cases that use that lock order, referenced below:
48 *
49 * ARC is self-contained
50 * bplist is self-contained
51 * refcount is self-contained
52 * txg is self-contained (hopefully!)
53 * zst_lock
54 * zf_rwlock
55 *
56 * XXX try to improve evicting path?
57 *
58 * dp_config_rwlock > os_obj_lock > dn_struct_rwlock >
59 * 	dn_dbufs_mtx > hash_mutexes > db_mtx > dd_lock > leafs
60 *
61 * dp_config_rwlock
62 *    must be held before: everything
63 *    protects dd namespace changes
64 *    protects property changes globally
65 *    held from:
66 *    	dsl_dir_open/r:
67 *    	dsl_dir_create_sync/w:
68 *    	dsl_dir_sync_destroy/w:
69 *    	dsl_dir_rename_sync/w:
70 *    	dsl_prop_changed_notify/r:
71 *
72 * os_obj_lock
73 *   must be held before:
74 *   	everything except dp_config_rwlock
75 *   protects os_obj_next
76 *   held from:
77 *   	dmu_object_alloc: dn_dbufs_mtx, db_mtx, hash_mutexes, dn_struct_rwlock
78 *
79 * dn_struct_rwlock
80 *   must be held before:
81 *   	everything except dp_config_rwlock and os_obj_lock
82 *   protects structure of dnode (eg. nlevels)
83 *   	db_blkptr can change when syncing out change to nlevels
84 *   	dn_maxblkid
85 *   	dn_nlevels
86 *   	dn_*blksz*
87 *   	phys nlevels, maxblkid, physical blkptr_t's (?)
88 *   held from:
89 *   	callers of dbuf_read_impl, dbuf_hold[_impl], dbuf_prefetch
90 *   	dmu_object_info_from_dnode: dn_dirty_mtx (dn_datablksz)
91 *   	dmu_tx_count_free:
92 *   	dbuf_read_impl: db_mtx, dmu_zfetch()
93 *   	dmu_zfetch: zf_rwlock/r, zst_lock, dbuf_prefetch()
94 *   	dbuf_new_size: db_mtx
95 *   	dbuf_dirty: db_mtx
96 *	dbuf_findbp: (callers, phys? - the real need)
97 *	dbuf_create: dn_dbufs_mtx, hash_mutexes, db_mtx (phys?)
98 *	dbuf_prefetch: dn_dirty_mtx, hash_mutexes, db_mtx, dn_dbufs_mtx
99 *	dbuf_hold_impl: hash_mutexes, db_mtx, dn_dbufs_mtx, dbuf_findbp()
100 *	dnode_sync/w (increase_indirection): db_mtx (phys)
101 *	dnode_set_blksz/w: dn_dbufs_mtx (dn_*blksz*)
102 *	dnode_new_blkid/w: (dn_maxblkid)
103 *	dnode_free_range/w: dn_dirty_mtx (dn_maxblkid)
104 *	dnode_next_offset: (phys)
105 *
106 * dn_dbufs_mtx
107 *    must be held before:
108 *    	db_mtx, hash_mutexes
109 *    protects:
110 *    	dn_dbufs
111 *    	dn_evicted
112 *    held from:
113 *    	dmu_evict_user: db_mtx (dn_dbufs)
114 *    	dbuf_free_range: db_mtx (dn_dbufs)
115 *    	dbuf_remove_ref: db_mtx, callees:
116 *    		dbuf_hash_remove: hash_mutexes, db_mtx
117 *    	dbuf_create: hash_mutexes, db_mtx (dn_dbufs)
118 *    	dnode_set_blksz: (dn_dbufs)
119 *
120 * hash_mutexes (global)
121 *   must be held before:
122 *   	db_mtx
123 *   protects dbuf_hash_table (global) and db_hash_next
124 *   held from:
125 *   	dbuf_find: db_mtx
126 *   	dbuf_hash_insert: db_mtx
127 *   	dbuf_hash_remove: db_mtx
128 *
129 * db_mtx (meta-leaf)
130 *   must be held before:
131 *   	dn_mtx, dn_dirty_mtx, dd_lock (leaf mutexes)
132 *   protects:
133 *   	db_state
134 * 	db_holds
135 * 	db_buf
136 * 	db_changed
137 * 	db_data_pending
138 * 	db_dirtied
139 * 	db_link
140 * 	db_dirty_node (??)
141 * 	db_dirtycnt
142 * 	db_d.*
143 * 	db.*
144 *   held from:
145 * 	dbuf_dirty: dn_mtx, dn_dirty_mtx
146 * 	dbuf_dirty->dsl_dir_willuse_space: dd_lock
147 * 	dbuf_dirty->dbuf_new_block->dsl_dataset_block_freeable: dd_lock
148 * 	dbuf_undirty: dn_dirty_mtx (db_d)
149 * 	dbuf_write_done: dn_dirty_mtx (db_state)
150 * 	dbuf_*
151 * 	dmu_buf_update_user: none (db_d)
152 * 	dmu_evict_user: none (db_d) (maybe can eliminate)
153 *   	dbuf_find: none (db_holds)
154 *   	dbuf_hash_insert: none (db_holds)
155 *   	dmu_buf_read_array_impl: none (db_state, db_changed)
156 *   	dmu_sync: none (db_dirty_node, db_d)
157 *   	dnode_reallocate: none (db)
158 *
159 * dn_mtx (leaf)
160 *   protects:
161 *   	dn_dirty_dbufs
162 *   	dn_ranges
163 *   	phys accounting
164 * 	dn_allocated_txg
165 * 	dn_free_txg
166 * 	dn_assigned_txg
167 * 	dd_assigned_tx
168 * 	dn_notxholds
169 * 	dn_dirtyctx
170 * 	dn_dirtyctx_firstset
171 * 	(dn_phys copy fields?)
172 * 	(dn_phys contents?)
173 *   held from:
174 *   	dnode_*
175 *   	dbuf_dirty: none
176 *   	dbuf_sync: none (phys accounting)
177 *   	dbuf_undirty: none (dn_ranges, dn_dirty_dbufs)
178 *   	dbuf_write_done: none (phys accounting)
179 *   	dmu_object_info_from_dnode: none (accounting)
180 *   	dmu_tx_commit: none
181 *   	dmu_tx_hold_object_impl: none
182 *   	dmu_tx_try_assign: dn_notxholds(cv)
183 *   	dmu_tx_unassign: none
184 *
185 * dd_lock
186 *    must be held before:
187 *      ds_lock
188 *      ancestors' dd_lock
189 *    protects:
190 *    	dd_prop_cbs
191 *    	dd_sync_*
192 *    	dd_used_bytes
193 *    	dd_tempreserved
194 *    	dd_space_towrite
195 *    	dd_myname
196 *    	dd_phys accounting?
197 *    held from:
198 *    	dsl_dir_*
199 *    	dsl_prop_changed_notify: none (dd_prop_cbs)
200 *    	dsl_prop_register: none (dd_prop_cbs)
201 *    	dsl_prop_unregister: none (dd_prop_cbs)
202 *    	dsl_dataset_block_freeable: none (dd_sync_*)
203 *
204 * os_lock (leaf)
205 *   protects:
206 *   	os_dirty_dnodes
207 *   	os_free_dnodes
208 *   	os_dnodes
209 *   	os_downgraded_dbufs
210 *   	dn_dirtyblksz
211 *   	dn_dirty_link
212 *   held from:
213 *   	dnode_create: none (os_dnodes)
214 *   	dnode_destroy: none (os_dnodes)
215 *   	dnode_setdirty: none (dn_dirtyblksz, os_*_dnodes)
216 *   	dnode_free: none (dn_dirtyblksz, os_*_dnodes)
217 *
218 * ds_lock
219 *    protects:
220 *    	ds_objset
221 *    	ds_open_refcount
222 *    	ds_snapname
223 *    	ds_phys accounting
224 *	ds_phys userrefs zapobj
225 *	ds_reserved
226 *    held from:
227 *    	dsl_dataset_*
228 *
229 * dr_mtx (leaf)
230 *    protects:
231 *	dr_children
232 *    held from:
233 *	dbuf_dirty
234 *	dbuf_undirty
235 *	dbuf_sync_indirect
236 *	dnode_new_blkid
237 */
238
239struct objset;
240struct dmu_pool;
241
242typedef struct dmu_xuio {
243	int next;
244	int cnt;
245	struct arc_buf **bufs;
246	iovec_t *iovp;
247} dmu_xuio_t;
248
249typedef struct xuio_stats {
250	/* loaned yet not returned arc_buf */
251	kstat_named_t xuiostat_onloan_rbuf;
252	kstat_named_t xuiostat_onloan_wbuf;
253	/* whether a copy is made when loaning out a read buffer */
254	kstat_named_t xuiostat_rbuf_copied;
255	kstat_named_t xuiostat_rbuf_nocopy;
256	/* whether a copy is made when assigning a write buffer */
257	kstat_named_t xuiostat_wbuf_copied;
258	kstat_named_t xuiostat_wbuf_nocopy;
259} xuio_stats_t;
260
261static xuio_stats_t xuio_stats = {
262	{ "onloan_read_buf",	KSTAT_DATA_UINT64 },
263	{ "onloan_write_buf",	KSTAT_DATA_UINT64 },
264	{ "read_buf_copied",	KSTAT_DATA_UINT64 },
265	{ "read_buf_nocopy",	KSTAT_DATA_UINT64 },
266	{ "write_buf_copied",	KSTAT_DATA_UINT64 },
267	{ "write_buf_nocopy",	KSTAT_DATA_UINT64 }
268};
269
270#define	XUIOSTAT_INCR(stat, val)	\
271	atomic_add_64(&xuio_stats.stat.value.ui64, (val))
272#define	XUIOSTAT_BUMP(stat)	XUIOSTAT_INCR(stat, 1)
273
274/*
275 * The list of data whose inclusion in a send stream can be pending from
276 * one call to backup_cb to another.  Multiple calls to dump_free() and
277 * dump_freeobjects() can be aggregated into a single DRR_FREE or
278 * DRR_FREEOBJECTS replay record.
279 */
280typedef enum {
281	PENDING_NONE,
282	PENDING_FREE,
283	PENDING_FREEOBJECTS
284} dmu_pendop_t;
285
286typedef struct dmu_sendarg {
287	list_node_t dsa_link;
288	dmu_replay_record_t *dsa_drr;
289	kthread_t *dsa_td;
290	struct file *dsa_fp;
291	int dsa_outfd;
292	struct proc *dsa_proc;
293	offset_t *dsa_off;
294	objset_t *dsa_os;
295	zio_cksum_t dsa_zc;
296	uint64_t dsa_toguid;
297	int dsa_err;
298	dmu_pendop_t dsa_pending_op;
299	boolean_t dsa_incremental;
300	uint64_t dsa_featureflags;
301	uint64_t dsa_last_data_object;
302	uint64_t dsa_last_data_offset;
303	uint64_t dsa_resume_object;
304	uint64_t dsa_resume_offset;
305} dmu_sendarg_t;
306
307void dmu_object_zapify(objset_t *, uint64_t, dmu_object_type_t, dmu_tx_t *);
308void dmu_object_free_zapified(objset_t *, uint64_t, dmu_tx_t *);
309int dmu_buf_hold_noread(objset_t *, uint64_t, uint64_t,
310    void *, dmu_buf_t **);
311
312#ifdef	__cplusplus
313}
314#endif
315
316#endif	/* _SYS_DMU_IMPL_H */
317