From 829e95c4dc74d7d6d31d01af9c39e03752499b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Tue, 26 Sep 2017 14:03:21 +0200 Subject: [PATCH] Skip FREEOBJECTS for objects which can't exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When sending an incremental stream based on a snapshot, the receiving side must have the same base snapshot. Thus we do not need to send FREEOBJECTS records for any objects past the maximum one which exists locally. This allows us to send incremental streams (again) to older ZFS implementations (e.g. ZoL < 0.7) which actually try to free all objects in a FREEOBJECTS record, instead of bailing out early. Reviewed by: Paul Dagnelie Reviewed-by: Brian Behlendorf Signed-off-by: Fabian Grünbichler Closes #5699 Closes #6507 Closes #6616 --- module/zfs/dmu_send.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index dee4cd775e..c63ab43e1a 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -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,