MFV r329713: 8731 ASSERT3U(nui64s, <=, UINT16_MAX) fails for large blocks
illumos/illumos-gate@a6c1eb3c08
a6c1eb3c08
https://www.illumos.org/issues/8731
annotate_ecksum() asserts that nui64s, calculated as nui64s = size / sizeof
(uint64_t), is not greater than UINT16_MAX.
This restriction is needed because histograms of incorrectly set and cleared
bits have 16 bit counters and if the buffer consists of too many 64-bit words,
then a counter can potentially overflow producing an incorrect result.
When the largest buffer size was 128KB the greatest value of nui64s was 16K,
well within the limit.
But now we have support for large buffers and for buffer sizes of 512KB and
above the restriction is violated.
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: Andriy Gapon <avg@FreeBSD.org>
MFC after: 2 weeks
This commit is contained in:
parent
7908daef61
commit
cbfdd7dd99
@ -360,8 +360,8 @@ zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out,
|
||||
|
||||
typedef struct zfs_ecksum_info {
|
||||
/* histograms of set and cleared bits by bit number in a 64-bit word */
|
||||
uint16_t zei_histogram_set[sizeof (uint64_t) * NBBY];
|
||||
uint16_t zei_histogram_cleared[sizeof (uint64_t) * NBBY];
|
||||
uint32_t zei_histogram_set[sizeof (uint64_t) * NBBY];
|
||||
uint32_t zei_histogram_cleared[sizeof (uint64_t) * NBBY];
|
||||
|
||||
/* inline arrays of bits set and cleared. */
|
||||
uint64_t zei_bits_set[ZFM_MAX_INLINE];
|
||||
@ -386,7 +386,7 @@ typedef struct zfs_ecksum_info {
|
||||
} zfs_ecksum_info_t;
|
||||
|
||||
static void
|
||||
update_histogram(uint64_t value_arg, uint16_t *hist, uint32_t *count)
|
||||
update_histogram(uint64_t value_arg, uint32_t *hist, uint32_t *count)
|
||||
{
|
||||
size_t i;
|
||||
size_t bits = 0;
|
||||
@ -552,7 +552,7 @@ annotate_ecksum(nvlist_t *ereport, zio_bad_cksum_t *info,
|
||||
if (badbuf == NULL || goodbuf == NULL)
|
||||
return (eip);
|
||||
|
||||
ASSERT3U(nui64s, <=, UINT16_MAX);
|
||||
ASSERT3U(nui64s, <=, UINT32_MAX);
|
||||
ASSERT3U(size, ==, nui64s * sizeof (uint64_t));
|
||||
ASSERT3U(size, <=, SPA_MAXBLOCKSIZE);
|
||||
ASSERT3U(size, <=, UINT32_MAX);
|
||||
@ -654,10 +654,10 @@ annotate_ecksum(nvlist_t *ereport, zio_bad_cksum_t *info,
|
||||
} else {
|
||||
fm_payload_set(ereport,
|
||||
FM_EREPORT_PAYLOAD_ZFS_BAD_SET_HISTOGRAM,
|
||||
DATA_TYPE_UINT16_ARRAY,
|
||||
DATA_TYPE_UINT32_ARRAY,
|
||||
NBBY * sizeof (uint64_t), eip->zei_histogram_set,
|
||||
FM_EREPORT_PAYLOAD_ZFS_BAD_CLEARED_HISTOGRAM,
|
||||
DATA_TYPE_UINT16_ARRAY,
|
||||
DATA_TYPE_UINT32_ARRAY,
|
||||
NBBY * sizeof (uint64_t), eip->zei_histogram_cleared,
|
||||
NULL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user