]>
Commit | Line | Data |
---|---|---|
34dc7c2f BB |
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 | /* | |
428870ff | 22 | * Copyright 2010 Sun Microsystems, Inc. All rights reserved. |
34dc7c2f BB |
23 | * Use is subject to license terms. |
24 | */ | |
a08ee875 LG |
25 | /* |
26 | * Copyright (c) 2013 by Delphix. All rights reserved. | |
27 | */ | |
34dc7c2f BB |
28 | |
29 | #ifndef _SYS_DMU_TX_H | |
30 | #define _SYS_DMU_TX_H | |
31 | ||
34dc7c2f BB |
32 | #include <sys/inttypes.h> |
33 | #include <sys/dmu.h> | |
34 | #include <sys/txg.h> | |
35 | #include <sys/refcount.h> | |
36 | ||
37 | #ifdef __cplusplus | |
38 | extern "C" { | |
39 | #endif | |
40 | ||
41 | struct dmu_buf_impl; | |
42 | struct dmu_tx_hold; | |
43 | struct dnode_link; | |
44 | struct dsl_pool; | |
45 | struct dnode; | |
46 | struct dsl_dir; | |
47 | ||
48 | struct dmu_tx { | |
49 | /* | |
50 | * No synchronization is needed because a tx can only be handled | |
51 | * by one thread. | |
52 | */ | |
53 | list_t tx_holds; /* list of dmu_tx_hold_t */ | |
54 | objset_t *tx_objset; | |
55 | struct dsl_dir *tx_dir; | |
56 | struct dsl_pool *tx_pool; | |
57 | uint64_t tx_txg; | |
58 | uint64_t tx_lastsnap_txg; | |
59 | uint64_t tx_lasttried_txg; | |
60 | txg_handle_t tx_txgh; | |
61 | void *tx_tempreserve_cookie; | |
62 | struct dmu_tx_hold *tx_needassign_txh; | |
a08ee875 LG |
63 | |
64 | /* list of dmu_tx_callback_t on this dmu_tx */ | |
65 | list_t tx_callbacks; | |
66 | ||
67 | /* placeholder for syncing context, doesn't need specific holds */ | |
68 | boolean_t tx_anyobj; | |
69 | ||
70 | /* has this transaction already been delayed? */ | |
71 | boolean_t tx_waited; | |
72 | ||
73 | /* time this transaction was created */ | |
74 | hrtime_t tx_start; | |
75 | ||
76 | /* need to wait for sufficient dirty space */ | |
77 | boolean_t tx_wait_dirty; | |
78 | ||
34dc7c2f | 79 | int tx_err; |
1c5de20a | 80 | #ifdef DEBUG_DMU_TX |
34dc7c2f BB |
81 | uint64_t tx_space_towrite; |
82 | uint64_t tx_space_tofree; | |
83 | uint64_t tx_space_tooverwrite; | |
84 | uint64_t tx_space_tounref; | |
85 | refcount_t tx_space_written; | |
86 | refcount_t tx_space_freed; | |
87 | #endif | |
88 | }; | |
89 | ||
90 | enum dmu_tx_hold_type { | |
91 | THT_NEWOBJECT, | |
92 | THT_WRITE, | |
93 | THT_BONUS, | |
94 | THT_FREE, | |
95 | THT_ZAP, | |
96 | THT_SPACE, | |
428870ff | 97 | THT_SPILL, |
34dc7c2f BB |
98 | THT_NUMTYPES |
99 | }; | |
100 | ||
101 | typedef struct dmu_tx_hold { | |
102 | dmu_tx_t *txh_tx; | |
103 | list_node_t txh_node; | |
104 | struct dnode *txh_dnode; | |
105 | uint64_t txh_space_towrite; | |
106 | uint64_t txh_space_tofree; | |
107 | uint64_t txh_space_tooverwrite; | |
108 | uint64_t txh_space_tounref; | |
b128c09f BB |
109 | uint64_t txh_memory_tohold; |
110 | uint64_t txh_fudge; | |
1c5de20a | 111 | #ifdef DEBUG_DMU_TX |
34dc7c2f BB |
112 | enum dmu_tx_hold_type txh_type; |
113 | uint64_t txh_arg1; | |
114 | uint64_t txh_arg2; | |
115 | #endif | |
116 | } dmu_tx_hold_t; | |
117 | ||
428870ff BB |
118 | typedef struct dmu_tx_callback { |
119 | list_node_t dcb_node; /* linked to tx_callbacks list */ | |
120 | dmu_tx_callback_func_t *dcb_func; /* caller function pointer */ | |
121 | void *dcb_data; /* caller private data */ | |
122 | } dmu_tx_callback_t; | |
34dc7c2f | 123 | |
570827e1 BB |
124 | /* |
125 | * Used for dmu tx kstat. | |
126 | */ | |
127 | typedef struct dmu_tx_stats { | |
128 | kstat_named_t dmu_tx_assigned; | |
129 | kstat_named_t dmu_tx_delay; | |
130 | kstat_named_t dmu_tx_error; | |
131 | kstat_named_t dmu_tx_suspended; | |
132 | kstat_named_t dmu_tx_group; | |
570827e1 BB |
133 | kstat_named_t dmu_tx_memory_reserve; |
134 | kstat_named_t dmu_tx_memory_reclaim; | |
570827e1 | 135 | kstat_named_t dmu_tx_dirty_throttle; |
a08ee875 LG |
136 | kstat_named_t dmu_tx_dirty_delay; |
137 | kstat_named_t dmu_tx_dirty_over_max; | |
570827e1 BB |
138 | kstat_named_t dmu_tx_quota; |
139 | } dmu_tx_stats_t; | |
140 | ||
141 | extern dmu_tx_stats_t dmu_tx_stats; | |
142 | ||
a08ee875 | 143 | #define DMU_TX_STAT_INCR(stat, val) \ |
570827e1 | 144 | atomic_add_64(&dmu_tx_stats.stat.value.ui64, (val)); |
a08ee875 | 145 | #define DMU_TX_STAT_BUMP(stat) \ |
570827e1 BB |
146 | DMU_TX_STAT_INCR(stat, 1); |
147 | ||
34dc7c2f BB |
148 | /* |
149 | * These routines are defined in dmu.h, and are called by the user. | |
150 | */ | |
151 | dmu_tx_t *dmu_tx_create(objset_t *dd); | |
a08ee875 | 152 | int dmu_tx_assign(dmu_tx_t *tx, txg_how_t txg_how); |
34dc7c2f BB |
153 | void dmu_tx_commit(dmu_tx_t *tx); |
154 | void dmu_tx_abort(dmu_tx_t *tx); | |
155 | uint64_t dmu_tx_get_txg(dmu_tx_t *tx); | |
a08ee875 | 156 | struct dsl_pool *dmu_tx_pool(dmu_tx_t *tx); |
34dc7c2f BB |
157 | void dmu_tx_wait(dmu_tx_t *tx); |
158 | ||
428870ff BB |
159 | void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func, |
160 | void *dcb_data); | |
161 | void dmu_tx_do_callbacks(list_t *cb_list, int error); | |
162 | ||
34dc7c2f BB |
163 | /* |
164 | * These routines are defined in dmu_spa.h, and are called by the SPA. | |
165 | */ | |
166 | extern dmu_tx_t *dmu_tx_create_assigned(struct dsl_pool *dp, uint64_t txg); | |
167 | ||
168 | /* | |
169 | * These routines are only called by the DMU. | |
170 | */ | |
171 | dmu_tx_t *dmu_tx_create_dd(dsl_dir_t *dd); | |
172 | int dmu_tx_is_syncing(dmu_tx_t *tx); | |
173 | int dmu_tx_private_ok(dmu_tx_t *tx); | |
174 | void dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object); | |
175 | void dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta); | |
176 | void dmu_tx_dirty_buf(dmu_tx_t *tx, struct dmu_buf_impl *db); | |
177 | int dmu_tx_holds(dmu_tx_t *tx, uint64_t object); | |
178 | void dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space); | |
179 | ||
1c5de20a | 180 | #ifdef DEBUG_DMU_TX |
34dc7c2f BB |
181 | #define DMU_TX_DIRTY_BUF(tx, db) dmu_tx_dirty_buf(tx, db) |
182 | #else | |
183 | #define DMU_TX_DIRTY_BUF(tx, db) | |
184 | #endif | |
185 | ||
570827e1 BB |
186 | void dmu_tx_init(void); |
187 | void dmu_tx_fini(void); | |
188 | ||
34dc7c2f BB |
189 | #ifdef __cplusplus |
190 | } | |
191 | #endif | |
192 | ||
193 | #endif /* _SYS_DMU_TX_H */ |