mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-19 16:16:48 +00:00
fuse_statfs: scale with long double to avoid integer overflow
The branch-aggregation code computed blocks * f_frsize / min_frsize as u64 arithmetic. With large filesystems the intermediate product blocks * f_frsize overflows 64 bits long before the division can bring the result back into range, producing garbage bavail/bfree values reported to userspace. Compute the scale factor once in long double and multiply each count by it, so the only narrowing happens in the final cast back to fsblkcnt_t.
This commit is contained in:
committed by
trapexit
parent
4288a60c5d
commit
ef9c7ad5df
+7
-3
@@ -41,9 +41,13 @@ _normalize_statvfs(struct statvfs *fsstat_,
|
||||
const unsigned long min_frsize_,
|
||||
const unsigned long min_namemax_)
|
||||
{
|
||||
fsstat_->f_blocks = (fsblkcnt_t)((fsstat_->f_blocks * fsstat_->f_frsize) / min_frsize_);
|
||||
fsstat_->f_bfree = (fsblkcnt_t)((fsstat_->f_bfree * fsstat_->f_frsize) / min_frsize_);
|
||||
fsstat_->f_bavail = (fsblkcnt_t)((fsstat_->f_bavail * fsstat_->f_frsize) / min_frsize_);
|
||||
long double scale;
|
||||
|
||||
scale = (((long double)fsstat_->f_frsize) / ((long double)min_frsize_));
|
||||
|
||||
fsstat_->f_blocks = (fsblkcnt_t)(fsstat_->f_blocks * scale);
|
||||
fsstat_->f_bfree = (fsblkcnt_t)(fsstat_->f_bfree * scale);
|
||||
fsstat_->f_bavail = (fsblkcnt_t)(fsstat_->f_bavail * scale);
|
||||
fsstat_->f_bsize = min_bsize_;
|
||||
fsstat_->f_frsize = min_frsize_;
|
||||
fsstat_->f_namemax = min_namemax_;
|
||||
|
||||
Reference in New Issue
Block a user