Skip to content

Commit 2a59b6b

Browse files
amotinbehlendorf
authored andcommitted
ABD: Be more assertive in iterators
Once we verified the ABDs and asserted the sizes we should never see premature ABDs ends. Assert that and remove extra branches from production builds. Reviewed-by: Brian Atkinson <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored by: iXsystems, Inc. Closes #15428
1 parent db2db50 commit 2a59b6b

File tree

1 file changed

+26
-78
lines changed

1 file changed

+26
-78
lines changed

module/zfs/abd.c

Lines changed: 26 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -802,13 +802,10 @@ abd_iterate_func(abd_t *abd, size_t off, size_t size,
802802
abd_verify(abd);
803803
ASSERT3U(off + size, <=, abd->abd_size);
804804

805-
boolean_t gang = abd_is_gang(abd);
806805
abd_t *c_abd = abd_init_abd_iter(abd, &aiter, off);
807806

808807
while (size > 0) {
809-
/* If we are at the end of the gang ABD we are done */
810-
if (gang && !c_abd)
811-
break;
808+
IMPLY(abd_is_gang(abd), c_abd != NULL);
812809

813810
abd_iter_map(&aiter);
814811

@@ -930,7 +927,6 @@ abd_iterate_func2(abd_t *dabd, abd_t *sabd, size_t doff, size_t soff,
930927
{
931928
int ret = 0;
932929
struct abd_iter daiter, saiter;
933-
boolean_t dabd_is_gang_abd, sabd_is_gang_abd;
934930
abd_t *c_dabd, *c_sabd;
935931

936932
if (size == 0)
@@ -942,16 +938,12 @@ abd_iterate_func2(abd_t *dabd, abd_t *sabd, size_t doff, size_t soff,
942938
ASSERT3U(doff + size, <=, dabd->abd_size);
943939
ASSERT3U(soff + size, <=, sabd->abd_size);
944940

945-
dabd_is_gang_abd = abd_is_gang(dabd);
946-
sabd_is_gang_abd = abd_is_gang(sabd);
947941
c_dabd = abd_init_abd_iter(dabd, &daiter, doff);
948942
c_sabd = abd_init_abd_iter(sabd, &saiter, soff);
949943

950944
while (size > 0) {
951-
/* if we are at the end of the gang ABD we are done */
952-
if ((dabd_is_gang_abd && !c_dabd) ||
953-
(sabd_is_gang_abd && !c_sabd))
954-
break;
945+
IMPLY(abd_is_gang(dabd), c_dabd != NULL);
946+
IMPLY(abd_is_gang(sabd), c_sabd != NULL);
955947

956948
abd_iter_map(&daiter);
957949
abd_iter_map(&saiter);
@@ -1032,66 +1024,40 @@ abd_raidz_gen_iterate(abd_t **cabds, abd_t *dabd,
10321024
int i;
10331025
ssize_t len, dlen;
10341026
struct abd_iter caiters[3];
1035-
struct abd_iter daiter = {0};
1027+
struct abd_iter daiter;
10361028
void *caddrs[3];
10371029
unsigned long flags __maybe_unused = 0;
10381030
abd_t *c_cabds[3];
10391031
abd_t *c_dabd = NULL;
1040-
boolean_t cabds_is_gang_abd[3];
1041-
boolean_t dabd_is_gang_abd = B_FALSE;
10421032

10431033
ASSERT3U(parity, <=, 3);
1044-
10451034
for (i = 0; i < parity; i++) {
1046-
cabds_is_gang_abd[i] = abd_is_gang(cabds[i]);
1035+
abd_verify(cabds[i]);
1036+
ASSERT3U(csize, <=, cabds[i]->abd_size);
10471037
c_cabds[i] = abd_init_abd_iter(cabds[i], &caiters[i], 0);
10481038
}
10491039

1050-
if (dabd) {
1051-
dabd_is_gang_abd = abd_is_gang(dabd);
1040+
ASSERT3S(dsize, >=, 0);
1041+
if (dsize > 0) {
1042+
ASSERT(dabd);
1043+
abd_verify(dabd);
1044+
ASSERT3U(dsize, <=, dabd->abd_size);
10521045
c_dabd = abd_init_abd_iter(dabd, &daiter, 0);
10531046
}
10541047

1055-
ASSERT3S(dsize, >=, 0);
1056-
10571048
abd_enter_critical(flags);
10581049
while (csize > 0) {
1059-
/* if we are at the end of the gang ABD we are done */
1060-
if (dabd_is_gang_abd && !c_dabd)
1061-
break;
1062-
1050+
len = csize;
10631051
for (i = 0; i < parity; i++) {
1064-
/*
1065-
* If we are at the end of the gang ABD we are
1066-
* done.
1067-
*/
1068-
if (cabds_is_gang_abd[i] && !c_cabds[i])
1069-
break;
1052+
IMPLY(abd_is_gang(cabds[i]), c_cabds[i] != NULL);
10701053
abd_iter_map(&caiters[i]);
10711054
caddrs[i] = caiters[i].iter_mapaddr;
1055+
len = MIN(caiters[i].iter_mapsize, len);
10721056
}
10731057

1074-
len = csize;
1075-
1076-
if (dabd && dsize > 0)
1058+
if (dsize > 0) {
1059+
IMPLY(abd_is_gang(dabd), c_dabd != NULL);
10771060
abd_iter_map(&daiter);
1078-
1079-
switch (parity) {
1080-
case 3:
1081-
len = MIN(caiters[2].iter_mapsize, len);
1082-
zfs_fallthrough;
1083-
case 2:
1084-
len = MIN(caiters[1].iter_mapsize, len);
1085-
zfs_fallthrough;
1086-
case 1:
1087-
len = MIN(caiters[0].iter_mapsize, len);
1088-
}
1089-
1090-
/* must be progressive */
1091-
ASSERT3S(len, >, 0);
1092-
1093-
if (dabd && dsize > 0) {
1094-
/* this needs precise iter.length */
10951061
len = MIN(daiter.iter_mapsize, len);
10961062
dlen = len;
10971063
} else
@@ -1114,7 +1080,7 @@ abd_raidz_gen_iterate(abd_t **cabds, abd_t *dabd,
11141080
&caiters[i], len);
11151081
}
11161082

1117-
if (dabd && dsize > 0) {
1083+
if (dsize > 0) {
11181084
abd_iter_unmap(&daiter);
11191085
c_dabd =
11201086
abd_advance_abd_iter(dabd, c_dabd, &daiter,
@@ -1153,16 +1119,16 @@ abd_raidz_rec_iterate(abd_t **cabds, abd_t **tabds,
11531119
struct abd_iter xiters[3];
11541120
void *caddrs[3], *xaddrs[3];
11551121
unsigned long flags __maybe_unused = 0;
1156-
boolean_t cabds_is_gang_abd[3];
1157-
boolean_t tabds_is_gang_abd[3];
11581122
abd_t *c_cabds[3];
11591123
abd_t *c_tabds[3];
11601124

11611125
ASSERT3U(parity, <=, 3);
11621126

11631127
for (i = 0; i < parity; i++) {
1164-
cabds_is_gang_abd[i] = abd_is_gang(cabds[i]);
1165-
tabds_is_gang_abd[i] = abd_is_gang(tabds[i]);
1128+
abd_verify(cabds[i]);
1129+
abd_verify(tabds[i]);
1130+
ASSERT3U(tsize, <=, cabds[i]->abd_size);
1131+
ASSERT3U(tsize, <=, tabds[i]->abd_size);
11661132
c_cabds[i] =
11671133
abd_init_abd_iter(cabds[i], &citers[i], 0);
11681134
c_tabds[i] =
@@ -1171,36 +1137,18 @@ abd_raidz_rec_iterate(abd_t **cabds, abd_t **tabds,
11711137

11721138
abd_enter_critical(flags);
11731139
while (tsize > 0) {
1174-
1140+
len = tsize;
11751141
for (i = 0; i < parity; i++) {
1176-
/*
1177-
* If we are at the end of the gang ABD we
1178-
* are done.
1179-
*/
1180-
if (cabds_is_gang_abd[i] && !c_cabds[i])
1181-
break;
1182-
if (tabds_is_gang_abd[i] && !c_tabds[i])
1183-
break;
1142+
IMPLY(abd_is_gang(cabds[i]), c_cabds[i] != NULL);
1143+
IMPLY(abd_is_gang(tabds[i]), c_tabds[i] != NULL);
11841144
abd_iter_map(&citers[i]);
11851145
abd_iter_map(&xiters[i]);
11861146
caddrs[i] = citers[i].iter_mapaddr;
11871147
xaddrs[i] = xiters[i].iter_mapaddr;
1148+
len = MIN(citers[i].iter_mapsize, len);
1149+
len = MIN(xiters[i].iter_mapsize, len);
11881150
}
11891151

1190-
len = tsize;
1191-
switch (parity) {
1192-
case 3:
1193-
len = MIN(xiters[2].iter_mapsize, len);
1194-
len = MIN(citers[2].iter_mapsize, len);
1195-
zfs_fallthrough;
1196-
case 2:
1197-
len = MIN(xiters[1].iter_mapsize, len);
1198-
len = MIN(citers[1].iter_mapsize, len);
1199-
zfs_fallthrough;
1200-
case 1:
1201-
len = MIN(xiters[0].iter_mapsize, len);
1202-
len = MIN(citers[0].iter_mapsize, len);
1203-
}
12041152
/* must be progressive */
12051153
ASSERT3S(len, >, 0);
12061154
/*

0 commit comments

Comments
 (0)