153 err = dsl_dataset_hold_obj(dp,
154 ds->ds_phys->ds_prev_snap_obj, dp,
155 &dp->dp_origin_snap);
156 dsl_dataset_rele(ds, FTAG);
157 }
158 dsl_dir_close(dd, dp);
159 if (err)
160 goto out;
161 }
162
163 if (spa_version(dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
164 err = dsl_pool_open_special_dir(dp, FREE_DIR_NAME,
165 &dp->dp_free_dir);
166 if (err)
167 goto out;
168
169 err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
170 DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj);
171 if (err)
172 goto out;
173 VERIFY3U(0, ==, bpobj_open(&dp->dp_free_bpobj,
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;
184 }
185
186 err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
187 DMU_POOL_TMP_USERREFS, sizeof (uint64_t), 1,
188 &dp->dp_tmp_userrefs_obj);
189 if (err == ENOENT)
190 err = 0;
191 if (err)
192 goto out;
193
239 kmem_free(dp, sizeof (dsl_pool_t));
240 }
241
242 dsl_pool_t *
243 dsl_pool_create(spa_t *spa, nvlist_t *zplprops, uint64_t txg)
244 {
245 int err;
246 dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);
247 dmu_tx_t *tx = dmu_tx_create_assigned(dp, txg);
248 objset_t *os;
249 dsl_dataset_t *ds;
250 uint64_t obj;
251
252 /* create and open the MOS (meta-objset) */
253 dp->dp_meta_objset = dmu_objset_create_impl(spa,
254 NULL, &dp->dp_meta_rootbp, DMU_OST_META, tx);
255
256 /* create the pool directory */
257 err = zap_create_claim(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
258 DMU_OT_OBJECT_DIRECTORY, DMU_OT_NONE, 0, tx);
259 ASSERT3U(err, ==, 0);
260
261 /* Initialize scan structures */
262 VERIFY3U(0, ==, dsl_scan_init(dp, txg));
263
264 /* create and open the root dir */
265 dp->dp_root_dir_obj = dsl_dir_create_sync(dp, NULL, NULL, tx);
266 VERIFY(0 == dsl_dir_open_obj(dp, dp->dp_root_dir_obj,
267 NULL, dp, &dp->dp_root_dir));
268
269 /* create and open the meta-objset dir */
270 (void) dsl_dir_create_sync(dp, dp->dp_root_dir, MOS_DIR_NAME, tx);
271 VERIFY(0 == dsl_pool_open_special_dir(dp,
272 MOS_DIR_NAME, &dp->dp_mos_dir));
273
274 if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
275 /* create and open the free dir */
276 (void) dsl_dir_create_sync(dp, dp->dp_root_dir,
277 FREE_DIR_NAME, tx);
278 VERIFY(0 == dsl_pool_open_special_dir(dp,
279 FREE_DIR_NAME, &dp->dp_free_dir));
280
281 /* create and open the free_bplist */
282 obj = bpobj_alloc(dp->dp_meta_objset, SPA_MAXBLOCKSIZE, tx);
283 VERIFY(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
284 DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx) == 0);
285 VERIFY3U(0, ==, bpobj_open(&dp->dp_free_bpobj,
286 dp->dp_meta_objset, obj));
287 }
288
289 if (spa_version(spa) >= SPA_VERSION_DSL_SCRUB)
290 dsl_pool_create_origin(dp, tx);
291
292 /* create the root dataset */
293 obj = dsl_dataset_create_sync_dd(dp->dp_root_dir, NULL, 0, tx);
294
295 /* create the root objset */
296 VERIFY(0 == dsl_dataset_hold_obj(dp, obj, FTAG, &ds));
297 os = dmu_objset_create_impl(dp->dp_spa, ds,
298 dsl_dataset_get_blkptr(ds), DMU_OST_ZFS, tx);
299 #ifdef _KERNEL
300 zfs_create_fs(os, kcred, zplprops, tx);
301 #endif
302 dsl_dataset_rele(ds, FTAG);
303
304 dmu_tx_commit(tx);
305
657 dmu_buf_will_dirty(prev->ds_dbuf, tx);
658 prev->ds_phys->ds_next_clones_obj =
659 zap_create(dp->dp_meta_objset,
660 DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx);
661 }
662 VERIFY(0 == zap_add_int(dp->dp_meta_objset,
663 prev->ds_phys->ds_next_clones_obj, ds->ds_object, tx));
664
665 dsl_dataset_rele(ds, FTAG);
666 if (prev != dp->dp_origin_snap)
667 dsl_dataset_rele(prev, FTAG);
668 return (0);
669 }
670
671 void
672 dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx)
673 {
674 ASSERT(dmu_tx_is_syncing(tx));
675 ASSERT(dp->dp_origin_snap != NULL);
676
677 VERIFY3U(0, ==, dmu_objset_find_spa(dp->dp_spa, NULL, upgrade_clones_cb,
678 tx, DS_FIND_CHILDREN));
679 }
680
681 /* ARGSUSED */
682 static int
683 upgrade_dir_clones_cb(spa_t *spa, uint64_t dsobj, const char *dsname, void *arg)
684 {
685 dmu_tx_t *tx = arg;
686 dsl_dataset_t *ds;
687 dsl_pool_t *dp = spa_get_dsl(spa);
688 objset_t *mos = dp->dp_meta_objset;
689
690 VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
691
692 if (ds->ds_dir->dd_phys->dd_origin_obj) {
693 dsl_dataset_t *origin;
694
695 VERIFY3U(0, ==, dsl_dataset_hold_obj(dp,
696 ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &origin));
697
698 if (origin->ds_dir->dd_phys->dd_clones == 0) {
699 dmu_buf_will_dirty(origin->ds_dir->dd_dbuf, tx);
700 origin->ds_dir->dd_phys->dd_clones = zap_create(mos,
701 DMU_OT_DSL_CLONES, DMU_OT_NONE, 0, tx);
702 }
703
704 VERIFY3U(0, ==, zap_add_int(dp->dp_meta_objset,
705 origin->ds_dir->dd_phys->dd_clones, dsobj, tx));
706
707 dsl_dataset_rele(origin, FTAG);
708 }
709
710 dsl_dataset_rele(ds, FTAG);
711 return (0);
712 }
713
714 void
715 dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx)
716 {
717 ASSERT(dmu_tx_is_syncing(tx));
718 uint64_t obj;
719
720 (void) dsl_dir_create_sync(dp, dp->dp_root_dir, FREE_DIR_NAME, tx);
721 VERIFY(0 == dsl_pool_open_special_dir(dp,
722 FREE_DIR_NAME, &dp->dp_free_dir));
723
724 /*
725 * We can't use bpobj_alloc(), because spa_version() still
726 * returns the old version, and we need a new-version bpobj with
727 * subobj support. So call dmu_object_alloc() directly.
728 */
729 obj = dmu_object_alloc(dp->dp_meta_objset, DMU_OT_BPOBJ,
730 SPA_MAXBLOCKSIZE, DMU_OT_BPOBJ_HDR, sizeof (bpobj_phys_t), tx);
731 VERIFY3U(0, ==, zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
732 DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx));
733 VERIFY3U(0, ==, bpobj_open(&dp->dp_free_bpobj,
734 dp->dp_meta_objset, obj));
735
736 VERIFY3U(0, ==, dmu_objset_find_spa(dp->dp_spa, NULL,
737 upgrade_dir_clones_cb, tx, DS_FIND_CHILDREN));
738 }
739
740 void
741 dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx)
742 {
743 uint64_t dsobj;
744 dsl_dataset_t *ds;
745
746 ASSERT(dmu_tx_is_syncing(tx));
747 ASSERT(dp->dp_origin_snap == NULL);
748
749 /* create the origin dir, ds, & snap-ds */
750 rw_enter(&dp->dp_config_rwlock, RW_WRITER);
751 dsobj = dsl_dataset_create_sync(dp->dp_root_dir, ORIGIN_DIR_NAME,
752 NULL, 0, kcred, tx);
753 VERIFY(0 == dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
754 dsl_dataset_snapshot_sync(ds, ORIGIN_DIR_NAME, tx);
755 VERIFY(0 == dsl_dataset_hold_obj(dp, ds->ds_phys->ds_prev_snap_obj,
756 dp, &dp->dp_origin_snap));
|
153 err = dsl_dataset_hold_obj(dp,
154 ds->ds_phys->ds_prev_snap_obj, dp,
155 &dp->dp_origin_snap);
156 dsl_dataset_rele(ds, FTAG);
157 }
158 dsl_dir_close(dd, dp);
159 if (err)
160 goto out;
161 }
162
163 if (spa_version(dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
164 err = dsl_pool_open_special_dir(dp, FREE_DIR_NAME,
165 &dp->dp_free_dir);
166 if (err)
167 goto out;
168
169 err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
170 DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj);
171 if (err)
172 goto out;
173 VERIFY0(bpobj_open(&dp->dp_free_bpobj,
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;
184 }
185
186 err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
187 DMU_POOL_TMP_USERREFS, sizeof (uint64_t), 1,
188 &dp->dp_tmp_userrefs_obj);
189 if (err == ENOENT)
190 err = 0;
191 if (err)
192 goto out;
193
239 kmem_free(dp, sizeof (dsl_pool_t));
240 }
241
242 dsl_pool_t *
243 dsl_pool_create(spa_t *spa, nvlist_t *zplprops, uint64_t txg)
244 {
245 int err;
246 dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);
247 dmu_tx_t *tx = dmu_tx_create_assigned(dp, txg);
248 objset_t *os;
249 dsl_dataset_t *ds;
250 uint64_t obj;
251
252 /* create and open the MOS (meta-objset) */
253 dp->dp_meta_objset = dmu_objset_create_impl(spa,
254 NULL, &dp->dp_meta_rootbp, DMU_OST_META, tx);
255
256 /* create the pool directory */
257 err = zap_create_claim(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
258 DMU_OT_OBJECT_DIRECTORY, DMU_OT_NONE, 0, tx);
259 ASSERT0(err);
260
261 /* Initialize scan structures */
262 VERIFY0(dsl_scan_init(dp, txg));
263
264 /* create and open the root dir */
265 dp->dp_root_dir_obj = dsl_dir_create_sync(dp, NULL, NULL, tx);
266 VERIFY(0 == dsl_dir_open_obj(dp, dp->dp_root_dir_obj,
267 NULL, dp, &dp->dp_root_dir));
268
269 /* create and open the meta-objset dir */
270 (void) dsl_dir_create_sync(dp, dp->dp_root_dir, MOS_DIR_NAME, tx);
271 VERIFY(0 == dsl_pool_open_special_dir(dp,
272 MOS_DIR_NAME, &dp->dp_mos_dir));
273
274 if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
275 /* create and open the free dir */
276 (void) dsl_dir_create_sync(dp, dp->dp_root_dir,
277 FREE_DIR_NAME, tx);
278 VERIFY(0 == dsl_pool_open_special_dir(dp,
279 FREE_DIR_NAME, &dp->dp_free_dir));
280
281 /* create and open the free_bplist */
282 obj = bpobj_alloc(dp->dp_meta_objset, SPA_MAXBLOCKSIZE, tx);
283 VERIFY(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
284 DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx) == 0);
285 VERIFY0(bpobj_open(&dp->dp_free_bpobj,
286 dp->dp_meta_objset, obj));
287 }
288
289 if (spa_version(spa) >= SPA_VERSION_DSL_SCRUB)
290 dsl_pool_create_origin(dp, tx);
291
292 /* create the root dataset */
293 obj = dsl_dataset_create_sync_dd(dp->dp_root_dir, NULL, 0, tx);
294
295 /* create the root objset */
296 VERIFY(0 == dsl_dataset_hold_obj(dp, obj, FTAG, &ds));
297 os = dmu_objset_create_impl(dp->dp_spa, ds,
298 dsl_dataset_get_blkptr(ds), DMU_OST_ZFS, tx);
299 #ifdef _KERNEL
300 zfs_create_fs(os, kcred, zplprops, tx);
301 #endif
302 dsl_dataset_rele(ds, FTAG);
303
304 dmu_tx_commit(tx);
305
657 dmu_buf_will_dirty(prev->ds_dbuf, tx);
658 prev->ds_phys->ds_next_clones_obj =
659 zap_create(dp->dp_meta_objset,
660 DMU_OT_NEXT_CLONES, DMU_OT_NONE, 0, tx);
661 }
662 VERIFY(0 == zap_add_int(dp->dp_meta_objset,
663 prev->ds_phys->ds_next_clones_obj, ds->ds_object, tx));
664
665 dsl_dataset_rele(ds, FTAG);
666 if (prev != dp->dp_origin_snap)
667 dsl_dataset_rele(prev, FTAG);
668 return (0);
669 }
670
671 void
672 dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx)
673 {
674 ASSERT(dmu_tx_is_syncing(tx));
675 ASSERT(dp->dp_origin_snap != NULL);
676
677 VERIFY0(dmu_objset_find_spa(dp->dp_spa, NULL, upgrade_clones_cb,
678 tx, DS_FIND_CHILDREN));
679 }
680
681 /* ARGSUSED */
682 static int
683 upgrade_dir_clones_cb(spa_t *spa, uint64_t dsobj, const char *dsname, void *arg)
684 {
685 dmu_tx_t *tx = arg;
686 dsl_dataset_t *ds;
687 dsl_pool_t *dp = spa_get_dsl(spa);
688 objset_t *mos = dp->dp_meta_objset;
689
690 VERIFY0(dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
691
692 if (ds->ds_dir->dd_phys->dd_origin_obj) {
693 dsl_dataset_t *origin;
694
695 VERIFY0(dsl_dataset_hold_obj(dp,
696 ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &origin));
697
698 if (origin->ds_dir->dd_phys->dd_clones == 0) {
699 dmu_buf_will_dirty(origin->ds_dir->dd_dbuf, tx);
700 origin->ds_dir->dd_phys->dd_clones = zap_create(mos,
701 DMU_OT_DSL_CLONES, DMU_OT_NONE, 0, tx);
702 }
703
704 VERIFY0(zap_add_int(dp->dp_meta_objset,
705 origin->ds_dir->dd_phys->dd_clones, dsobj, tx));
706
707 dsl_dataset_rele(origin, FTAG);
708 }
709
710 dsl_dataset_rele(ds, FTAG);
711 return (0);
712 }
713
714 void
715 dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx)
716 {
717 ASSERT(dmu_tx_is_syncing(tx));
718 uint64_t obj;
719
720 (void) dsl_dir_create_sync(dp, dp->dp_root_dir, FREE_DIR_NAME, tx);
721 VERIFY(0 == dsl_pool_open_special_dir(dp,
722 FREE_DIR_NAME, &dp->dp_free_dir));
723
724 /*
725 * We can't use bpobj_alloc(), because spa_version() still
726 * returns the old version, and we need a new-version bpobj with
727 * subobj support. So call dmu_object_alloc() directly.
728 */
729 obj = dmu_object_alloc(dp->dp_meta_objset, DMU_OT_BPOBJ,
730 SPA_MAXBLOCKSIZE, DMU_OT_BPOBJ_HDR, sizeof (bpobj_phys_t), tx);
731 VERIFY0(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
732 DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx));
733 VERIFY0(bpobj_open(&dp->dp_free_bpobj,
734 dp->dp_meta_objset, obj));
735
736 VERIFY0(dmu_objset_find_spa(dp->dp_spa, NULL,
737 upgrade_dir_clones_cb, tx, DS_FIND_CHILDREN));
738 }
739
740 void
741 dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx)
742 {
743 uint64_t dsobj;
744 dsl_dataset_t *ds;
745
746 ASSERT(dmu_tx_is_syncing(tx));
747 ASSERT(dp->dp_origin_snap == NULL);
748
749 /* create the origin dir, ds, & snap-ds */
750 rw_enter(&dp->dp_config_rwlock, RW_WRITER);
751 dsobj = dsl_dataset_create_sync(dp->dp_root_dir, ORIGIN_DIR_NAME,
752 NULL, 0, kcred, tx);
753 VERIFY(0 == dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
754 dsl_dataset_snapshot_sync(ds, ORIGIN_DIR_NAME, tx);
755 VERIFY(0 == dsl_dataset_hold_obj(dp, ds->ds_phys->ds_prev_snap_obj,
756 dp, &dp->dp_origin_snap));
|