diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index 36a480d36a05..4d0b20f17d3b 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -852,6 +852,11 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj, case EINVAL: zfs_error_aux(hdl, "%s", strerror(errno)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); + case ENOTSUP: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "large blocks detected but large_blocks feature " + "is inactive; raw send unsupported")); + return (zfs_error(hdl, EZFS_NOTSUP, errbuf)); default: return (zfs_standard_error(hdl, errno, errbuf)); @@ -2567,6 +2572,11 @@ zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags, case EROFS: zfs_error_aux(hdl, "%s", strerror(errno)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); + case ENOTSUP: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "large blocks detected but large_blocks feature " + "is inactive; raw send unsupported")); + return (zfs_error(hdl, EZFS_NOTSUP, errbuf)); default: return (zfs_standard_error(hdl, errno, errbuf)); diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index d654382237c0..2f15a5b85041 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -488,6 +488,7 @@ dmu_dump_write(dmu_send_cookie_t *dscp, dmu_object_type_t type, uint64_t object, /* only set the compression fields if the buf is compressed or raw */ if (raw || lsize != psize) { + ASSERT(bp != NULL); ASSERT(raw || dscp->dsc_featureflags & DMU_BACKUP_FEATURE_COMPRESSED); ASSERT(!BP_IS_EMBEDDED(bp)); @@ -1010,6 +1011,9 @@ do_dump(dmu_send_cookie_t *dscp, struct send_range *range) if (srdp->datablksz > SPA_OLD_MAXBLOCKSIZE && !(dscp->dsc_featureflags & DMU_BACKUP_FEATURE_LARGE_BLOCKS)) { + if (dscp->dsc_featureflags & DMU_BACKUP_FEATURE_RAW) + return (SET_ERROR(ENOTSUP)); + while (srdp->datablksz > 0 && err == 0) { int n = MIN(srdp->datablksz, SPA_OLD_MAXBLOCKSIZE); diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c index 62ee9bb9ab6c..928bc3d2e040 100644 --- a/module/zfs/dsl_scan.c +++ b/module/zfs/dsl_scan.c @@ -1980,6 +1980,20 @@ dsl_scan_visitbp(blkptr_t *bp, const zbookmark_phys_t *zb, return; } + /* + * If there are blocks larger than 128kB check if large_blocks + * is active. If not, activate it. + */ + if (BP_GET_LSIZE(bp) > SPA_OLD_MAXBLOCKSIZE) { + spa_feature_t f = SPA_FEATURE_LARGE_BLOCKS; + if (!dsl_dataset_feature_is_active(ds, f)) { + ds->ds_feature_activation[f] = (void *)B_TRUE; + dsl_dataset_activate_feature(ds->ds_object, f, + ds->ds_feature_activation[f], tx); + ds->ds_feature[f] = ds->ds_feature_activation[f]; + } + } + if (bp->blk_birth <= scn->scn_phys.scn_cur_min_txg) { scn->scn_lt_min_this_txg++; return;