Skip to content

Commit 7338419

Browse files
Ravi Singhcmaiolino
authored andcommitted
xfs: return default quota limits for IDs without a dquot
When an ID has no dquot on disk, Q_XGETQUOTA returns -ENOENT even though default quota limits are configured and enforced against that ID. This means unprivileged users who have never used any resources cannot see the limits that apply to them. When xfs_qm_dqget() returns -ENOENT for a non-zero ID, return a zero-usage response with the default limits filled in from m_quotainfo rather than propagating the error. This is consistent with the enforcement behavior in xfs_qm_adjust_dqlimits(), which pushes the same default limits into a dquot when it is first allocated. Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Ravi Singh <ravising@redhat.com> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
1 parent 181ea4e commit 7338419

1 file changed

Lines changed: 42 additions & 1 deletion

File tree

fs/xfs/xfs_qm_syscalls.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,38 @@ xfs_qm_scall_setqlim(
391391
return error;
392392
}
393393

394+
/*
395+
* Fill out the default quota limits for an ID that has no dquot on disk.
396+
* Returns 0 if default limits are configured
397+
* and were filled in, -ENOENT otherwise.
398+
*/
399+
static int
400+
xfs_qm_scall_getquota_fill_defaults(
401+
struct xfs_mount *mp,
402+
xfs_dqtype_t type,
403+
struct qc_dqblk *dst)
404+
{
405+
struct xfs_def_quota *defq;
406+
407+
defq = xfs_get_defquota(mp->m_quotainfo, type);
408+
409+
if (!defq->blk.soft && !defq->blk.hard &&
410+
!defq->ino.soft && !defq->ino.hard &&
411+
!defq->rtb.soft && !defq->rtb.hard) {
412+
return -ENOENT;
413+
}
414+
415+
memset(dst, 0, sizeof(*dst));
416+
dst->d_spc_softlimit = XFS_FSB_TO_B(mp, defq->blk.soft);
417+
dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, defq->blk.hard);
418+
dst->d_ino_softlimit = defq->ino.soft;
419+
dst->d_ino_hardlimit = defq->ino.hard;
420+
dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, defq->rtb.soft);
421+
dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, defq->rtb.hard);
422+
423+
return 0;
424+
}
425+
394426
/* Fill out the quota context. */
395427
static void
396428
xfs_qm_scall_getquota_fill_qc(
@@ -451,8 +483,17 @@ xfs_qm_scall_getquota(
451483
* set doalloc. If it doesn't exist, we'll get ENOENT back.
452484
*/
453485
error = xfs_qm_dqget(mp, id, type, false, &dqp);
454-
if (error)
486+
if (error) {
487+
/*
488+
* If there is no dquot on disk and default limits are
489+
* configured, return them with zero usage so that
490+
* unprivileged users can see what limits apply to them.
491+
*/
492+
if (error == -ENOENT && id != 0 &&
493+
!xfs_qm_scall_getquota_fill_defaults(mp, type, dst))
494+
return 0;
455495
return error;
496+
}
456497

457498
/*
458499
* If everything's NULL, this dquot doesn't quite exist as far as

0 commit comments

Comments
 (0)