mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-25 11:47:43 +03:00
Decryption error handling improvements
Currently, the decryption and block authentication code in the ZIO / ARC layers is a bit inconsistent with regards to the ereports that are produces and the error codes that are passed to calling functions. This patch ensures that all of these errors (which begin as ECKSUM) are converted to EIO before they leave the ZIO or ARC layer and that ereports are correctly generated on each decryption / authentication failure. In addition, this patch fixes a bug in zio_decrypt() where ECKSUM never gets written to zio->io_error. Reviewed by: Matt Ahrens <matt@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Tom Caputi <tcaputi@datto.com> Closes #7372
This commit is contained in:
committed by
Brian Behlendorf
parent
4515b1d01c
commit
a2c2ed1bd4
+14
-6
@@ -1194,8 +1194,10 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags)
|
||||
DMU_OT_IS_ENCRYPTED(dn->dn_bonustype) &&
|
||||
(flags & DB_RF_NO_DECRYPT) == 0 &&
|
||||
arc_is_encrypted(dn_buf)) {
|
||||
SET_BOOKMARK(&zb, dmu_objset_id(db->db_objset),
|
||||
DMU_META_DNODE_OBJECT, 0, dn->dn_dbuf->db_blkid);
|
||||
err = arc_untransform(dn_buf, dn->dn_objset->os_spa,
|
||||
dmu_objset_id(dn->dn_objset), B_TRUE);
|
||||
&zb, B_TRUE);
|
||||
if (err != 0) {
|
||||
DB_DNODE_EXIT(db);
|
||||
mutex_exit(&db->db_mtx);
|
||||
@@ -1264,8 +1266,7 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags)
|
||||
if (DBUF_IS_L2CACHEABLE(db))
|
||||
aflags |= ARC_FLAG_L2CACHE;
|
||||
|
||||
SET_BOOKMARK(&zb, db->db_objset->os_dsl_dataset ?
|
||||
db->db_objset->os_dsl_dataset->ds_object : DMU_META_OBJSET,
|
||||
SET_BOOKMARK(&zb, dmu_objset_id(db->db_objset),
|
||||
db->db.db_object, db->db_level, db->db_blkid);
|
||||
|
||||
/*
|
||||
@@ -1409,9 +1410,12 @@ dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags)
|
||||
if (db->db_buf != NULL && (flags & DB_RF_NO_DECRYPT) == 0 &&
|
||||
(arc_is_encrypted(db->db_buf) ||
|
||||
arc_get_compression(db->db_buf) != ZIO_COMPRESS_OFF)) {
|
||||
zbookmark_phys_t zb;
|
||||
|
||||
SET_BOOKMARK(&zb, dmu_objset_id(db->db_objset),
|
||||
db->db.db_object, db->db_level, db->db_blkid);
|
||||
dbuf_fix_old_data(db, spa_syncing_txg(spa));
|
||||
err = arc_untransform(db->db_buf, spa,
|
||||
dmu_objset_id(db->db_objset), B_FALSE);
|
||||
err = arc_untransform(db->db_buf, spa, &zb, B_FALSE);
|
||||
dbuf_set_data(db, db->db_buf);
|
||||
}
|
||||
mutex_exit(&db->db_mtx);
|
||||
@@ -3458,6 +3462,8 @@ dbuf_check_crypt(dbuf_dirty_record_t *dr)
|
||||
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||
|
||||
if (!dr->dt.dl.dr_raw && arc_is_encrypted(db->db_buf)) {
|
||||
zbookmark_phys_t zb;
|
||||
|
||||
/*
|
||||
* Unfortunately, there is currently no mechanism for
|
||||
* syncing context to handle decryption errors. An error
|
||||
@@ -3465,8 +3471,10 @@ dbuf_check_crypt(dbuf_dirty_record_t *dr)
|
||||
* changed a dnode block and updated the associated
|
||||
* checksums going up the block tree.
|
||||
*/
|
||||
SET_BOOKMARK(&zb, dmu_objset_id(db->db_objset),
|
||||
db->db.db_object, db->db_level, db->db_blkid);
|
||||
err = arc_untransform(db->db_buf, db->db_objset->os_spa,
|
||||
dmu_objset_id(db->db_objset), B_TRUE);
|
||||
&zb, B_TRUE);
|
||||
if (err)
|
||||
panic("Invalid dnode block MAC");
|
||||
} else if (dr->dt.dl.dr_raw) {
|
||||
|
||||
Reference in New Issue
Block a user