Fix possible bad bit shift in dnode_next_offset_level()
031d7c2fe6
did not handle reverse
iteration, such that the original issue theoretically could still occur.
Note that contrary to the claim in the ZFS disk format specification
that a maximum of 6 levels are possible, 9 levels are possible with
recordsize=512 and and indirect block size of 16KB. In this unusual
configuration, span will be 65. The maximum size of span at 70 can be
reached at recordsize=16K and an indirect blocksize of 16KB.
When we are at this indirection level and are traversing backward, the
minimum value is start, but we cannot calculate that with 64-bit
arithmetic, so we avoid the calculation and instead rely on the earlier
statement that did `*offset = start;`.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu>
Reported-by: Coverity (CID-1466214)
Closes #14618
This commit is contained in:
parent
60cfd3bbc2
commit
fa46802585
@ -2597,8 +2597,9 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
|
||||
|
||||
if (inc < 0) {
|
||||
/* traversing backwards; position offset at the end */
|
||||
ASSERT3U(*offset, <=, start);
|
||||
*offset = MIN(*offset + (1ULL << span) - 1, start);
|
||||
if (span < 8 * sizeof (*offset))
|
||||
*offset = MIN(*offset + (1ULL << span) - 1,
|
||||
start);
|
||||
} else if (*offset < start) {
|
||||
*offset = start;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user