18 * |
18 * |
19 * CDDL HEADER END |
19 * CDDL HEADER END |
20 */ |
20 */ |
21 /* |
21 /* |
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
23 * Copyright (c) 2011 by Delphix. All rights reserved. |
23 * Copyright (c) 2012 by Delphix. All rights reserved. |
24 */ |
24 */ |
25 |
25 |
26 #include <sys/dsl_pool.h> |
26 #include <sys/dsl_pool.h> |
27 #include <sys/dsl_dataset.h> |
27 #include <sys/dsl_dataset.h> |
28 #include <sys/dsl_prop.h> |
28 #include <sys/dsl_prop.h> |
38 #include <sys/zfs_context.h> |
38 #include <sys/zfs_context.h> |
39 #include <sys/fs/zfs.h> |
39 #include <sys/fs/zfs.h> |
40 #include <sys/zfs_znode.h> |
40 #include <sys/zfs_znode.h> |
41 #include <sys/spa_impl.h> |
41 #include <sys/spa_impl.h> |
42 #include <sys/dsl_deadlist.h> |
42 #include <sys/dsl_deadlist.h> |
|
43 #include <sys/bptree.h> |
|
44 #include <sys/zfeature.h> |
43 |
45 |
44 int zfs_no_write_throttle = 0; |
46 int zfs_no_write_throttle = 0; |
45 int zfs_write_limit_shift = 3; /* 1/8th of physical memory */ |
47 int zfs_write_limit_shift = 3; /* 1/8th of physical memory */ |
46 int zfs_txg_synctime_ms = 1000; /* target millisecs to sync a txg */ |
48 int zfs_txg_synctime_ms = 1000; /* target millisecs to sync a txg */ |
47 |
49 |
98 |
100 |
99 return (dp); |
101 return (dp); |
100 } |
102 } |
101 |
103 |
102 int |
104 int |
103 dsl_pool_open(spa_t *spa, uint64_t txg, dsl_pool_t **dpp) |
105 dsl_pool_init(spa_t *spa, uint64_t txg, dsl_pool_t **dpp) |
104 { |
106 { |
105 int err; |
107 int err; |
106 dsl_pool_t *dp = dsl_pool_open_impl(spa, txg); |
108 dsl_pool_t *dp = dsl_pool_open_impl(spa, txg); |
|
109 |
|
110 err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp, |
|
111 &dp->dp_meta_objset); |
|
112 if (err != 0) |
|
113 dsl_pool_close(dp); |
|
114 else |
|
115 *dpp = dp; |
|
116 |
|
117 return (err); |
|
118 } |
|
119 |
|
120 int |
|
121 dsl_pool_open(dsl_pool_t *dp) |
|
122 { |
|
123 int err; |
107 dsl_dir_t *dd; |
124 dsl_dir_t *dd; |
108 dsl_dataset_t *ds; |
125 dsl_dataset_t *ds; |
109 uint64_t obj; |
126 uint64_t obj; |
110 |
127 |
|
128 ASSERT(!dmu_objset_is_dirty_anywhere(dp->dp_meta_objset)); |
|
129 |
111 rw_enter(&dp->dp_config_rwlock, RW_WRITER); |
130 rw_enter(&dp->dp_config_rwlock, RW_WRITER); |
112 err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp, |
|
113 &dp->dp_meta_objset); |
|
114 if (err) |
|
115 goto out; |
|
116 |
|
117 err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, |
131 err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, |
118 DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1, |
132 DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1, |
119 &dp->dp_root_dir_obj); |
133 &dp->dp_root_dir_obj); |
120 if (err) |
134 if (err) |
121 goto out; |
135 goto out; |
127 |
141 |
128 err = dsl_pool_open_special_dir(dp, MOS_DIR_NAME, &dp->dp_mos_dir); |
142 err = dsl_pool_open_special_dir(dp, MOS_DIR_NAME, &dp->dp_mos_dir); |
129 if (err) |
143 if (err) |
130 goto out; |
144 goto out; |
131 |
145 |
132 if (spa_version(spa) >= SPA_VERSION_ORIGIN) { |
146 if (spa_version(dp->dp_spa) >= SPA_VERSION_ORIGIN) { |
133 err = dsl_pool_open_special_dir(dp, ORIGIN_DIR_NAME, &dd); |
147 err = dsl_pool_open_special_dir(dp, ORIGIN_DIR_NAME, &dd); |
134 if (err) |
148 if (err) |
135 goto out; |
149 goto out; |
136 err = dsl_dataset_hold_obj(dp, dd->dd_phys->dd_head_dataset_obj, |
150 err = dsl_dataset_hold_obj(dp, dd->dd_phys->dd_head_dataset_obj, |
137 FTAG, &ds); |
151 FTAG, &ds); |
156 DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj); |
170 DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj); |
157 if (err) |
171 if (err) |
158 goto out; |
172 goto out; |
159 VERIFY3U(0, ==, bpobj_open(&dp->dp_free_bpobj, |
173 VERIFY3U(0, ==, bpobj_open(&dp->dp_free_bpobj, |
160 dp->dp_meta_objset, obj)); |
174 dp->dp_meta_objset, obj)); |
|
175 } |
|
176 |
|
177 if (spa_feature_is_active(dp->dp_spa, |
|
178 &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) { |
|
179 err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, |
|
180 DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1, |
|
181 &dp->dp_bptree_obj); |
|
182 if (err != 0) |
|
183 goto out; |
161 } |
184 } |
162 |
185 |
163 err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, |
186 err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, |
164 DMU_POOL_TMP_USERREFS, sizeof (uint64_t), 1, |
187 DMU_POOL_TMP_USERREFS, sizeof (uint64_t), 1, |
165 &dp->dp_tmp_userrefs_obj); |
188 &dp->dp_tmp_userrefs_obj); |
166 if (err == ENOENT) |
189 if (err == ENOENT) |
167 err = 0; |
190 err = 0; |
168 if (err) |
191 if (err) |
169 goto out; |
192 goto out; |
170 |
193 |
171 err = dsl_scan_init(dp, txg); |
194 err = dsl_scan_init(dp, dp->dp_tx.tx_open_txg); |
172 |
195 |
173 out: |
196 out: |
174 rw_exit(&dp->dp_config_rwlock); |
197 rw_exit(&dp->dp_config_rwlock); |
175 if (err) |
|
176 dsl_pool_close(dp); |
|
177 else |
|
178 *dpp = dp; |
|
179 |
|
180 return (err); |
198 return (err); |
181 } |
199 } |
182 |
200 |
183 void |
201 void |
184 dsl_pool_close(dsl_pool_t *dp) |
202 dsl_pool_close(dsl_pool_t *dp) |
786 objset_t *mos = dp->dp_meta_objset; |
804 objset_t *mos = dp->dp_meta_objset; |
787 |
805 |
788 ASSERT(dp->dp_tmp_userrefs_obj == 0); |
806 ASSERT(dp->dp_tmp_userrefs_obj == 0); |
789 ASSERT(dmu_tx_is_syncing(tx)); |
807 ASSERT(dmu_tx_is_syncing(tx)); |
790 |
808 |
791 dp->dp_tmp_userrefs_obj = zap_create(mos, DMU_OT_USERREFS, |
809 dp->dp_tmp_userrefs_obj = zap_create_link(mos, DMU_OT_USERREFS, |
792 DMU_OT_NONE, 0, tx); |
810 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_TMP_USERREFS, tx); |
793 |
|
794 VERIFY(zap_add(mos, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_TMP_USERREFS, |
|
795 sizeof (uint64_t), 1, &dp->dp_tmp_userrefs_obj, tx) == 0); |
|
796 } |
811 } |
797 |
812 |
798 static int |
813 static int |
799 dsl_pool_user_hold_rele_impl(dsl_pool_t *dp, uint64_t dsobj, |
814 dsl_pool_user_hold_rele_impl(dsl_pool_t *dp, uint64_t dsobj, |
800 const char *tag, uint64_t *now, dmu_tx_t *tx, boolean_t holding) |
815 const char *tag, uint64_t *now, dmu_tx_t *tx, boolean_t holding) |