Skip to content

df(windows): fix Avail/Use% by using number_of_free_clusters for bavail#9470

Open
naoNao89 wants to merge 1 commit intouutils:mainfrom
naoNao89:fix/df-windows-bavail
Open

df(windows): fix Avail/Use% by using number_of_free_clusters for bavail#9470
naoNao89 wants to merge 1 commit intouutils:mainfrom
naoNao89:fix/df-windows-bavail

Conversation

@naoNao89
Copy link
Contributor

@naoNao89 naoNao89 commented Nov 24, 2025

Fix Windows df incorrectly reporting 0 bytes available and 100% usage for all filesystems. The issue was caused by hardcoding bavail (blocks available to non-privileged processes) to 0 instead of using the actual free clusters from Windows API.

On Windows, all mounted filesystems displayed:

  • Avail: 0 bytes (always)
  • Use%: 100% (always)
  • --total flag: Completely broken aggregation

This made df output useless for Windows users.

Before (Broken)

Filesystem               Size  Used Avail Use%
\Device\HarddiskVolume2  256G  180G     0 100%
\Device\HarddiskVolume3  677G  494G     0 100%
\Device\HarddiskVolume4  1.9T  1.8T     0 100%
\Device\HarddiskVolume1   50M   35M     0 100%
\Device\HarddiskVolume8   11T  5.9T     0 100%

After (Fixed)

Filesystem               Size  Used Avail Use%
\Device\HarddiskVolume2  256G  180G  76G  70%
\Device\HarddiskVolume3  677G  494G 183G  73%
\Device\HarddiskVolume4  1.9T  1.8T 100G  95%
\Device\HarddiskVolume1   50M   35M  15M  70%
\Device\HarddiskVolume8   11T  5.9T 5.1T  54%

Windows API Context

The fix correctly implements POSIX semantics on Windows:

POSIX Windows Meaning
f_bfree lpNumberOfFreeClusters (no quota consideration) Total free clusters
f_bavail lpNumberOfFreeClusters (quota-aware) Free clusters available to user

Windows GetDiskFreeSpaceW() already respects disk quotas, making this fix semantically correct.

Fixes

Closes #7461

Related Issues

