mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] xfs: fix f_bfree underflow in statfs()
@ 2026-11-12 10:20 Hengyu Liang
  2026-11-12 13:44 ` Christoph Hellwig
  0 siblings, 1 reply; 3+ messages in thread
From: Hengyu Liang @ 2026-11-12 10:20 UTC (permalink / raw)
  To: Carlos Maiolino
  Cc: Darrick J. Wong, Christoph Hellwig, linux-xfs, linux-kernel, stable

Commit dd324cb79e54 ("xfs: refactor xfs_fs_statfs") made
xfs_statfs_data() limit f_bfree with max(0LL, ...) instead of
max_t(int64_t, 0, ...).

However, the value is an unsigned difference, so max() never picks 0.
As of now, when the free block counter is below the count of
unavailable blocks, statfs() reports f_bfree and f_bavail close to 2^64
instead of 0, and df prints negative sizes.

A similar issue happened before and was fixed by commit 237aac4624aa
("xfs: ensure f_bfree returned by statfs() is non-negative"). Perhaps
the refactored code needs that fix as well.

The issue can be reproduced on a new 2 GiB filesystem mounted on /mnt:

    for i in $(seq 3000); do head -c 65536 /dev/zero > /mnt/s$i; done
    dd if=/dev/zero of=/mnt/big bs=1M
    xfs_io -x -c 'resblks 100000000' /mnt
    for i in $(seq 1 2 3000); do rm /mnt/s$i; done
    sync
    df -h /mnt

Before commit dd324cb79e54 ("xfs: refactor xfs_fs_statfs"), the result
is:

    Filesystem      Size  Used Avail Use% Mounted on
    /dev/vda        2.0G  2.0G     0 100% /mnt

After that commit, the result is:

    Filesystem      Size  Used Avail Use% Mounted on
    /dev/vda        2.0G  -64Z  -24K 100% /mnt

This patch will compare the difference as a signed value again.

Fixes: dd324cb79e54 ("xfs: refactor xfs_fs_statfs")
Cc: stable@vger.kernel.org # v6.14
Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu>
---
The resblks ioctl only keeps the reproducer short. The same values show
up after filling a filesystem, writing with O_DIRECT into preallocated
space and deleting files.

Application impact (Ubuntu 26.04 user space, XFS root in that state):
on v6.13, "apt install" stops with "You don't have enough free space in
/var/cache/apt/archives/". On v6.14, it prints "18.4 EB available",
starts the download and fails with ENOSPC. GNOME's "Low Disk Space"
notification is sent on v6.13 and not on v6.14.

Tested on xfs for-next: with this patch, df, apt and the notification
behave as on v6.13.

 fs/xfs/xfs_super.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 5a06132aa384..42be6bd34d43 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -916,7 +916,7 @@ xfs_statfs_data(
 		xfs_sum_freecounter(mp, XC_FREE_BLOCKS);
 
 	/* make sure st->f_bfree does not underflow */
-	st->f_bfree = max(0LL,
+	st->f_bfree = max_t(int64_t, 0,
 		fdblocks - xfs_freecounter_unavailable(mp, XC_FREE_BLOCKS));
 
 	/*

base-commit: 48326a2382d80715475d10ce98734ac65d2d2150
-- 
2.53.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-11-12 15:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-12 10:20 [PATCH] xfs: fix f_bfree underflow in statfs() Hengyu Liang
2026-11-12 13:44 ` Christoph Hellwig
2026-11-12 15:07   ` Hengyu Liang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®