Skip to content

Commit

Permalink
honor zfs_send_set_freerecords_bit
Browse files Browse the repository at this point in the history
instead of only not setting the DRR_FLAG_FREERECORDS flag, also don't
create any FREE or FREEOBJECTS records when creating a full stream with
zfs_send_set_freerecords_bit disabled.

this allows to re-use this parameter to workaround hanging zfs recv on
0.6.5.x systems.

Original Author: Paul Dagnelie <[email protected]>
Ported-By: Fabian Grünbichler <[email protected]>
Signed-Off-By: Fabian Grünbichler <[email protected]>
  • Loading branch information
Fabian-Gruenbichler committed Sep 8, 2017
1 parent fabab09 commit 982692c
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions module/zfs/dmu_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ dump_record(dmu_sendarg_t *dsp, void *payload, int payload_len)
* Note that we send free records even for a full send, because we want to be
* able to receive a full send as a clone, which requires a list of all the free
* and freeobject records that were generated on the source.
*
* Disable this behaviour by setting zfs_send_set_freerecords_bit to false to
* workaround receiving implementations that cannot handle such streams.
*/
static int
dump_free(dmu_sendarg_t *dsp, uint64_t object, uint64_t offset,
Expand All @@ -223,6 +226,16 @@ dump_free(dmu_sendarg_t *dsp, uint64_t object, uint64_t offset,
(object == dsp->dsa_last_data_object &&
offset > dsp->dsa_last_data_offset));

/*
* If we are doing a non-incremental send, then there can't
* be any data in the dataset we're receiving into. Unless we're receiving
* a full send as a clone, a free record would simply be a no-op.
* If we disable the tunable for this, save space by not sending it to
* begin with.
*/
if (!zfs_send_set_freerecords_bit && !dsp->dsa_drr->drr_u.drr_begin.drr_fromguid)
return (0);

if (length != -1ULL && offset + length < offset)
length = -1ULL;

Expand Down Expand Up @@ -455,6 +468,10 @@ dump_freeobjects(dmu_sendarg_t *dsp, uint64_t firstobj, uint64_t numobjs)
{
struct drr_freeobjects *drrfo = &(dsp->dsa_drr->drr_u.drr_freeobjects);

/* See comment in dump_free(). */
if (!zfs_send_set_freerecords_bit && !dsp->dsa_drr->drr_u.drr_begin.drr_fromguid)
return (0);

/*
* If there is a pending op, but it's not PENDING_FREEOBJECTS,
* push it out, since free block aggregation can only be done for
Expand Down

0 comments on commit 982692c

Please sign in to comment.