@github-actions
Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/misc/tee (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/tail/overlay-headers (fails in this run but passes in the 'main' branch)

@sylvestre
Copy link
Contributor

could you please add a test to make sure we don't regress in the future? thanks

@naoNao89 naoNao89 force-pushed the fix/df-windows-bavail branch from 9d81e88 to 57198e8 Compare November 25, 2025 23:27
@naoNao89
Copy link
Contributor Author

done assert!(fs_usage.bavail >= 0);

@github-actions
Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/misc/tee (fails in this run but passes in the 'main' branch)

@sylvestre
Copy link
Contributor

@naoNao89 i was thinking about tests/by-util/test_df.rs

@naoNao89 naoNao89 force-pushed the fix/df-windows-bavail branch 2 times, most recently from a388c9a to 94dd012 Compare November 26, 2025 23:50
@codspeed-hq
Copy link

codspeed-hq bot commented Nov 27, 2025

Merging this PR will not alter performance

✅ 288 untouched benchmarks
⏩ 38 skipped benchmarks1


Comparing naoNao89:fix/df-windows-bavail (2fef881) with main (d13a2e0)

Open in CodSpeed

Footnotes

  1. 38 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@github-actions
Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/tail/overlay-headers (fails in this run but passes in the 'main' branch)

@naoNao89 naoNao89 force-pushed the fix/df-windows-bavail branch from 94dd012 to 586f6b7 Compare November 27, 2025 00:39
@github-actions
Copy link

GNU testsuite comparison:

Skipping an intermittent issue tests/tail/overlay-headers (passes in this run but fails in the 'main' branch)

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/pr/bounded-memory is no longer failing!

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/factor/t10. tests/factor/t10 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/factor/t33. tests/factor/t33 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/isatty. tests/rm/isatty is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/pr/bounded-memory (fails in this run but passes in the 'main' branch)
Note: The gnu test tests/cut/bounded-memory is now being skipped but was previously passing.
Note: The gnu test tests/unexpand/bounded-memory is now being skipped but was previously passing.
Congrats! The gnu test tests/basenc/bounded-memory is now passing!

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/df/skip-rootfs. tests/df/skip-rootfs is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/factor/t10. tests/factor/t10 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/factor/t33. tests/factor/t33 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/factor/t34. tests/factor/t34 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/isatty. tests/rm/isatty is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/tty/tty-eof (passes in this run but fails in the 'main' branch)
Note: The gnu test tests/rm/many-dir-entries-vs-OOM is now being skipped but was previously passing.
Congrats! The gnu test tests/basenc/bounded-memory is now passing!

@naoNao89 naoNao89 force-pushed the fix/df-windows-bavail branch from 4df2522 to 0f996bb Compare February 15, 2026 04:13
@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/factor/t10. tests/factor/t10 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/factor/t33. tests/factor/t33 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/factor/t34. tests/factor/t34 is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/pr/bounded-memory (fails in this run but passes in the 'main' branch)
Congrats! The gnu test tests/basenc/bounded-memory is now passing!

@naoNao89 naoNao89 force-pushed the fix/df-windows-bavail branch from 0f996bb to 8e04006 Compare February 15, 2026 05:24
@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/factor/t10. tests/factor/t10 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/factor/t33. tests/factor/t33 is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/pr/bounded-memory (fails in this run but passes in the 'main' branch)
Congrats! The gnu test tests/factor/t32 is no longer failing!
Note: The gnu test tests/cut/bounded-memory is now being skipped but was previously passing.
Note: The gnu test tests/tail/pipe-f is now being skipped but was previously passing.
Congrats! The gnu test tests/basenc/bounded-memory is now passing!

@naoNao89 naoNao89 force-pushed the fix/df-windows-bavail branch 4 times, most recently from d8a882b to 37f3d7a Compare February 15, 2026 06:35
@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/factor/t33. tests/factor/t33 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/timeout/timeout-group. tests/timeout/timeout-group is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/pr/bounded-memory (fails in this run but passes in the 'main' branch)
Congrats! The gnu test tests/basenc/bounded-memory is now passing!

@naoNao89 naoNao89 force-pushed the fix/df-windows-bavail branch 2 times, most recently from 0316c4d to e41963a Compare February 15, 2026 08:25
@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/factor/t10. tests/factor/t10 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/factor/t33. tests/factor/t33 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/factor/t34. tests/factor/t34 is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/pr/bounded-memory (fails in this run but passes in the 'main' branch)
Note: The gnu test tests/seq/seq-epipe is now being skipped but was previously passing.
Congrats! The gnu test tests/basenc/bounded-memory is now passing!

Comment on lines 1180 to 1181
"At least one filesystem should have non-zero available space. Got output:\n{}",
output
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"At least one filesystem should have non-zero available space. Got output:\n{}",
output
"At least one filesystem should have non-zero available space. Got output:\n{output}"

Fix Windows df incorrectly reporting 0 bytes available and 100% usage
for all filesystems. The issue was caused by hardcoding bavail
(blocks available to non-privileged processes) to 0 instead of using
the actual free clusters from Windows API.

Changes:
- Set bavail to number_of_free_clusters on Windows (was: 0)
- Add regression test test_windows_avail_column_not_zero

Fixes uutils#7461
@naoNao89 naoNao89 force-pushed the fix/df-windows-bavail branch from e41963a to 2fef881 Compare February 15, 2026 13:19
@github-actions
Copy link

GNU testsuite comparison:

Note: The gnu test tests/tail/pipe-f is now being skipped but was previously passing.
Congrats! The gnu test tests/env/env-signal-handler is now passing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

df: Incorrect avilable size and percent usage

2 participants