Skip to content

Commit

Permalink
Raw receives must compress metadnode blocks
Browse files Browse the repository at this point in the history
Currently, the DMU relies on ZIO layer compression to free LO
dnode blocks that no longer have objects in them. However,
raw receives disable all compression, meaning that these blocks
can never be freed. In addition to the obvious space concerns,
this could also cause incremental raw receives to fail to mount
since the MAC of a hole is different from that of a completely
zeroed block.

This patch corrects this issue by adding a special case in
zio_write_compress() which will attempt to compress these blocks
to a hole even if ZIO_FLAG_RAW_ENCRYPT is set. This patch also
removes the zfs_mdcomp_disable tunable, since tuning it could
cause these same issues.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
  • Loading branch information
Tom Caputi authored and lundman committed Jul 12, 2018
1 parent 61f53ad commit 5f27a49
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 28 deletions.
11 changes: 0 additions & 11 deletions man/man5/zfs-module-parameters.5
Expand Up @@ -1144,17 +1144,6 @@ regardless of this setting.
Default value: \fB1,048,576\fR.
.RE

.sp
.ne 2
.na
\fBzfs_mdcomp_disable\fR (int)
.ad
.RS 12n
Disable meta data compression
.sp
Use \fB1\fR for yes and \fB0\fR for no (default).
.RE

.sp
.ne 2
.na
Expand Down
2 changes: 1 addition & 1 deletion module/zfs/dbuf.c
Expand Up @@ -3477,7 +3477,7 @@ dbuf_prepare_encrypted_dnode_leaf(dbuf_dirty_record_t *dr)
dmu_objset_id(db->db_objset),
dr->dt.dl.dr_byteorder, DMU_OT_DNODE,
dr->dt.dl.dr_salt, dr->dt.dl.dr_iv, dr->dt.dl.dr_mac);
}
}
}

/*
Expand Down
16 changes: 6 additions & 10 deletions module/zfs/dmu.c
Expand Up @@ -2400,16 +2400,12 @@ dmu_write_policy(objset_t *os, dnode_t *dn, int level, int wp, zio_prop_t *zp)
* 3. all other level 0 blocks
*/
if (ismd) {
if (zfs_mdcomp_disable) {
compress = ZIO_COMPRESS_EMPTY;
} else {
/*
* XXX -- we should design a compression algorithm
* that specializes in arrays of bps.
*/
compress = zio_compress_select(os->os_spa,
ZIO_COMPRESS_ON, ZIO_COMPRESS_ON);
}
/*
* XXX -- we should design a compression algorithm
* that specializes in arrays of bps.
*/
compress = zio_compress_select(os->os_spa,
ZIO_COMPRESS_ON, ZIO_COMPRESS_ON);

/*
* Metadata always gets checksummed. If the data
Expand Down
13 changes: 13 additions & 0 deletions module/zfs/zio.c
Expand Up @@ -1630,6 +1630,19 @@ zio_write_compress(zio_t *zio)
*bp = zio->io_bp_orig;
zio->io_pipeline = zio->io_orig_pipeline;

} else if ((zio->io_flags & ZIO_FLAG_RAW_ENCRYPT) != 0 &&
zp->zp_type == DMU_OT_DNODE) {
/*
* The DMU actually relies on the zio layer's compression
* to free metadnode blocks that have had all contained
* dnodes freed. As a result, even when doing a raw
* receive, we must check whether the block can be compressed
* to a hole.
*/
psize = zio_compress_data(ZIO_COMPRESS_EMPTY,
zio->io_abd, NULL, lsize);
if (psize == 0)
compress = ZIO_COMPRESS_OFF;
} else {
ASSERT3U(psize, !=, 0);
}
Expand Down
Expand Up @@ -74,12 +74,6 @@ log_must mkfile -n 32M /$TESTPOOL/$TESTFS2/truncated
log_must truncate -s 4M /$TESTPOOL/$TESTFS2/truncated
sync

log_must set_metadata_compression_disabled 1
log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS2/no_mdcomp \
count=1 bs=512 seek=10G >/dev/null 2>&1
sync
log_must set_metadata_compression_disabled 0

log_must mkdir -p /$TESTPOOL/$TESTFS2/dir
for i in {1..1000}; do
log_must mkfile 512 /$TESTPOOL/$TESTFS2/dir/file-$i
Expand Down

0 comments on commit 5f27a49

Please sign in to comment.