On Tue, Mar 18, 2025 at 12:23:47AM -0400, Theodore Ts'o wrote: > This fixes an analogus bug that was fixed in xfs in commit > 4b8d867ca6e2 ("xfs: don't over-report free space or inodes in > statvfs") where statfs can report misleading / incorrect information > where project quota is enabled, and the free space is less than the > remaining quota. > > This commit will resolve a test failure in generic/762 which tests for > this bug. > > Cc: stable@xxxxxxxxxx > Fixes: 689c958cbe6b ("ext4: add project quota support") > Signed-off-by: Theodore Ts'o <tytso@xxxxxxx> Yeah, that looks exactly like the xfs solution to this problem... Reviewed-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --D > --- > fs/ext4/super.c | 27 +++++++++++++++++---------- > 1 file changed, 17 insertions(+), 10 deletions(-) > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index 4768770715ca..8cafcd3e9f5f 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -6820,22 +6820,29 @@ static int ext4_statfs_project(struct super_block *sb, > dquot->dq_dqb.dqb_bhardlimit); > limit >>= sb->s_blocksize_bits; > > - if (limit && buf->f_blocks > limit) { > + if (limit) { > + uint64_t remaining = 0; > + > curblock = (dquot->dq_dqb.dqb_curspace + > dquot->dq_dqb.dqb_rsvspace) >> sb->s_blocksize_bits; > - buf->f_blocks = limit; > - buf->f_bfree = buf->f_bavail = > - (buf->f_blocks > curblock) ? > - (buf->f_blocks - curblock) : 0; > + if (limit > curblock) > + remaining = limit - curblock; > + > + buf->f_blocks = min(buf->f_blocks, limit); > + buf->f_bfree = min(buf->f_bfree, remaining); > + buf->f_bavail = min(buf->f_bavail, remaining); > } > > limit = min_not_zero(dquot->dq_dqb.dqb_isoftlimit, > dquot->dq_dqb.dqb_ihardlimit); > - if (limit && buf->f_files > limit) { > - buf->f_files = limit; > - buf->f_ffree = > - (buf->f_files > dquot->dq_dqb.dqb_curinodes) ? > - (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0; > + if (limit) { > + uint64_t remaining = 0; > + > + if (limit > dquot->dq_dqb.dqb_curinodes) > + remaining = limit - dquot->dq_dqb.dqb_curinodes; > + > + buf->f_files = min(buf->f_files, limit); > + buf->f_ffree = min(buf->f_ffree, remaining); > } > > spin_unlock(&dquot->dq_dqb_lock); > -- > 2.47.2 > >