xfs: don't report reserved bnobt space as available
authorDarrick J. Wong <djwong@kernel.org>
Wed, 16 Mar 2022 20:38:43 +0000 (13:38 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 28 Mar 2022 15:39:10 +0000 (08:39 -0700)
On a modern filesystem, we don't allow userspace to allocate blocks for
data storage from the per-AG space reservations, the user-controlled
reservation pool that prevents ENOSPC in the middle of internal
operations, or the internal per-AG set-aside that prevents unwanted
filesystem shutdowns due to ENOSPC during a bmap btree split.

Since we now consider freespace btree blocks as unavailable for
allocation for data storage, we shouldn't report those blocks via statfs
either.  This makes the numbers that we return via the statfs f_bavail
and f_bfree fields a more conservative estimate of actual free space.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/xfs_fsops.c
fs/xfs/xfs_super.c

index 5b5b68affe66d083552fde0bb582e0efec50a4eb..196e2c51309c39afdd7beacc96101bfbb3eea393 100644 (file)
@@ -347,7 +347,7 @@ xfs_fs_counts(
        cnt->allocino = percpu_counter_read_positive(&mp->m_icount);
        cnt->freeino = percpu_counter_read_positive(&mp->m_ifree);
        cnt->freedata = percpu_counter_read_positive(&mp->m_fdblocks) -
        cnt->allocino = percpu_counter_read_positive(&mp->m_icount);
        cnt->freeino = percpu_counter_read_positive(&mp->m_ifree);
        cnt->freedata = percpu_counter_read_positive(&mp->m_fdblocks) -
-                                               mp->m_alloc_set_aside;
+                                               xfs_fdblocks_unavailable(mp);
 
        spin_lock(&mp->m_sb_lock);
        cnt->freertx = mp->m_sb.sb_frextents;
 
        spin_lock(&mp->m_sb_lock);
        cnt->freertx = mp->m_sb.sb_frextents;
index d84714e4e46a2a536f3920bc29d63776f0e79f40..54be9d64093edacfaea509ff2d1e73cf61a58493 100644 (file)
@@ -815,7 +815,8 @@ xfs_fs_statfs(
        spin_unlock(&mp->m_sb_lock);
 
        /* make sure statp->f_bfree does not underflow */
        spin_unlock(&mp->m_sb_lock);
 
        /* make sure statp->f_bfree does not underflow */
-       statp->f_bfree = max_t(int64_t, fdblocks - mp->m_alloc_set_aside, 0);
+       statp->f_bfree = max_t(int64_t, 0,
+                               fdblocks - xfs_fdblocks_unavailable(mp));
        statp->f_bavail = statp->f_bfree;
 
        fakeinos = XFS_FSB_TO_INO(mp, statp->f_bfree);
        statp->f_bavail = statp->f_bfree;
 
        fakeinos = XFS_FSB_TO_INO(mp, statp->f_bfree);