-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Overflowing refreservation is bad #15996
Conversation
Yeah I'd have probably have returned |
We can't, it's a uint64_t return. We could trip a VERIFY there, and just kill the process, but that seems rude, and given our existing error handling in that code is "if we don't get anything out of this calculation, just do the naive thing", setting it as big as we could seemed the least terrible option without reworking it entirely. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Theoretically, there can be zvol smaller than 128KB. In such case nblocks * asize will be less then tsize, that will result in zero volsize. Would we shift both tsize and SPA_OLD_MAXBLOCKSIZE right by SPA_MINBLOCKSHIFT (that should not lose precision), it would be impossible.
It seems to be hard to construct a case where that happens in practice, quickly glancing, I end up with a refreservation of a couple MiB even in cases like that. I'll implement the change, but just as an observation, it doesn't immediately seem easy to reproduce in practice. (I would assume this case basically can't come up with parity overhead on parity-based devices, and there's already a bailout case for non-parity devices not passing through this code. That said, I agree that's a better solution, I was just curious how easily you could make it happen in practice.) |
I haven't tried is with the patch, but was thinking about something like: |
Good find. I believe this is just waiting on the small change mentioned for very small zvols. Assuming that's even possible in practice. |
@rincebrain could you rebase this to get a fresh CI run. |
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. Signed-off-by: Rich Ercolani <[email protected]>
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 openzfs#15996
Motivation and Context
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.
Description
Shuffle the multiplicands around so that we save the 2^17 multiplier for the end, and if our previous value exceeds 2^47, just use UINT64_MAX.
(We could also just fail in that case, I don't have an especially strong opinion, it just seemed like a useful explicit check to add given the problem at hand.)
How Has This Been Tested?
Types of changes
Checklist:
Signed-off-by
.