@@ -180,6 +180,8 @@ struct send_range {
180
180
*/
181
181
dnode_phys_t * dnp ;
182
182
blkptr_t bp ;
183
+ /* Piggyback unmodified spill block */
184
+ struct send_range * spill_range ;
183
185
} object ;
184
186
struct srr {
185
187
uint32_t datablksz ;
@@ -231,6 +233,8 @@ range_free(struct send_range *range)
231
233
size_t size = sizeof (dnode_phys_t ) *
232
234
(range -> sru .object .dnp -> dn_extra_slots + 1 );
233
235
kmem_free (range -> sru .object .dnp , size );
236
+ if (range -> sru .object .spill_range )
237
+ range_free (range -> sru .object .spill_range );
234
238
} else if (range -> type == DATA ) {
235
239
mutex_enter (& range -> sru .data .lock );
236
240
while (range -> sru .data .io_outstanding )
@@ -617,7 +621,7 @@ dump_spill(dmu_send_cookie_t *dscp, const blkptr_t *bp, uint64_t object,
617
621
drrs -> drr_length = blksz ;
618
622
drrs -> drr_toguid = dscp -> dsc_toguid ;
619
623
620
- /* See comment in dump_dnode () for full details */
624
+ /* See comment in piggyback_unmodified_spill () for full details */
621
625
if (zfs_send_unmodified_spill_blocks &&
622
626
(BP_GET_LOGICAL_BIRTH (bp ) <= dscp -> dsc_fromtxg )) {
623
627
drrs -> drr_flags |= DRR_SPILL_UNMODIFIED ;
@@ -793,35 +797,6 @@ dump_dnode(dmu_send_cookie_t *dscp, const blkptr_t *bp, uint64_t object,
793
797
(dnp -> dn_datablkszsec << SPA_MINBLOCKSHIFT ), DMU_OBJECT_END ) != 0 )
794
798
return (SET_ERROR (EINTR ));
795
799
796
- /*
797
- * Send DRR_SPILL records for unmodified spill blocks. This is useful
798
- * because changing certain attributes of the object (e.g. blocksize)
799
- * can cause old versions of ZFS to incorrectly remove a spill block.
800
- * Including these records in the stream forces an up to date version
801
- * to always be written ensuring they're never lost. Current versions
802
- * of the code which understand the DRR_FLAG_SPILL_BLOCK feature can
803
- * ignore these unmodified spill blocks.
804
- */
805
- if (zfs_send_unmodified_spill_blocks &&
806
- (dnp -> dn_flags & DNODE_FLAG_SPILL_BLKPTR ) &&
807
- (BP_GET_LOGICAL_BIRTH (DN_SPILL_BLKPTR (dnp )) <= dscp -> dsc_fromtxg )) {
808
- struct send_range record ;
809
- blkptr_t * bp = DN_SPILL_BLKPTR (dnp );
810
-
811
- memset (& record , 0 , sizeof (struct send_range ));
812
- record .type = DATA ;
813
- record .object = object ;
814
- record .eos_marker = B_FALSE ;
815
- record .start_blkid = DMU_SPILL_BLKID ;
816
- record .end_blkid = record .start_blkid + 1 ;
817
- record .sru .data .bp = * bp ;
818
- record .sru .data .obj_type = dnp -> dn_type ;
819
- record .sru .data .datablksz = BP_GET_LSIZE (bp );
820
-
821
- if (do_dump (dscp , & record ) != 0 )
822
- return (SET_ERROR (EINTR ));
823
- }
824
-
825
800
if (dscp -> dsc_err != 0 )
826
801
return (SET_ERROR (EINTR ));
827
802
@@ -911,6 +886,9 @@ do_dump(dmu_send_cookie_t *dscp, struct send_range *range)
911
886
case OBJECT :
912
887
err = dump_dnode (dscp , & range -> sru .object .bp , range -> object ,
913
888
range -> sru .object .dnp );
889
+ /* Dump piggybacked unmodified spill block */
890
+ if (!err && range -> sru .object .spill_range )
891
+ err = do_dump (dscp , range -> sru .object .spill_range );
914
892
return (err );
915
893
case OBJECT_RANGE : {
916
894
ASSERT3U (range -> start_blkid + 1 , = = , range -> end_blkid );
@@ -939,34 +917,7 @@ do_dump(dmu_send_cookie_t *dscp, struct send_range *range)
939
917
940
918
ASSERT3U (srdp -> datablksz , = = , BP_GET_LSIZE (bp ));
941
919
ASSERT3U (range -> start_blkid + 1 , = = , range -> end_blkid );
942
- if (BP_GET_TYPE (bp ) == DMU_OT_SA ) {
943
- arc_flags_t aflags = ARC_FLAG_WAIT ;
944
- zio_flag_t zioflags = ZIO_FLAG_CANFAIL ;
945
-
946
- if (dscp -> dsc_featureflags & DMU_BACKUP_FEATURE_RAW ) {
947
- ASSERT (BP_IS_PROTECTED (bp ));
948
- zioflags |= ZIO_FLAG_RAW ;
949
- }
950
920
951
- zbookmark_phys_t zb ;
952
- ASSERT3U (range -> start_blkid , = = , DMU_SPILL_BLKID );
953
- zb .zb_objset = dmu_objset_id (dscp -> dsc_os );
954
- zb .zb_object = range -> object ;
955
- zb .zb_level = 0 ;
956
- zb .zb_blkid = range -> start_blkid ;
957
-
958
- arc_buf_t * abuf = NULL ;
959
- if (!dscp -> dsc_dso -> dso_dryrun && arc_read (NULL , spa ,
960
- bp , arc_getbuf_func , & abuf , ZIO_PRIORITY_ASYNC_READ ,
961
- zioflags , & aflags , & zb ) != 0 )
962
- return (SET_ERROR (EIO ));
963
-
964
- err = dump_spill (dscp , bp , zb .zb_object ,
965
- (abuf == NULL ? NULL : abuf -> b_data ));
966
- if (abuf != NULL )
967
- arc_buf_destroy (abuf , & abuf );
968
- return (err );
969
- }
970
921
if (send_do_embed (bp , dscp -> dsc_featureflags )) {
971
922
err = dump_write_embedded (dscp , range -> object ,
972
923
range -> start_blkid * srdp -> datablksz ,
@@ -975,8 +926,9 @@ do_dump(dmu_send_cookie_t *dscp, struct send_range *range)
975
926
}
976
927
ASSERT (range -> object > dscp -> dsc_resume_object ||
977
928
(range -> object == dscp -> dsc_resume_object &&
929
+ (range -> start_blkid == DMU_SPILL_BLKID ||
978
930
range -> start_blkid * srdp -> datablksz >=
979
- dscp -> dsc_resume_offset ));
931
+ dscp -> dsc_resume_offset ))) ;
980
932
/* it's a level-0 block of a regular object */
981
933
982
934
mutex_enter (& srdp -> lock );
@@ -1006,8 +958,6 @@ do_dump(dmu_send_cookie_t *dscp, struct send_range *range)
1006
958
ASSERT (dscp -> dsc_dso -> dso_dryrun ||
1007
959
srdp -> abuf != NULL || srdp -> abd != NULL );
1008
960
1009
- uint64_t offset = range -> start_blkid * srdp -> datablksz ;
1010
-
1011
961
char * data = NULL ;
1012
962
if (srdp -> abd != NULL ) {
1013
963
data = abd_to_buf (srdp -> abd );
@@ -1016,6 +966,14 @@ do_dump(dmu_send_cookie_t *dscp, struct send_range *range)
1016
966
data = srdp -> abuf -> b_data ;
1017
967
}
1018
968
969
+ if (BP_GET_TYPE (bp ) == DMU_OT_SA ) {
970
+ ASSERT3U (range -> start_blkid , = = , DMU_SPILL_BLKID );
971
+ err = dump_spill (dscp , bp , range -> object , data );
972
+ return (err );
973
+ }
974
+
975
+ uint64_t offset = range -> start_blkid * srdp -> datablksz ;
976
+
1019
977
/*
1020
978
* If we have large blocks stored on disk but the send flags
1021
979
* don't allow us to send large blocks, we split the data from
@@ -1098,6 +1056,8 @@ range_alloc(enum type type, uint64_t object, uint64_t start_blkid,
1098
1056
range -> sru .data .io_outstanding = 0 ;
1099
1057
range -> sru .data .io_err = 0 ;
1100
1058
range -> sru .data .io_compressed = B_FALSE ;
1059
+ } else if (type == OBJECT ) {
1060
+ range -> sru .object .spill_range = NULL ;
1101
1061
}
1102
1062
return (range );
1103
1063
}
@@ -1742,6 +1702,45 @@ enqueue_range(struct send_reader_thread_arg *srta, bqueue_t *q, dnode_t *dn,
1742
1702
bqueue_enqueue (q , range , datablksz );
1743
1703
}
1744
1704
1705
+ /*
1706
+ * Send DRR_SPILL records for unmodified spill blocks. This is useful
1707
+ * because changing certain attributes of the object (e.g. blocksize)
1708
+ * can cause old versions of ZFS to incorrectly remove a spill block.
1709
+ * Including these records in the stream forces an up to date version
1710
+ * to always be written ensuring they're never lost. Current versions
1711
+ * of the code which understand the DRR_FLAG_SPILL_BLOCK feature can
1712
+ * ignore these unmodified spill blocks.
1713
+ */
1714
+ static uint64_t
1715
+ piggyback_unmodified_spill (struct send_reader_thread_arg * srta ,
1716
+ struct send_range * range )
1717
+ {
1718
+ if (range -> type != OBJECT ||
1719
+ !zfs_send_unmodified_spill_blocks )
1720
+ return (0 );
1721
+
1722
+ struct send_range * spill_range = NULL ;
1723
+ dnode_phys_t * dnp = range -> sru .object .dnp ;
1724
+ uint64_t fromtxg = srta -> smta -> to_arg -> fromtxg ;
1725
+
1726
+ if (!(dnp -> dn_flags & DNODE_FLAG_SPILL_BLKPTR ) ||
1727
+ !(BP_GET_LOGICAL_BIRTH (DN_SPILL_BLKPTR (dnp )) <= fromtxg ))
1728
+ return (0 );
1729
+
1730
+ blkptr_t * bp = DN_SPILL_BLKPTR (dnp );
1731
+
1732
+ spill_range = range_alloc (DATA , range -> object , DMU_SPILL_BLKID ,
1733
+ DMU_SPILL_BLKID + 1 , B_FALSE );
1734
+ spill_range -> sru .data .bp = * bp ;
1735
+ spill_range -> sru .data .obj_type = dnp -> dn_type ;
1736
+ spill_range -> sru .data .datablksz = BP_GET_LSIZE (bp );
1737
+
1738
+ issue_data_read (srta , spill_range );
1739
+ range -> sru .object .spill_range = spill_range ;
1740
+
1741
+ return (BP_GET_LSIZE (bp ));
1742
+ }
1743
+
1745
1744
/*
1746
1745
* This thread is responsible for two things: First, it retrieves the correct
1747
1746
* blkptr in the to ds if we need to send the data because of something from
@@ -1760,6 +1759,7 @@ send_reader_thread(void *arg)
1760
1759
fstrans_cookie_t cookie = spl_fstrans_mark ();
1761
1760
struct send_range * range = bqueue_dequeue (inq );
1762
1761
int err = 0 ;
1762
+ uint64_t spill = 0 ;
1763
1763
1764
1764
/*
1765
1765
* If the record we're analyzing is from a redaction bookmark from the
@@ -1783,7 +1783,9 @@ send_reader_thread(void *arg)
1783
1783
case OBJECT :
1784
1784
case OBJECT_RANGE :
1785
1785
case REDACT : // Redacted blocks must exist
1786
- bqueue_enqueue (outq , range , sizeof (* range ));
1786
+ /* For OBJECT */
1787
+ spill = piggyback_unmodified_spill (srta , range );
1788
+ bqueue_enqueue (outq , range , sizeof (* range ) + spill );
1787
1789
range = get_next_range_nofree (inq , range );
1788
1790
break ;
1789
1791
case PREVIOUSLY_REDACTED : {
0 commit comments