]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/dmu_send.c
Encryption patch follow-up
[mirror_zfs.git] / module / zfs / dmu_send.c
index dee4cd775e9b716fc067673dd443666c527ecb62..235e832d74801af5019a96a27a1191d5f5caea71 100644 (file)
@@ -454,6 +454,22 @@ static int
 dump_freeobjects(dmu_sendarg_t *dsp, uint64_t firstobj, uint64_t numobjs)
 {
        struct drr_freeobjects *drrfo = &(dsp->dsa_drr->drr_u.drr_freeobjects);
+       uint64_t maxobj = DNODES_PER_BLOCK *
+           (DMU_META_DNODE(dsp->dsa_os)->dn_maxblkid + 1);
+
+       /*
+        * ZoL < 0.7 does not handle large FREEOBJECTS records correctly,
+        * leading to zfs recv never completing. to avoid this issue, don't
+        * send FREEOBJECTS records for object IDs which cannot exist on the
+        * receiving side.
+        */
+       if (maxobj > 0) {
+               if (maxobj < firstobj)
+                       return (0);
+
+               if (maxobj < firstobj + numobjs)
+                       numobjs = maxobj - firstobj;
+       }
 
        /*
         * If there is a pending op, but it's not PENDING_FREEOBJECTS,
@@ -501,7 +517,7 @@ dump_dnode(dmu_sendarg_t *dsp, const blkptr_t *bp, uint64_t object,
     dnode_phys_t *dnp)
 {
        struct drr_object *drro = &(dsp->dsa_drr->drr_u.drr_object);
-       int bonuslen = P2ROUNDUP(dnp->dn_bonuslen, 8);
+       int bonuslen;
 
        if (object < dsp->dsa_resume_object) {
                /*
@@ -542,6 +558,8 @@ dump_dnode(dmu_sendarg_t *dsp, const blkptr_t *bp, uint64_t object,
            drro->drr_blksz > SPA_OLD_MAXBLOCKSIZE)
                drro->drr_blksz = SPA_OLD_MAXBLOCKSIZE;
 
+       bonuslen = P2ROUNDUP(dnp->dn_bonuslen, 8);
+
        if ((dsp->dsa_featureflags & DMU_BACKUP_FEATURE_RAW)) {
                ASSERT(BP_IS_ENCRYPTED(bp));
 
@@ -555,7 +573,7 @@ dump_dnode(dmu_sendarg_t *dsp, const blkptr_t *bp, uint64_t object,
 
                /*
                 * Since we encrypt the entire bonus area, the (raw) part
-                * beyond the the bonuslen is actually nonzero, so we need
+                * beyond the bonuslen is actually nonzero, so we need
                 * to send it.
                 */
                if (bonuslen != 0) {