From: "Darrick J. Wong" <djwong@kernel.org>
To: Emmanuel Florac <eflorac@intellique.com>
Cc: Dave Chinner <david@fromorbit.com>, linux-xfs@vger.kernel.org
Subject: Re: Weird behaviour with project quotas
Date: Fri, 13 Dec 2024 09:15:37 -0800 [thread overview]
Message-ID: <20241213171537.GL6698@frogsfrogsfrogs> (raw)
In-Reply-To: <20241213164251.361f8877@harpe.intellique.com>
On Fri, Dec 13, 2024 at 04:42:51PM +0100, Emmanuel Florac wrote:
> Le Thu, 12 Dec 2024 12:25:47 -0800
> "Darrick J. Wong" <djwong@kernel.org> écrivait:
>
>
> > Does this recreate the symptoms?
> >
> <snip>
> > # df /mnt /mnt/dir
> > Filesystem Size Used Avail Use% Mounted on
> > /dev/sda 20G 420M 20G 3% /mnt
> > /dev/sda 2.0G 0 2.0G 0% /mnt
> > # fallocate -l 19g /mnt/a
> > # df /mnt /mnt/dir
> > Filesystem Size Used Avail Use% Mounted on
> > /dev/sda 20G 20G 345M 99% /mnt
> > /dev/sda 2.0G 0 2.0G 0% /mnt
> >
> > Clearly, df should be reporting 345M available for both cases, since
> > we haven't actually used any of project 55's blocks.
> >
> > # xfs_io -f -c 'pwrite -S 0x59 0 1m' -c fsync -c 'stat -vvvv'
> > /mnt/dir/fork wrote 1048576/1048576 bytes at offset 0
> > 1 MiB, 256 ops; 0.0008 sec (1.121 GiB/sec and 293915.0402 ops/sec)
> > fd.path = "/mnt/dir/fork"
> > fd.flags = non-sync,non-direct,read-write
> > stat.ino = 134
> > stat.type = regular file
> > stat.size = 1048576
> > stat.blocks = 2048
> > stat.atime = Thu Dec 12 12:11:06 2024
> > stat.mtime = Thu Dec 12 12:11:06 2024
> > stat.ctime = Thu Dec 12 12:11:06 2024
> > fsxattr.xflags = 0x0 []
> > fsxattr.projid = 55
> > fsxattr.extsize = 0
> > fsxattr.cowextsize = 0
> > fsxattr.nextents = 1
> > fsxattr.naextents = 0
> > dioattr.mem = 0x200
> > dioattr.miniosz = 512
> > dioattr.maxiosz = 2147483136
> > # df /mnt /mnt/dir
> > Filesystem Size Used Avail Use% Mounted on
> > /dev/sda 20G 20G 344M 99% /mnt
> > /dev/sda 2.0G 1.0M 2.0G 1% /mnt
> >
> > I think this behavior comes from xfs_fill_statvfs_from_dquot, which
> > does this:
> >
> > limit = blkres->softlimit ?
> > blkres->softlimit :
> > blkres->hardlimit;
> > if (limit && statp->f_blocks > limit) {
> > statp->f_blocks = limit;
> > statp->f_bfree = statp->f_bavail =
> > (statp->f_blocks > blkres->reserved) ?
> > (statp->f_blocks - blkres->reserved) : 0;
> > }
> >
> > I think the f_bfree/f_bavail assignment is wrong because it doesn't
> > handle the case where f_bfree was less than (limit - reserved).
> >
> > if (limit) {
> > uint64_t remaining = 0;
> >
> > if (statp->f_blocks > limit)
> > statp->f_blocks = limit;
> > if (limit > blkres->reserved)
> > remaining = limit - blkres->reserved;
> > statp->f_bfree = min(statp->f_bfree, remaining);
> > statp->f_bavail = min(statp->f_bavail, remaining);
> > }
> >
> > This fixes the df output a bit:
> > # df /mnt /mnt/dir
> > Filesystem Size Used Avail Use% Mounted on
> > /dev/sda 20G 20G 344M 99% /mnt
> > /dev/sda 2.0G 1.7G 344M 84% /mnt
> >
> > Though the "used" column is nonsense now. But I guess that's why
> > statfs only defines total blocks and free/available blocks.
>
> Yep, that looks exactly like the problem we've met. Does the fact that
> not all folders have project quota change something in that case ?
No, I don't think that changes anything. If you can build your own
kernel, can you try this out?
--D
xfs: don't over-report free space or inodes in statvfs
Emmanual Florac reports a strange occurrence when project quota limits
are enabled, free space is lower than the remaining quota, and someone
runs statvfs:
# mkfs.xfs -f /dev/sda
# mount /dev/sda /mnt -o prjquota
# xfs_quota -x -c 'limit -p bhard=2G 55' /mnt
# mkdir /mnt/dir
# xfs_io -c 'chproj 55' -c 'chattr +P' -c 'stat -vvvv' /mnt/dir
# fallocate -l 19g /mnt/a
# df /mnt /mnt/dir
Filesystem Size Used Avail Use% Mounted on
/dev/sda 20G 20G 345M 99% /mnt
/dev/sda 2.0G 0 2.0G 0% /mnt
I think the bug here is that xfs_fill_statvfs_from_dquot unconditionally
assigns to f_bfree without checking that the filesystem has enough free
space to fill the remaining project quota. However, this is a
longstanding behavior of xfs so it's unclear what to do here.
Cc: <stable@vger.kernel.org> # v2.6.18
Fixes: 932f2c323196c2 ("[XFS] statvfs component of directory/project quota support, code originally by Glen.")
Reported-by: Emmanuel Florac <eflorac@intellique.com>
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
fs/xfs/xfs_qm_bhv.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
index 847ba29630e9d8..db5b8afd9d1b97 100644
--- a/fs/xfs/xfs_qm_bhv.c
+++ b/fs/xfs/xfs_qm_bhv.c
@@ -32,21 +32,28 @@ xfs_fill_statvfs_from_dquot(
limit = blkres->softlimit ?
blkres->softlimit :
blkres->hardlimit;
- if (limit && statp->f_blocks > limit) {
- statp->f_blocks = limit;
- statp->f_bfree = statp->f_bavail =
- (statp->f_blocks > blkres->reserved) ?
- (statp->f_blocks - blkres->reserved) : 0;
+ if (limit) {
+ uint64_t remaining = 0;
+
+ if (limit > blkres->reserved)
+ remaining = limit - blkres->reserved;
+
+ statp->f_blocks = min(statp->f_blocks, limit);
+ statp->f_bfree = min(statp->f_bfree, remaining);
+ statp->f_bavail = min(statp->f_bavail, remaining);
}
limit = dqp->q_ino.softlimit ?
dqp->q_ino.softlimit :
dqp->q_ino.hardlimit;
- if (limit && statp->f_files > limit) {
- statp->f_files = limit;
- statp->f_ffree =
- (statp->f_files > dqp->q_ino.reserved) ?
- (statp->f_files - dqp->q_ino.reserved) : 0;
+ if (limit) {
+ uint64_t remaining = 0;
+
+ if (limit > dqp->q_ino.reserved)
+ remaining = limit - dqp->q_ino.reserved;
+
+ statp->f_files = min(statp->f_files, limit);
+ statp->f_ffree = min(statp->f_ffree, remaining);
}
}
next prev parent reply other threads:[~2024-12-13 17:15 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-28 16:14 Weird behaviour with project quotas Emmanuel Florac
2024-11-28 21:07 ` Dave Chinner
2024-11-29 9:33 ` Emmanuel Florac
2024-11-29 22:14 ` Dave Chinner
2024-12-12 15:33 ` Emmanuel Florac
2024-12-12 20:25 ` Darrick J. Wong
2024-12-13 15:42 ` Emmanuel Florac
2024-12-13 17:15 ` Darrick J. Wong [this message]
2024-12-16 22:18 ` Emmanuel Florac
2024-12-17 16:50 ` Darrick J. Wong
2024-12-18 17:47 ` Emmanuel Florac
2024-12-18 17:55 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241213171537.GL6698@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=david@fromorbit.com \
--cc=eflorac@intellique.com \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox