int dsl_dataset_keystatus_byname(dsl_pool_t *dp, const char *dsname, zfs_crypt_key_status_t *keystatus) { dsl_dataset_t *ds; int error; error = dsl_dataset_hold(dp, dsname, FTAG, &ds); if (error != 0) { return (error); } *keystatus = dsl_dataset_keystatus(ds, B_FALSE); dsl_dataset_rele(ds, FTAG); return (0); }
/*ARGSUSED*/ static int dmu_objset_create_check(void *arg1, void *arg2, dmu_tx_t *tx) { dsl_dir_t *dd = arg1; struct oscarg *oa = arg2; objset_t *mos = dd->dd_pool->dp_meta_objset; int err; uint64_t ddobj; static boolean_t dp_config_rwlock_held = B_TRUE; err = zap_lookup(mos, dd->dd_phys->dd_child_dir_zapobj, oa->lastname, sizeof (uint64_t), 1, &ddobj); if (err != ENOENT) return (err ? err : EEXIST); if (oa->clone_origin != NULL) { /* You can't clone across pools. */ if (oa->clone_origin->ds_dir->dd_pool != dd->dd_pool) return (EXDEV); /* You can only clone snapshots, not the head datasets. */ if (!dsl_dataset_is_snapshot(oa->clone_origin)) return (EINVAL); if (dsl_dataset_keystatus(oa->clone_origin, dp_config_rwlock_held) == ZFS_CRYPT_KEY_UNAVAILABLE) return (ENOKEY); } /* * Check we have the required crypto algorithms available * via kcf since this is our last chance to fail the dataset creation. */ if (oa->crypto_ctx != NULL && !zcrypt_mech_available(oa->crypto_ctx->dcc_crypt)) { return (ENOTSUP); } return (0); }