Overflowing refreservation is bad
Someone came to me and pointed out that you could pretty readily cause the refreservation calculation to exceed 2**64, given the 2**17 multiplier in it, and produce refreservations wildly less than the actual volsize in cases where it should have failed. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rich Ercolani <rincebrain@gmail.com> Closes #15996
This commit is contained in:
parent
4840f023af
commit
db499e68f9
|
@ -5565,8 +5565,21 @@ volsize_from_vdevs(zpool_handle_t *zhp, uint64_t nblocks, uint64_t blksize)
|
|||
/*
|
||||
* Scale this size down as a ratio of 128k / tsize.
|
||||
* See theory statement above.
|
||||
*
|
||||
* Bitshift is to avoid the case of nblocks * asize < tsize
|
||||
* producing a size of 0.
|
||||
*/
|
||||
volsize = nblocks * asize * SPA_OLD_MAXBLOCKSIZE / tsize;
|
||||
volsize = (nblocks * asize) / (tsize >> SPA_MINBLOCKSHIFT);
|
||||
/*
|
||||
* If we would blow UINT64_MAX with this next multiplication,
|
||||
* don't.
|
||||
*/
|
||||
if (volsize >
|
||||
(UINT64_MAX / (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT)))
|
||||
volsize = UINT64_MAX;
|
||||
else
|
||||
volsize *= (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
|
||||
|
||||
if (volsize > ret) {
|
||||
ret = volsize;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue