Skip to content
This repository was archived by the owner on Nov 3, 2025. It is now read-only.

Commit 2aaf4e5

Browse files
chaseyuCarlotta-Montelli
authored andcommitted
f2fs: don't over-report free space or inodes in statvfs
[ Upstream commit a9201960623287927bf5776de3f70fb2fbde7e02 ] This fixes an analogus bug that was fixed in modern filesystems: a) xfs in commit 4b8d867ca6e2 ("xfs: don't over-report free space or inodes in statvfs") b) ext4 in commit f87d3af74193 ("ext4: 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. generic/762 - output mismatch (see /share/git/fstests/results//generic/762.out.bad) # --- tests/generic/762.out 2025-04-15 10:21:53.371067071 +0800 # +++ /share/git/fstests/results//generic/762.out.bad 2025-05-13 16:13:37.000000000 +0800 # @@ -6,8 +6,10 @@ # root blocks2 is in range # dir blocks2 is in range # root bavail2 is in range # -dir bavail2 is in range # +dir bavail2 has value of 1539066 # +dir bavail2 is NOT in range 304734.87 .. 310891.13 # root blocks3 is in range # ... # (Run 'diff -u /share/git/fstests/tests/generic/762.out /share/git/fstests/results//generic/762.out.bad' to see the entire diff) HINT: You _MAY_ be missing kernel fix: XXXXXXXXXXXXXX xfs: don't over-report free space or inodes in statvfs Cc: [email protected] Fixes: ddc34e3 ("f2fs: introduce f2fs_statfs_project") Signed-off-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 14ecc65 commit 2aaf4e5

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

fs/f2fs/super.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,26 +1342,32 @@ static int f2fs_statfs_project(struct super_block *sb,
13421342

13431343
limit = min_not_zero(dquot->dq_dqb.dqb_bsoftlimit,
13441344
dquot->dq_dqb.dqb_bhardlimit);
1345-
if (limit)
1346-
limit >>= sb->s_blocksize_bits;
1345+
limit >>= sb->s_blocksize_bits;
1346+
1347+
if (limit) {
1348+
uint64_t remaining = 0;
13471349

1348-
if (limit && buf->f_blocks > limit) {
13491350
curblock = (dquot->dq_dqb.dqb_curspace +
13501351
dquot->dq_dqb.dqb_rsvspace) >> sb->s_blocksize_bits;
1351-
buf->f_blocks = limit;
1352-
buf->f_bfree = buf->f_bavail =
1353-
(buf->f_blocks > curblock) ?
1354-
(buf->f_blocks - curblock) : 0;
1352+
if (limit > curblock)
1353+
remaining = limit - curblock;
1354+
1355+
buf->f_blocks = min(buf->f_blocks, limit);
1356+
buf->f_bfree = min(buf->f_bfree, remaining);
1357+
buf->f_bavail = min(buf->f_bavail, remaining);
13551358
}
13561359

13571360
limit = min_not_zero(dquot->dq_dqb.dqb_isoftlimit,
13581361
dquot->dq_dqb.dqb_ihardlimit);
13591362

1360-
if (limit && buf->f_files > limit) {
1361-
buf->f_files = limit;
1362-
buf->f_ffree =
1363-
(buf->f_files > dquot->dq_dqb.dqb_curinodes) ?
1364-
(buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0;
1363+
if (limit) {
1364+
uint64_t remaining = 0;
1365+
1366+
if (limit > dquot->dq_dqb.dqb_curinodes)
1367+
remaining = limit - dquot->dq_dqb.dqb_curinodes;
1368+
1369+
buf->f_files = min(buf->f_files, limit);
1370+
buf->f_ffree = min(buf->f_ffree, remaining);
13651371
}
13661372

13671373
spin_unlock(&dquot->dq_dqb_lock);

0 commit comments

Comments
 (0)