From: Dominik Csapak <d.csapak@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH storage] api: status: try to prevent converting integers to floating point
Date: Mon, 15 Dec 2025 09:14:16 +0100 [thread overview]
Message-ID: <20251215081435.472283-1-d.csapak@proxmox.com> (raw)
Since perl can have multiple internal representations for the same
scalar variables, it calculates and caches them on demand.
So when doing a division with a variable, it calculates and caches the
floating point representation of it.
When using JSON::XS (which is the default and what we use), it has to
look at the internal representation and chooses a format, and if
both integer and floating point representations are there it chooses,
floating point.
This is usually not a problem, but for bigger numbers this representation
changes to the format `1.234e+15`.
Since our API designates the `total` and `used` fields as integers, our
Schema2Rust code wants to de-serialize this as an integer again and
fails with such values. (And with this the PDM de-serialization)
To avoid this internal conversion, extract the variables before doing
division with it, so the original object is not touched.
There might be more places where we do such calculations, but it's hard
to search for them, so let's fix it as we find them.
(And comment to avoid accidental refactoring to the broken code)
Example perl code to reproduce the problem:
```
use JSON;
my $foo = 12057594037927909;
print JSON::encode_json($foo);
```
returns `12057594037927909`, but
```
use JSON;
my $foo = 12057594037927909;
my $bar = 123.123 / $foo;
print JSON::encode_json($foo);
```
return `1.20575940379279e+16`.
This was reported in the PDM forum:
https://forum.proxmox.com/threads/177888/
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
src/PVE/API2/Storage/Status.pm | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/PVE/API2/Storage/Status.pm b/src/PVE/API2/Storage/Status.pm
index 31bcc6d..8225c3a 100644
--- a/src/PVE/API2/Storage/Status.pm
+++ b/src/PVE/API2/Storage/Status.pm
@@ -257,7 +257,10 @@ __PACKAGE__->register_method({
}
if ($data->{total}) {
- $data->{used_fraction} = ($data->{used} // 0) / $data->{total};
+ # extract variables, otherwise the division converts used and total to floating points
+ my $total = $data->{total};
+ my $used = $data->{used} // 0;
+ $data->{used_fraction} = $used / $total;
}
$res->{$storeid} = $data;
--
2.47.3
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
reply other threads:[~2025-12-15 8:14 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251215081435.472283-1-d.csapak@proxmox.com \
--to=d.csapak@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox