When receiving a stream with the large block flag, activate feature

ZFS send streams include a feature flag DMU_BACKUP_FEATURE_LARGE_BLOCKS
to indicate the presence of large blocks in the dataset. On the sending
side, this flag is included if the `-L` flag is passed to `zfs send`
and the feature is active in the dataset. On the receive side, the
stream is refused if the feature is active in the destination dataset
but the stream does not include the feature flag.

The problem is the feature is only activated when a large block is
born. If a large block has been born in the destination, but never
the source, the send can't work. This can arise when sending streams
back and forth between two datasets.

This commit fixes the problem by always activating the large blocks
feature when receiving a stream with the large block feature flag.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Austin Wise <AustinWise@gmail.com>
Closes #18105
This commit is contained in:
Austin Wise
2026-01-07 16:47:12 -08:00
committed by Tony Hutter
parent 8a826c0f68
commit 65e13c33d8
5 changed files with 188 additions and 0 deletions
+16
View File
@@ -1018,6 +1018,22 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx)
dmu_buf_will_dirty(newds->ds_dbuf, tx);
dsl_dataset_phys(newds)->ds_flags |= DS_FLAG_INCONSISTENT;
/*
* When receiving, we refuse to accept streams that are missing the
* large block feature flag if the large block is already active
* (see ZFS_ERR_STREAM_LARGE_BLOCK_MISMATCH). To prevent this
* check from being spuriously triggered, we always activate
* the large block feature if the feature flag is present in the
* stream. This covers the case where the sending side has the feature
* active, but has since deleted the file containing large blocks.
*/
if (featureflags & DMU_BACKUP_FEATURE_LARGE_BLOCKS &&
!dsl_dataset_feature_is_active(newds, SPA_FEATURE_LARGE_BLOCKS)) {
dsl_dataset_activate_feature(newds->ds_object,
SPA_FEATURE_LARGE_BLOCKS, (void *)B_TRUE, tx);
newds->ds_feature[SPA_FEATURE_LARGE_BLOCKS] = (void *)B_TRUE;
}
/*
* Activate longname feature if received
*/