mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 19:19:32 +03:00
Raw receives must compress metadnode blocks
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> Closes #7198
This commit is contained in:
parent
5121c4fb0c
commit
b1d217338a
@ -1033,8 +1033,6 @@ int dmu_diff(const char *tosnap_name, const char *fromsnap_name,
|
|||||||
#define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */
|
#define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */
|
||||||
extern uint64_t zfs_crc64_table[256];
|
extern uint64_t zfs_crc64_table[256];
|
||||||
|
|
||||||
extern int zfs_mdcomp_disable;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1400,17 +1400,6 @@ regardless of this setting.
|
|||||||
Default value: \fB1,048,576\fR.
|
Default value: \fB1,048,576\fR.
|
||||||
.RE
|
.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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.na
|
.na
|
||||||
|
@ -6776,6 +6776,9 @@ arc_write_ready(zio_t *zio)
|
|||||||
buf->b_flags &= ~ARC_BUF_FLAG_ENCRYPTED;
|
buf->b_flags &= ~ARC_BUF_FLAG_ENCRYPTED;
|
||||||
if (BP_GET_COMPRESS(bp) == ZIO_COMPRESS_OFF)
|
if (BP_GET_COMPRESS(bp) == ZIO_COMPRESS_OFF)
|
||||||
buf->b_flags &= ~ARC_BUF_FLAG_COMPRESSED;
|
buf->b_flags &= ~ARC_BUF_FLAG_COMPRESSED;
|
||||||
|
} else if (BP_IS_HOLE(bp) && ARC_BUF_ENCRYPTED(buf)) {
|
||||||
|
buf->b_flags &= ~ARC_BUF_FLAG_ENCRYPTED;
|
||||||
|
buf->b_flags &= ~ARC_BUF_FLAG_COMPRESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this must be done after the buffer flags are adjusted */
|
/* this must be done after the buffer flags are adjusted */
|
||||||
|
@ -3465,7 +3465,8 @@ dbuf_check_crypt(dbuf_dirty_record_t *dr)
|
|||||||
* Writing raw encrypted data requires the db's arc buffer
|
* Writing raw encrypted data requires the db's arc buffer
|
||||||
* to be converted to raw by the caller.
|
* to be converted to raw by the caller.
|
||||||
*/
|
*/
|
||||||
ASSERT(arc_is_encrypted(db->db_buf));
|
ASSERT(arc_is_encrypted(db->db_buf) ||
|
||||||
|
db->db.db_object == DMU_META_DNODE_OBJECT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2107,8 +2107,6 @@ dmu_object_dirty_raw(objset_t *os, uint64_t object, dmu_tx_t *tx)
|
|||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
int zfs_mdcomp_disable = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When the "redundant_metadata" property is set to "most", only indirect
|
* When the "redundant_metadata" property is set to "most", only indirect
|
||||||
* blocks of this level and higher will have an additional ditto block.
|
* blocks of this level and higher will have an additional ditto block.
|
||||||
@ -2138,16 +2136,12 @@ dmu_write_policy(objset_t *os, dnode_t *dn, int level, int wp, zio_prop_t *zp)
|
|||||||
* 3. all other level 0 blocks
|
* 3. all other level 0 blocks
|
||||||
*/
|
*/
|
||||||
if (ismd) {
|
if (ismd) {
|
||||||
if (zfs_mdcomp_disable) {
|
/*
|
||||||
compress = ZIO_COMPRESS_EMPTY;
|
* XXX -- we should design a compression algorithm
|
||||||
} else {
|
* that specializes in arrays of bps.
|
||||||
/*
|
*/
|
||||||
* XXX -- we should design a compression algorithm
|
compress = zio_compress_select(os->os_spa,
|
||||||
* that specializes in arrays of bps.
|
ZIO_COMPRESS_ON, ZIO_COMPRESS_ON);
|
||||||
*/
|
|
||||||
compress = zio_compress_select(os->os_spa,
|
|
||||||
ZIO_COMPRESS_ON, ZIO_COMPRESS_ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Metadata always gets checksummed. If the data
|
* Metadata always gets checksummed. If the data
|
||||||
@ -2523,9 +2517,6 @@ EXPORT_SYMBOL(dmu_buf_hold);
|
|||||||
EXPORT_SYMBOL(dmu_ot);
|
EXPORT_SYMBOL(dmu_ot);
|
||||||
|
|
||||||
/* BEGIN CSTYLED */
|
/* BEGIN CSTYLED */
|
||||||
module_param(zfs_mdcomp_disable, int, 0644);
|
|
||||||
MODULE_PARM_DESC(zfs_mdcomp_disable, "Disable meta data compression");
|
|
||||||
|
|
||||||
module_param(zfs_nopwrite_enabled, int, 0644);
|
module_param(zfs_nopwrite_enabled, int, 0644);
|
||||||
MODULE_PARM_DESC(zfs_nopwrite_enabled, "Enable NOP writes");
|
MODULE_PARM_DESC(zfs_nopwrite_enabled, "Enable NOP writes");
|
||||||
|
|
||||||
|
@ -1532,9 +1532,21 @@ zio_write_compress(zio_t *zio)
|
|||||||
*bp = zio->io_bp_orig;
|
*bp = zio->io_bp_orig;
|
||||||
zio->io_pipeline = zio->io_orig_pipeline;
|
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 {
|
} else {
|
||||||
ASSERT3U(psize, !=, 0);
|
ASSERT3U(psize, !=, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -39,11 +39,6 @@
|
|||||||
|
|
||||||
verify_runnable "both"
|
verify_runnable "both"
|
||||||
|
|
||||||
function set_metadata_compression_disabled # <0|1>
|
|
||||||
{
|
|
||||||
echo $1 > /sys/module/zfs/parameters/zfs_mdcomp_disable
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanup
|
function cleanup
|
||||||
{
|
{
|
||||||
datasetexists $TESTPOOL/$TESTFS2 && \
|
datasetexists $TESTPOOL/$TESTFS2 && \
|
||||||
@ -73,12 +68,6 @@ log_must mkfile 32M /$TESTPOOL/$TESTFS2/truncated
|
|||||||
log_must truncate -s 4M /$TESTPOOL/$TESTFS2/truncated
|
log_must truncate -s 4M /$TESTPOOL/$TESTFS2/truncated
|
||||||
sync
|
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
|
log_must mkdir -p /$TESTPOOL/$TESTFS2/dir
|
||||||
for i in {1..1000}; do
|
for i in {1..1000}; do
|
||||||
log_must mkfile 512 /$TESTPOOL/$TESTFS2/dir/file-$i
|
log_must mkfile 512 /$TESTPOOL/$TESTFS2/dir/file-$i
|
||||||
|
Loading…
Reference in New Issue
Block a user