Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2fe33661 authored by Stuart Brodsky's avatar Stuart Brodsky Committed by Dave Chinner
Browse files

xfs: ensure f_ffree returned by statfs() is non-negative



Because of delayed updates to sb_icount field in the super block, it
is possible to allocate over maxicount number of inodes.  This
causes the arithmetic to calculate a negative number of free inodes
in user commands like df or stat -f.

Since maxicount is a somewhat arbitrary number, a slight over
allocation is not critical but user commands should be displayed as
0 or greater and never go negative.  To do this the value in the
stats buffer f_ffree is capped to never go negative.

[ Modified to use max_t as per Christoph's comment. ]

Signed-off-by: default avatarStu Brodsky <sbrodsky@sgi.com>
Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
parent efceab1d
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1226,6 +1226,7 @@ xfs_fs_statfs(
	struct xfs_inode	*ip = XFS_I(dentry->d_inode);
	__uint64_t		fakeinos, id;
	xfs_extlen_t		lsize;
	__int64_t		ffree;

	statp->f_type = XFS_SB_MAGIC;
	statp->f_namelen = MAXNAMELEN - 1;
@@ -1249,7 +1250,11 @@ xfs_fs_statfs(
		statp->f_files = min_t(typeof(statp->f_files),
					statp->f_files,
					mp->m_maxicount);
	statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);

	/* make sure statp->f_ffree does not underflow */
	ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
	statp->f_ffree = max_t(__int64_t, ffree, 0);

	spin_unlock(&mp->m_sb_lock);

	if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||