Raw DRR_OBJECT records must write raw data

b1d21733 made it possible for empty metadnode blocks to be
compressed to a hole, fixing a bug that would cause invalid
metadnode MACs when a send stream attempted to free objects
and allowing the blocks to be reclaimed when they were no
longer needed. However, this patch also introduced a race
condition; if a txg sync occurred after a DRR_OBJECT_RANGE
record was received but before any objects were added, the
metadnode block would be compressed to a hole and lose all
of its encryption parameters. This would cause subsequent
DRR_OBJECT records to fail when they attempted to write
their data into an unencrypted block. This patch defers the
DRR_OBJECT_RANGE handling to receive_object() so that the
encryption parameters are set with each object that is
written into that block.

Reviewed-by: Kash Pande <kash@tripleback.net>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #7215 
Closes #7236
This commit is contained in:
Tom Caputi
2018-02-27 12:04:05 -05:00
committed by Brian Behlendorf
parent 8b5814393f
commit 095495e008
4 changed files with 72 additions and 55 deletions
+1 -2
View File
@@ -3465,8 +3465,7 @@ dbuf_check_crypt(dbuf_dirty_record_t *dr)
* Writing raw encrypted data requires the db's arc buffer
* to be converted to raw by the caller.
*/
ASSERT(arc_is_encrypted(db->db_buf) ||
db->db.db_object == DMU_META_DNODE_OBJECT);
ASSERT(arc_is_encrypted(db->db_buf));
}
}