FAT32 statfs(2) inode usage

From: Ben Woods <woodsb02_at_freebsd.org>
Date: Mon, 06 Mar 2023 05:41:50 UTC
Hi Everyone,

I'm using Netdata to monitor my FreeBSD systems, and it is reporting critical alerts that my UEFI system partition has run out of available inodes. Investigating a bit further, I realised that the FreeBSD df(1) utility is reporting the same, meaning this is a FreeBSD bug rather than a Netdata bug.

$ df -i /boot/efi
Filesystem  512-blocks Used  Avail Capacity iused ifree %iused  Mounted on
/dev/nvd0p1     532352 3680 528672     1%     512     0  100%   /boot/efi

It looks like this stems from the following section of the msdosfs(5) driver code sys/fs/msdosfs/msdosfs_vfsops.c:
----------------------------
static int
msdosfs_statfs(struct mount *mp, struct statfs *sbp)
{
	struct msdosfsmount *pmp;

	pmp = VFSTOMSDOSFS(mp);
	sbp->f_bsize = pmp->pm_bpcluster;
	sbp->f_iosize = pmp->pm_bpcluster;
	sbp->f_blocks = pmp->pm_maxcluster + 1;
	sbp->f_bfree = pmp->pm_freeclustercount;
	sbp->f_bavail = pmp->pm_freeclustercount;
	sbp->f_files = pmp->pm_RootDirEnts;	/* XXX */
	sbp->f_ffree = 0;	/* what to put in here? */
	return (0);
}
----------------------------

I think it might be more correct for msdosfs_vfsops.c to set the f_files variable to 0. Thoughts on this change?

This would then cause the following df(1) code to report iused% as "-" rather than "100%":
----------------------------
inodes = sfsp->f_files;
used = inodes - sfsp->f_ffree;
...
if (inodes == 0)
	xo_emit(" {:inodes-used-percent/    -}{U:} ");
else {
	xo_emit(" {:inodes-used-percent/%4.0f}{U:%%} ",
		(double)used / (double)inodes * 100.0);
}
----------------------------

This would then give an df(1) output which is consistent with GNU/Linux - see below test results from Debian 11:
# df -i /mnt/fat32
Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/vdb1           0     0     0     - /mnt/fat32

Regards,
Ben

--
From: Ben Woods
woodsb02@freebsd.org