Skip to content

Commit be60794

Browse files
cmaiolinodchinner
authored andcommitted
xfs: Split default quota limits by quota type
Default quotas are globally set due historical reasons. IRIX only supported user and project quotas, and default quota was only applied to user quotas. In Linux, when a default quota is set, all different quota types inherits the same default value. An user with a quota limit larger than the default quota value, will still be limited to the default value because the group quotas also inherits the default quotas. Unless the group which the user belongs to have a custom quota limit set. This patch aims to split the default quota value by quota type. Allowing each quota type having different default values. Default time limits are still set globally. XFS does not set a per-user/group timer, but a single global timer. For changing this behavior, some changes should be made in user-space tools another bugs being fixed. Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
1 parent 296c24e commit be60794

File tree

5 files changed

+103
-42
lines changed

5 files changed

+103
-42
lines changed

fs/xfs/xfs_dquot.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,26 +92,28 @@ xfs_qm_adjust_dqlimits(
9292
{
9393
struct xfs_quotainfo *q = mp->m_quotainfo;
9494
struct xfs_disk_dquot *d = &dq->q_core;
95+
struct xfs_def_quota *defq;
9596
int prealloc = 0;
9697

9798
ASSERT(d->d_id);
99+
defq = xfs_get_defquota(dq, q);
98100

99-
if (q->qi_bsoftlimit && !d->d_blk_softlimit) {
100-
d->d_blk_softlimit = cpu_to_be64(q->qi_bsoftlimit);
101+
if (defq->bsoftlimit && !d->d_blk_softlimit) {
102+
d->d_blk_softlimit = cpu_to_be64(defq->bsoftlimit);
101103
prealloc = 1;
102104
}
103-
if (q->qi_bhardlimit && !d->d_blk_hardlimit) {
104-
d->d_blk_hardlimit = cpu_to_be64(q->qi_bhardlimit);
105+
if (defq->bhardlimit && !d->d_blk_hardlimit) {
106+
d->d_blk_hardlimit = cpu_to_be64(defq->bhardlimit);
105107
prealloc = 1;
106108
}
107-
if (q->qi_isoftlimit && !d->d_ino_softlimit)
108-
d->d_ino_softlimit = cpu_to_be64(q->qi_isoftlimit);
109-
if (q->qi_ihardlimit && !d->d_ino_hardlimit)
110-
d->d_ino_hardlimit = cpu_to_be64(q->qi_ihardlimit);
111-
if (q->qi_rtbsoftlimit && !d->d_rtb_softlimit)
112-
d->d_rtb_softlimit = cpu_to_be64(q->qi_rtbsoftlimit);
113-
if (q->qi_rtbhardlimit && !d->d_rtb_hardlimit)
114-
d->d_rtb_hardlimit = cpu_to_be64(q->qi_rtbhardlimit);
109+
if (defq->isoftlimit && !d->d_ino_softlimit)
110+
d->d_ino_softlimit = cpu_to_be64(defq->isoftlimit);
111+
if (defq->ihardlimit && !d->d_ino_hardlimit)
112+
d->d_ino_hardlimit = cpu_to_be64(defq->ihardlimit);
113+
if (defq->rtbsoftlimit && !d->d_rtb_softlimit)
114+
d->d_rtb_softlimit = cpu_to_be64(defq->rtbsoftlimit);
115+
if (defq->rtbhardlimit && !d->d_rtb_hardlimit)
116+
d->d_rtb_hardlimit = cpu_to_be64(defq->rtbhardlimit);
115117

116118
if (prealloc)
117119
xfs_dquot_set_prealloc_limits(dq);

fs/xfs/xfs_qm.c

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,37 @@ xfs_qm_shrink_count(
560560
return list_lru_shrink_count(&qi->qi_lru, sc);
561561
}
562562

563+
STATIC void
564+
xfs_qm_set_defquota(
565+
xfs_mount_t *mp,
566+
uint type,
567+
xfs_quotainfo_t *qinf)
568+
{
569+
xfs_dquot_t *dqp;
570+
struct xfs_def_quota *defq;
571+
int error;
572+
573+
error = xfs_qm_dqread(mp, 0, type, XFS_QMOPT_DOWARN, &dqp);
574+
575+
if (!error) {
576+
xfs_disk_dquot_t *ddqp = &dqp->q_core;
577+
578+
defq = xfs_get_defquota(dqp, qinf);
579+
580+
/*
581+
* Timers and warnings have been already set, let's just set the
582+
* default limits for this quota type
583+
*/
584+
defq->bhardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
585+
defq->bsoftlimit = be64_to_cpu(ddqp->d_blk_softlimit);
586+
defq->ihardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
587+
defq->isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit);
588+
defq->rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
589+
defq->rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
590+
xfs_qm_dqdestroy(dqp);
591+
}
592+
}
593+
563594
/*
564595
* This initializes all the quota information that's kept in the
565596
* mount structure
@@ -606,19 +637,19 @@ xfs_qm_init_quotainfo(
606637
* We try to get the limits from the superuser's limits fields.
607638
* This is quite hacky, but it is standard quota practice.
608639
*
609-
* We look at the USR dquot with id == 0 first, but if user quotas
610-
* are not enabled we goto the GRP dquot with id == 0.
611-
* We don't really care to keep separate default limits for user
612-
* and group quotas, at least not at this point.
613-
*
614640
* Since we may not have done a quotacheck by this point, just read
615641
* the dquot without attaching it to any hashtables or lists.
642+
*
643+
* Timers and warnings are globally set by the first timer found in
644+
* user/group/proj quota types, otherwise a default value is used.
645+
* This should be split into different fields per quota type.
616646
*/
617647
error = xfs_qm_dqread(mp, 0,
618648
XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER :
619649
(XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP :
620650
XFS_DQ_PROJ),
621651
XFS_QMOPT_DOWARN, &dqp);
652+
622653
if (!error) {
623654
xfs_disk_dquot_t *ddqp = &dqp->q_core;
624655

@@ -639,13 +670,6 @@ xfs_qm_init_quotainfo(
639670
be16_to_cpu(ddqp->d_iwarns) : XFS_QM_IWARNLIMIT;
640671
qinf->qi_rtbwarnlimit = ddqp->d_rtbwarns ?
641672
be16_to_cpu(ddqp->d_rtbwarns) : XFS_QM_RTBWARNLIMIT;
642-
qinf->qi_bhardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
643-
qinf->qi_bsoftlimit = be64_to_cpu(ddqp->d_blk_softlimit);
644-
qinf->qi_ihardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
645-
qinf->qi_isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit);
646-
qinf->qi_rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
647-
qinf->qi_rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
648-
649673
xfs_qm_dqdestroy(dqp);
650674
} else {
651675
qinf->qi_btimelimit = XFS_QM_BTIMELIMIT;
@@ -656,6 +680,13 @@ xfs_qm_init_quotainfo(
656680
qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
657681
}
658682

683+
if (XFS_IS_UQUOTA_RUNNING(mp))
684+
xfs_qm_set_defquota(mp, XFS_DQ_USER, qinf);
685+
if (XFS_IS_GQUOTA_RUNNING(mp))
686+
xfs_qm_set_defquota(mp, XFS_DQ_GROUP, qinf);
687+
if (XFS_IS_PQUOTA_RUNNING(mp))
688+
xfs_qm_set_defquota(mp, XFS_DQ_PROJ, qinf);
689+
659690
qinf->qi_shrinker.count_objects = xfs_qm_shrink_count;
660691
qinf->qi_shrinker.scan_objects = xfs_qm_shrink_scan;
661692
qinf->qi_shrinker.seeks = DEFAULT_SEEKS;

fs/xfs/xfs_qm.h

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ extern struct kmem_zone *xfs_qm_dqtrxzone;
5353
*/
5454
#define XFS_DQUOT_CLUSTER_SIZE_FSB (xfs_filblks_t)1
5555

56+
struct xfs_def_quota {
57+
xfs_qcnt_t bhardlimit; /* default data blk hard limit */
58+
xfs_qcnt_t bsoftlimit; /* default data blk soft limit */
59+
xfs_qcnt_t ihardlimit; /* default inode count hard limit */
60+
xfs_qcnt_t isoftlimit; /* default inode count soft limit */
61+
xfs_qcnt_t rtbhardlimit; /* default realtime blk hard limit */
62+
xfs_qcnt_t rtbsoftlimit; /* default realtime blk soft limit */
63+
};
64+
5665
/*
5766
* Various quota information for individual filesystems.
5867
* The mount structure keeps a pointer to this.
@@ -76,12 +85,9 @@ typedef struct xfs_quotainfo {
7685
struct mutex qi_quotaofflock;/* to serialize quotaoff */
7786
xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */
7887
uint qi_dqperchunk; /* # ondisk dqs in above chunk */
79-
xfs_qcnt_t qi_bhardlimit; /* default data blk hard limit */
80-
xfs_qcnt_t qi_bsoftlimit; /* default data blk soft limit */
81-
xfs_qcnt_t qi_ihardlimit; /* default inode count hard limit */
82-
xfs_qcnt_t qi_isoftlimit; /* default inode count soft limit */
83-
xfs_qcnt_t qi_rtbhardlimit;/* default realtime blk hard limit */
84-
xfs_qcnt_t qi_rtbsoftlimit;/* default realtime blk soft limit */
88+
struct xfs_def_quota qi_usr_default;
89+
struct xfs_def_quota qi_grp_default;
90+
struct xfs_def_quota qi_prj_default;
8591
struct shrinker qi_shrinker;
8692
} xfs_quotainfo_t;
8793

@@ -171,4 +177,20 @@ extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint,
171177
extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint);
172178
extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint);
173179

180+
static inline struct xfs_def_quota *
181+
xfs_get_defquota(struct xfs_dquot *dqp, struct xfs_quotainfo *qi)
182+
{
183+
struct xfs_def_quota *defq;
184+
185+
if (XFS_QM_ISUDQ(dqp))
186+
defq = &qi->qi_usr_default;
187+
else if (XFS_QM_ISGDQ(dqp))
188+
defq = &qi->qi_grp_default;
189+
else {
190+
ASSERT(XFS_QM_ISPDQ(dqp));
191+
defq = &qi->qi_prj_default;
192+
}
193+
return defq;
194+
}
195+
174196
#endif /* __XFS_QM_H__ */

fs/xfs/xfs_qm_syscalls.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ xfs_qm_scall_setqlim(
404404
struct xfs_disk_dquot *ddq;
405405
struct xfs_dquot *dqp;
406406
struct xfs_trans *tp;
407+
struct xfs_def_quota *defq;
407408
int error;
408409
xfs_qcnt_t hard, soft;
409410

@@ -431,6 +432,8 @@ xfs_qm_scall_setqlim(
431432
ASSERT(error != -ENOENT);
432433
goto out_unlock;
433434
}
435+
436+
defq = xfs_get_defquota(dqp, q);
434437
xfs_dqunlock(dqp);
435438

436439
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
@@ -458,8 +461,8 @@ xfs_qm_scall_setqlim(
458461
ddq->d_blk_softlimit = cpu_to_be64(soft);
459462
xfs_dquot_set_prealloc_limits(dqp);
460463
if (id == 0) {
461-
q->qi_bhardlimit = hard;
462-
q->qi_bsoftlimit = soft;
464+
defq->bhardlimit = hard;
465+
defq->bsoftlimit = soft;
463466
}
464467
} else {
465468
xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft);
@@ -474,8 +477,8 @@ xfs_qm_scall_setqlim(
474477
ddq->d_rtb_hardlimit = cpu_to_be64(hard);
475478
ddq->d_rtb_softlimit = cpu_to_be64(soft);
476479
if (id == 0) {
477-
q->qi_rtbhardlimit = hard;
478-
q->qi_rtbsoftlimit = soft;
480+
defq->rtbhardlimit = hard;
481+
defq->rtbsoftlimit = soft;
479482
}
480483
} else {
481484
xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft);
@@ -491,8 +494,8 @@ xfs_qm_scall_setqlim(
491494
ddq->d_ino_hardlimit = cpu_to_be64(hard);
492495
ddq->d_ino_softlimit = cpu_to_be64(soft);
493496
if (id == 0) {
494-
q->qi_ihardlimit = hard;
495-
q->qi_isoftlimit = soft;
497+
defq->ihardlimit = hard;
498+
defq->isoftlimit = soft;
496499
}
497500
} else {
498501
xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft);

fs/xfs/xfs_trans_dquot.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -609,17 +609,20 @@ xfs_trans_dqresv(
609609
xfs_qcnt_t total_count;
610610
xfs_qcnt_t *resbcountp;
611611
xfs_quotainfo_t *q = mp->m_quotainfo;
612+
struct xfs_def_quota *defq;
612613

613614

614615
xfs_dqlock(dqp);
615616

617+
defq = xfs_get_defquota(dqp, q);
618+
616619
if (flags & XFS_TRANS_DQ_RES_BLKS) {
617620
hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
618621
if (!hardlimit)
619-
hardlimit = q->qi_bhardlimit;
622+
hardlimit = defq->bhardlimit;
620623
softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit);
621624
if (!softlimit)
622-
softlimit = q->qi_bsoftlimit;
625+
softlimit = defq->bsoftlimit;
623626
timer = be32_to_cpu(dqp->q_core.d_btimer);
624627
warns = be16_to_cpu(dqp->q_core.d_bwarns);
625628
warnlimit = dqp->q_mount->m_quotainfo->qi_bwarnlimit;
@@ -628,10 +631,10 @@ xfs_trans_dqresv(
628631
ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
629632
hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
630633
if (!hardlimit)
631-
hardlimit = q->qi_rtbhardlimit;
634+
hardlimit = defq->rtbhardlimit;
632635
softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit);
633636
if (!softlimit)
634-
softlimit = q->qi_rtbsoftlimit;
637+
softlimit = defq->rtbsoftlimit;
635638
timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
636639
warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
637640
warnlimit = dqp->q_mount->m_quotainfo->qi_rtbwarnlimit;
@@ -672,10 +675,10 @@ xfs_trans_dqresv(
672675
warnlimit = dqp->q_mount->m_quotainfo->qi_iwarnlimit;
673676
hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
674677
if (!hardlimit)
675-
hardlimit = q->qi_ihardlimit;
678+
hardlimit = defq->ihardlimit;
676679
softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
677680
if (!softlimit)
678-
softlimit = q->qi_isoftlimit;
681+
softlimit = defq->isoftlimit;
679682

680683
if (hardlimit && total_count > hardlimit) {
681684
xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);

0 commit comments

Comments
 (0)