#include <sys/fs/zfs.h>
#include <sys/dmu.h>
#include <sys/dmu_objset.h>
+#include <sys/dsl_crypt.h>
#include <sys/spa.h>
#include <sys/txg.h>
#include <sys/dbuf.h>
return (SET_ERROR(EXDEV));
}
+ /*
+ * Cloning across encrypted datasets is possible only if they
+ * share the same master key.
+ */
+ if (inos != outos && inos->os_encrypted &&
+ !dmu_objset_crypto_key_equal(inos, outos)) {
+ zfs_exit_two(inzfsvfs, outzfsvfs, FTAG);
+ return (SET_ERROR(EXDEV));
+ }
+
error = zfs_verify_zp(inzp);
if (error == 0)
error = zfs_verify_zp(outzp);
*/
break;
}
- /*
- * Encrypted data is fine as long as it comes from the same
- * dataset.
- * TODO: We want to extend it in the future to allow cloning to
- * datasets with the same keys, like clones or to be able to
- * clone a file from a snapshot of an encrypted dataset into the
- * dataset itself.
- */
- if (BP_IS_PROTECTED(&bps[0])) {
- if (inzfsvfs != outzfsvfs) {
- error = SET_ERROR(EXDEV);
- break;
- }
- }
/*
* Start a transaction.
}
error = dmu_brt_clone(outos, outzp->z_id, outoff, size, tx,
- bps, nbps, B_FALSE);
+ bps, nbps);
if (error != 0) {
dmu_tx_commit(tx);
break;
if (zp->z_blksz < blksz)
zfs_grow_blocksize(zp, blksz, tx);
- dmu_brt_clone(zfsvfs->z_os, zp->z_id, off, len, tx, bps, nbps, B_TRUE);
+ dmu_brt_clone(zfsvfs->z_os, zp->z_id, off, len, tx, bps, nbps);
zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime);