]> granicus.if.org Git - zfs/commitdiff
Fix issues with raw sends of spill blocks
authorTom Caputi <tcaputi@datto.com>
Tue, 17 Apr 2018 18:19:03 +0000 (14:19 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 17 Apr 2018 18:19:03 +0000 (11:19 -0700)
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 <behlendorf1@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #7378
Closes #7432

cmd/zstreamdump/zstreamdump.c
module/zfs/dmu_send.c
tests/zfs-tests/tests/functional/rsend/send_encrypted_files.ksh

index 4c33e0a5a92d0749c59c2da618d2370c2b053d57..6c7150b108eb4990b7b0f764c34d8cd7868ac86c 100644 (file)
@@ -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:
index 6f3f6fde9d5f1fd19727012a409d0e8e8a3be903..9422f3444f698ddeac535340fdf8a20f3756f81e 100644 (file)
@@ -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);
index 998c2afc3d2cd2dc0b618d2e0889492d5994db35..5bf25e27734b6beec03c2d7f2febcb3aa74d5437 100755 (executable)
@@ -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"