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: Stu Brodsky <sbrodsky@sgi.com> Signed-off-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
parent
efceab1d56
commit
2fe33661fc
|
@ -1226,6 +1226,7 @@ xfs_fs_statfs(
|
||||||
struct xfs_inode *ip = XFS_I(dentry->d_inode);
|
struct xfs_inode *ip = XFS_I(dentry->d_inode);
|
||||||
__uint64_t fakeinos, id;
|
__uint64_t fakeinos, id;
|
||||||
xfs_extlen_t lsize;
|
xfs_extlen_t lsize;
|
||||||
|
__int64_t ffree;
|
||||||
|
|
||||||
statp->f_type = XFS_SB_MAGIC;
|
statp->f_type = XFS_SB_MAGIC;
|
||||||
statp->f_namelen = MAXNAMELEN - 1;
|
statp->f_namelen = MAXNAMELEN - 1;
|
||||||
|
@ -1249,7 +1250,11 @@ xfs_fs_statfs(
|
||||||
statp->f_files = min_t(typeof(statp->f_files),
|
statp->f_files = min_t(typeof(statp->f_files),
|
||||||
statp->f_files,
|
statp->f_files,
|
||||||
mp->m_maxicount);
|
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);
|
spin_unlock(&mp->m_sb_lock);
|
||||||
|
|
||||||
if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
|
if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
|
||||||
|
|
Loading…
Reference in a new issue