Subject: df/total-verify fail with cephfs

From: Dylan Simon <[email-masked]>
Date: Wed, 5 Jan 2022 14:27:59 -0500

We have a filesystem that reports statfs f_files = nfiles, f_ffree = -1 
(UINTMAX_MAX).  (See rationale https://github.com/ceph/ceph/pull/36127)
Unfortunately this breaks df -i --total and in particular the df/total-verify
test fails.  Example output:

> df -i --total / /mnt/ceph
Filesystem        Inodes     IUsed    IFree IUse% Mounted on
/dev/sda1       20971520    529832 20441688    3% /
ceph           901006598         -        -     - /mnt/ceph
total          921978118 901536430 20441688   98% -

You can see that the total used is clearly not the computed total.  I think
this is because the individual rows use this logic for used:

  iv->used = UINTMAX_MAX;
  if (known_value (iv->total) && known_value (iv->available_to_root))
      iv->used = iv->total - iv->available_to_root;

while add_to_grand_total does them separately:

  if (known_value (iv->total))
    grand_fsu.fsu_files += iv->total;
  if (known_value (iv->available))
    grand_fsu.fsu_ffree += iv->available;

So the ceph line gets added to total but not available, and as a result, the
used computation of fsu_files - fsu_ffree = root.total + ceph.total -
root.available.  Maybe this is sensible but it's not what the test expects.

I can't think of a way to solve this that makes the test pass, aside from
collecting a grand_used total as well.  Only adding rows with all known values
might make sense but would still break the test (wrong total total instead):

  if (known_value (iv->total) && known_value (iv->available)) {
    grand_fsu.fsu_files += iv->total;
    grand_fsu.fsu_ffree += iv->available;
  }