I've noticed that the dsl_dataset_t that points to a given dataset 
changes during the life time of a 'zfs create' command.  We start out 
with one dsl_dataset_t* during dmu_objset_create_sync() but by the time 
we are later mounting the dataset we have a different in memory 
dsl_dataset_t* referring to the same dataset.

This causes me a big issue with per dataset provided encryption keys, 
but not with a per pool provided encryption key.

When keyscope=dataset we pass the key value used as the wrapping key 
down over the ioctl as part of the dataset creation.  This makes its way 
via dmu_objset_create_sync() to dsl_crypto_key_gen() which generates the 
actual encryption key and wraps it using the key that came over the 
ioctl, it then stores the wrapped key on disk using zap_update.  All 
this part works just fine.  The last thing that dsl_crypto_key_gen() 
does is place the encryption key into ds>ds_key so it can be used later. 
   When keyscope=pool the only difference with the above is that the 
wrapping key is already present in spa->spa_key.

The problem occurs when the userland zfs_create() attempts to mount the 
newly created dataset.  The dsl_dataset_t* that was valid during the 
creation isn't available anymore and since there is no key we can't 
mount the dataset.

Have I done something fundamentally wrong by hanging the crypto key off 
the dsl_dataset_t ?  Is there a better choice that is always going to be 
in memory for a given dataset through the whole 'zfs create' operation ?

-- 
Darren J Moffat

Reply via email to