int dmu_objset_snapshot(char *fsname, char *snapname, boolean_t recursive) { dsl_sync_task_t *dst; struct osnode *osn; struct snaparg sn = { 0 }; spa_t *spa; int err; (void) strcpy(sn.failed, fsname); err = spa_open(fsname, &spa, FTAG); if (err) return (err); sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); sn.snapname = snapname; list_create(&sn.objsets, sizeof (struct osnode), offsetof(struct osnode, node)); if (recursive) { sn.checkperms = B_TRUE; err = dmu_objset_find(fsname, dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN); } else { sn.checkperms = B_FALSE; err = dmu_objset_snapshot_one(fsname, &sn); } if (err) goto out; err = dsl_sync_task_group_wait(sn.dstg); for (dst = list_head(&sn.dstg->dstg_tasks); dst; dst = list_next(&sn.dstg->dstg_tasks, dst)) { dsl_dataset_t *ds = dst->dst_arg1; if (dst->dst_err) dsl_dataset_name(ds, sn.failed); } out: while (osn = list_head(&sn.objsets)) { list_remove(&sn.objsets, osn); zil_resume(dmu_objset_zil(osn->os)); dmu_objset_close(osn->os); kmem_free(osn, sizeof (struct osnode)); } list_destroy(&sn.objsets); if (err) (void) strcpy(fsname, sn.failed); dsl_sync_task_group_destroy(sn.dstg); spa_close(spa, FTAG); return (err); }
int dmu_objset_snapshot(char *fsname, char *snapname, nvlist_t *props, boolean_t recursive) { dsl_sync_task_t *dst; struct snaparg *sn; spa_t *spa; int err; sn = kmem_alloc(sizeof (struct snaparg), KM_SLEEP); (void) strcpy(sn->failed, fsname); err = spa_open(fsname, &spa, FTAG); if (err) { kmem_free(sn, sizeof (struct snaparg)); return (err); } sn->dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); sn->snapname = snapname; sn->props = props; if (recursive) { sn->checkperms = B_TRUE; err = dmu_objset_find(fsname, dmu_objset_snapshot_one, sn, DS_FIND_CHILDREN); } else { sn->checkperms = B_FALSE; err = dmu_objset_snapshot_one(fsname, sn); } if (err == 0) err = dsl_sync_task_group_wait(sn->dstg); for (dst = list_head(&sn->dstg->dstg_tasks); dst; dst = list_next(&sn->dstg->dstg_tasks, dst)) { objset_t *os = dst->dst_arg1; dsl_dataset_t *ds = os->os->os_dsl_dataset; if (dst->dst_err) dsl_dataset_name(ds, sn->failed); zil_resume(dmu_objset_zil(os)); dmu_objset_close(os); } if (err) (void) strcpy(fsname, sn->failed); dsl_sync_task_group_destroy(sn->dstg); spa_close(spa, FTAG); kmem_free(sn, sizeof (struct snaparg)); return (err); }
/* ARGSUSED */ int zil_vdev_offline(char *osname, void *arg) { objset_t *os; zilog_t *zilog; int error; error = dmu_objset_open(osname, DMU_OST_ANY, DS_MODE_USER, &os); if (error) return (error); zilog = dmu_objset_zil(os); if (zil_suspend(zilog) != 0) error = EEXIST; else zil_resume(zilog); dmu_objset_close(os); return (error); }
int dsl_crypto_key_new(const char *dsname) { dsl_dataset_t *ds; objset_t *os; zcrypt_keystore_node_t *skn; spa_t *spa; struct knarg arg; int error; dsl_pool_t *dp; void *cookie; error = dsl_pool_hold(dsname, FTAG, &dp); if (error != 0) return (error); if ((error = dsl_dataset_hold(dp, dsname, FTAG, &ds)) != 0) { dsl_pool_rele(dp, FTAG); return (error); } if (dsl_dataset_is_snapshot(ds)) { dsl_dataset_rele(ds, FTAG); dsl_pool_rele(dp, FTAG); return (ENOTSUP); } if ((error = dmu_objset_from_ds(ds, &os)) != 0) { dsl_dataset_rele(ds, FTAG); dsl_pool_rele(dp, FTAG); return (error); } if (os->os_crypt == ZIO_CRYPT_OFF) { dsl_dataset_rele(ds, FTAG); dsl_pool_rele(dp, FTAG); return (ENOTSUP); } ASSERT(os->os_crypt != ZIO_CRYPT_INHERIT); /* * Need the keychain and wrapping key to already be available. */ spa = dsl_dataset_get_spa(ds); skn = zcrypt_keystore_find_node(spa, ds->ds_object, B_FALSE); if (skn == NULL) { dsl_dataset_rele(ds, FTAG); dsl_pool_rele(dp, FTAG); return (ENOENT); } ASSERT(ds != NULL); ASSERT(ds->ds_objset != NULL); //zil_suspend_dmu_sync(dmu_objset_zil(os)); zil_suspend(dsname, &cookie); arg.kn_skn = skn; arg.kn_txgkey = zcrypt_key_gen(os->os_crypt); arg.kn_ds = ds; zcrypt_key_hold(skn->skn_wrapkey, FTAG); VERIFY(zcrypt_wrap_key(skn->skn_wrapkey, arg.kn_txgkey, &arg.kn_wkeybuf, &arg.kn_wkeylen, zio_crypt_select_wrap(os->os_crypt)) == 0); error = dsl_sync_task(spa->spa_name, dsl_crypto_key_new_check, dsl_crypto_key_new_sync, &arg, 1, ZFS_SPACE_CHECK_NONE); kmem_free(arg.kn_wkeybuf, arg.kn_wkeylen); zcrypt_key_release(skn->skn_wrapkey, FTAG); //zil_resume_dmu_sync(dmu_objset_zil(os)); zil_resume(os); dsl_dataset_rele(ds, FTAG); dsl_pool_rele(dp, FTAG); if (error) zcrypt_key_free(arg.kn_txgkey); return (error); }