Skip to content

Commit

Permalink
Overflowing refreservation is bad
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rincebrain authored Apr 29, 2024
1 parent 4840f02 commit db499e6
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion lib/libzfs/libzfs_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) / (tsize >> SPA_MINBLOCKSHIFT);
/*
* If we would blow UINT64_MAX with this next multiplication,
* don't.
*/
volsize = nblocks * asize * SPA_OLD_MAXBLOCKSIZE / tsize;
if (volsize >
(UINT64_MAX / (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT)))
volsize = UINT64_MAX;
else
volsize *= (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);

if (volsize > ret) {
ret = volsize;
}
Expand Down

0 comments on commit db499e6

Please sign in to comment.