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 <[email protected]>
Signed-off-by: Rich Ercolani <[email protected]>
Closes #15996
This commit is contained in:
Rich Ercolani authored and GitHub committed 2024-04-29 11:32:49 -07:00
1 parent 4840f023af
commit db499e68f9
1 file changed
+14 -1
+14 -1
View File
@@ -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;
}