mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 19:34:43 +01:00
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:
1 parent
4840f023af
commit
db499e68f9
1 file changed
+14
-1
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user