@@ -5020,7 +5020,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
5020
5020
char * path0 ;
5021
5021
char * pathrand ;
5022
5022
size_t fsize ;
5023
- int bshift = SPA_OLD_MAXBLOCKSHIFT + 2 ; /* don't scrog all labels */
5023
+ int bshift = SPA_MAXBLOCKSHIFT + 2 ; /* don't scrog all labels */
5024
5024
int iters = 1000 ;
5025
5025
int maxfaults ;
5026
5026
int mirror_save ;
@@ -5184,6 +5184,31 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
5184
5184
fsize = lseek (fd , 0 , SEEK_END );
5185
5185
5186
5186
while (-- iters != 0 ) {
5187
+ /*
5188
+ * The offset must be chosen carefully to ensure that
5189
+ * we do not inject a given logical block with errors
5190
+ * on two different leaf devices, because ZFS can not
5191
+ * tolerate that (if maxfaults==1).
5192
+ *
5193
+ * We divide each leaf into chunks of size
5194
+ * (# leaves * SPA_MAXBLOCKSIZE * 4). Within each chunk
5195
+ * there is a series of ranges to which we can inject errors.
5196
+ * Each range can accept errors on only a single leaf vdev.
5197
+ * The error injection ranges are separated by ranges
5198
+ * which we will not inject errors on any device (DMZs).
5199
+ * Each DMZ must be large enough such that a single block
5200
+ * can not straddle it, so that a single block can not be
5201
+ * a target in two different injection ranges (on different
5202
+ * leaf vdevs).
5203
+ *
5204
+ * For example, with 3 leaves, each chunk looks like:
5205
+ * 0 to 32M: injection range for leaf 0
5206
+ * 32M to 64M: DMZ - no injection allowed
5207
+ * 64M to 96M: injection range for leaf 1
5208
+ * 96M to 128M: DMZ - no injection allowed
5209
+ * 128M to 160M: injection range for leaf 2
5210
+ * 160M to 192M: DMZ - no injection allowed
5211
+ */
5187
5212
offset = ztest_random (fsize / (leaves << bshift )) *
5188
5213
(leaves << bshift ) + (leaf << bshift ) +
5189
5214
(ztest_random (1ULL << (bshift - 1 )) & -8ULL );
0 commit comments