From b0ee5946aaee396c9c90b07f27504c39f6dec0ef Mon Sep 17 00:00:00 2001 From: Tom Caputi Date: Tue, 17 Apr 2018 14:19:03 -0400 Subject: [PATCH] Fix issues with raw sends of spill blocks This patch fixes 2 issues in how spill blocks are processed during raw sends. The first problem is that compressed spill blocks were using the logical length rather than the physical length to determine how much data to dump into the send stream. The second issue is a typo that caused the spill record's object number to be used where the objset's ID number was required. Both issues have been corrected, and the payload_size is now printed in zstreamdump for future debugging. Reviewed-by: Brian Behlendorf Signed-off-by: Tom Caputi Closes #7378 Closes #7432 --- cmd/zstreamdump/zstreamdump.c | 9 +++++++-- module/zfs/dmu_send.c | 6 ++++-- .../tests/functional/rsend/send_encrypted_files.ksh | 12 +++++++++--- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/cmd/zstreamdump/zstreamdump.c b/cmd/zstreamdump/zstreamdump.c index 4c33e0a5a..6c7150b10 100644 --- a/cmd/zstreamdump/zstreamdump.c +++ b/cmd/zstreamdump/zstreamdump.c @@ -614,6 +614,9 @@ main(int argc, char *argv[]) BSWAP_64(drrs->drr_compressed_size); drrs->drr_type = BSWAP_32(drrs->drr_type); } + + payload_size = DRR_SPILL_PAYLOAD_SIZE(drrs); + if (verbose) { sprintf_bytes(salt, drrs->drr_salt, ZIO_DATA_SALT_LEN); @@ -626,19 +629,21 @@ main(int argc, char *argv[]) "length = %llu flags = %u " "compression type = %u " "compressed_size = %llu " + "payload_size = %llu " "salt = %s iv = %s mac = %s\n", (u_longlong_t)drrs->drr_object, (u_longlong_t)drrs->drr_length, drrs->drr_flags, drrs->drr_compressiontype, (u_longlong_t)drrs->drr_compressed_size, + (u_longlong_t)payload_size, salt, iv, mac); } - (void) ssread(buf, drrs->drr_length, &zc); + (void) ssread(buf, payload_size, &zc); if (dump) { - print_block(buf, drrs->drr_length); + print_block(buf, payload_size); } break; case DRR_WRITE_EMBEDDED: diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index 6f3f6fde9..9422f3444 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -422,6 +422,7 @@ dump_spill(dmu_sendarg_t *dsp, const blkptr_t *bp, uint64_t object, void *data) { struct drr_spill *drrs = &(dsp->dsa_drr->drr_u.drr_spill); uint64_t blksz = BP_GET_LSIZE(bp); + uint64_t payload_size = blksz; if (dsp->dsa_pending_op != PENDING_NONE) { if (dump_record(dsp, NULL, 0) != 0) @@ -446,9 +447,10 @@ dump_spill(dmu_sendarg_t *dsp, const blkptr_t *bp, uint64_t object, void *data) drrs->drr_compressed_size = BP_GET_PSIZE(bp); zio_crypt_decode_params_bp(bp, drrs->drr_salt, drrs->drr_iv); zio_crypt_decode_mac_bp(bp, drrs->drr_mac); + payload_size = drrs->drr_compressed_size; } - if (dump_record(dsp, data, blksz) != 0) + if (dump_record(dsp, data, payload_size) != 0) return (SET_ERROR(EINTR)); return (0); } @@ -3395,7 +3397,7 @@ receive_read_record(struct receive_arg *ra) ra->byteswap; abuf = arc_loan_raw_buf(dmu_objset_spa(ra->os), - drrs->drr_object, byteorder, drrs->drr_salt, + dmu_objset_id(ra->os), byteorder, drrs->drr_salt, drrs->drr_iv, drrs->drr_mac, drrs->drr_type, drrs->drr_compressed_size, drrs->drr_length, drrs->drr_compressiontype); diff --git a/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh b/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh index 998c2afc3..5bf25e277 100755 --- a/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh +++ b/tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh @@ -15,7 +15,7 @@ # # -# Copyright (c) 2017 by Datto Inc. All rights reserved. +# Copyright (c) 2018 by Datto Inc. All rights reserved. # . $STF_SUITE/tests/functional/rsend/rsend.kshlib @@ -33,8 +33,9 @@ # 6. Add a file truncated to 4M to the filesystem # 7. Add a sparse file with metadata compression disabled to the filesystem # 8. Add and remove 1000 empty files to the filesystem -# 9. Snapshot the filesystem -# 10. Send and receive the filesystem, ensuring that it can be mounted +# 9. Add a file with a large xattr value +# 10. Snapshot the filesystem +# 11. Send and receive the filesystem, ensuring that it can be mounted # verify_runnable "both" @@ -79,6 +80,11 @@ for i in {1..1000}; do done sync +# ZoL issue #7432 +log_must zfs set compression=on xattr=sa $TESTPOOL/$TESTFS2 +log_must touch /$TESTPOOL/$TESTFS2/attrs +log_must eval "python -c 'print \"a\" * 4096' | attr -s bigval /$TESTPOOL/$TESTFS2/attrs" + log_must zfs snapshot $TESTPOOL/$TESTFS2@now log_must eval "zfs send -wR $TESTPOOL/$TESTFS2@now > $sendfile"