Skip to content

Commit 5dd7085

Browse files
author
Darrick J. Wong
committed
xfs: create quota preallocation watermarks for realtime quota
Refactor the quota preallocation watermarking code so that it'll work for realtime quota too. Convert the do_div calls into div_u64 for compactness. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
1 parent 9a17ebf commit 5dd7085

File tree

4 files changed

+81
-32
lines changed

4 files changed

+81
-32
lines changed

fs/xfs/xfs_dquot.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,25 @@ xfs_qm_init_dquot_blk(
277277
xfs_trans_log_buf(tp, bp, 0, BBTOB(q->qi_dqchunklen) - 1);
278278
}
279279

280+
static void
281+
xfs_dquot_set_prealloc(
282+
struct xfs_dquot_pre *pre,
283+
const struct xfs_dquot_res *res)
284+
{
285+
xfs_qcnt_t space;
286+
287+
pre->q_prealloc_hi_wmark = res->hardlimit;
288+
pre->q_prealloc_lo_wmark = res->softlimit;
289+
290+
space = div_u64(pre->q_prealloc_hi_wmark, 100);
291+
if (!pre->q_prealloc_lo_wmark)
292+
pre->q_prealloc_lo_wmark = space * 95;
293+
294+
pre->q_low_space[XFS_QLOWSP_1_PCNT] = space;
295+
pre->q_low_space[XFS_QLOWSP_3_PCNT] = space * 3;
296+
pre->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5;
297+
}
298+
280299
/*
281300
* Initialize the dynamic speculative preallocation thresholds. The lo/hi
282301
* watermarks correspond to the soft and hard limits by default. If a soft limit
@@ -285,22 +304,8 @@ xfs_qm_init_dquot_blk(
285304
void
286305
xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
287306
{
288-
uint64_t space;
289-
290-
dqp->q_prealloc_hi_wmark = dqp->q_blk.hardlimit;
291-
dqp->q_prealloc_lo_wmark = dqp->q_blk.softlimit;
292-
if (!dqp->q_prealloc_lo_wmark) {
293-
dqp->q_prealloc_lo_wmark = dqp->q_prealloc_hi_wmark;
294-
do_div(dqp->q_prealloc_lo_wmark, 100);
295-
dqp->q_prealloc_lo_wmark *= 95;
296-
}
297-
298-
space = dqp->q_prealloc_hi_wmark;
299-
300-
do_div(space, 100);
301-
dqp->q_low_space[XFS_QLOWSP_1_PCNT] = space;
302-
dqp->q_low_space[XFS_QLOWSP_3_PCNT] = space * 3;
303-
dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5;
307+
xfs_dquot_set_prealloc(&dqp->q_blk_prealloc, &dqp->q_blk);
308+
xfs_dquot_set_prealloc(&dqp->q_rtb_prealloc, &dqp->q_rtb);
304309
}
305310

306311
/*

fs/xfs/xfs_dquot.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ xfs_dquot_res_over_limits(
5656
return false;
5757
}
5858

59+
struct xfs_dquot_pre {
60+
xfs_qcnt_t q_prealloc_lo_wmark;
61+
xfs_qcnt_t q_prealloc_hi_wmark;
62+
int64_t q_low_space[XFS_QLOWSP_MAX];
63+
};
64+
5965
/*
6066
* The incore dquot structure
6167
*/
@@ -76,9 +82,9 @@ struct xfs_dquot {
7682

7783
struct xfs_dq_logitem q_logitem;
7884

79-
xfs_qcnt_t q_prealloc_lo_wmark;
80-
xfs_qcnt_t q_prealloc_hi_wmark;
81-
int64_t q_low_space[XFS_QLOWSP_MAX];
85+
struct xfs_dquot_pre q_blk_prealloc;
86+
struct xfs_dquot_pre q_rtb_prealloc;
87+
8288
struct mutex q_qlock;
8389
struct completion q_flush;
8490
atomic_t q_pincount;
@@ -192,7 +198,11 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
192198
int64_t freesp;
193199

194200
freesp = dqp->q_blk.hardlimit - dqp->q_blk.reserved;
195-
if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
201+
if (freesp < dqp->q_blk_prealloc.q_low_space[XFS_QLOWSP_1_PCNT])
202+
return true;
203+
204+
freesp = dqp->q_rtb.hardlimit - dqp->q_rtb.reserved;
205+
if (freesp < dqp->q_rtb_prealloc.q_low_space[XFS_QLOWSP_1_PCNT])
196206
return true;
197207

198208
return false;

fs/xfs/xfs_iomap.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,16 +353,26 @@ xfs_quota_need_throttle(
353353
xfs_fsblock_t alloc_blocks)
354354
{
355355
struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
356+
struct xfs_dquot_res *res;
357+
struct xfs_dquot_pre *pre;
356358

357359
if (!dq || !xfs_this_quota_on(ip->i_mount, type))
358360
return false;
359361

362+
if (XFS_IS_REALTIME_INODE(ip)) {
363+
res = &dq->q_rtb;
364+
pre = &dq->q_rtb_prealloc;
365+
} else {
366+
res = &dq->q_blk;
367+
pre = &dq->q_blk_prealloc;
368+
}
369+
360370
/* no hi watermark, no throttle */
361-
if (!dq->q_prealloc_hi_wmark)
371+
if (!pre->q_prealloc_hi_wmark)
362372
return false;
363373

364374
/* under the lo watermark, no throttle */
365-
if (dq->q_blk.reserved + alloc_blocks < dq->q_prealloc_lo_wmark)
375+
if (res->reserved + alloc_blocks < pre->q_prealloc_lo_wmark)
366376
return false;
367377

368378
return true;
@@ -377,22 +387,35 @@ xfs_quota_calc_throttle(
377387
int64_t *qfreesp)
378388
{
379389
struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
390+
struct xfs_dquot_res *res;
391+
struct xfs_dquot_pre *pre;
380392
int64_t freesp;
381393
int shift = 0;
382394

395+
if (!dq) {
396+
res = NULL;
397+
pre = NULL;
398+
} else if (XFS_IS_REALTIME_INODE(ip)) {
399+
res = &dq->q_rtb;
400+
pre = &dq->q_rtb_prealloc;
401+
} else {
402+
res = &dq->q_blk;
403+
pre = &dq->q_blk_prealloc;
404+
}
405+
383406
/* no dq, or over hi wmark, squash the prealloc completely */
384-
if (!dq || dq->q_blk.reserved >= dq->q_prealloc_hi_wmark) {
407+
if (!res || res->reserved >= pre->q_prealloc_hi_wmark) {
385408
*qblocks = 0;
386409
*qfreesp = 0;
387410
return;
388411
}
389412

390-
freesp = dq->q_prealloc_hi_wmark - dq->q_blk.reserved;
391-
if (freesp < dq->q_low_space[XFS_QLOWSP_5_PCNT]) {
413+
freesp = pre->q_prealloc_hi_wmark - res->reserved;
414+
if (freesp < pre->q_low_space[XFS_QLOWSP_5_PCNT]) {
392415
shift = 2;
393-
if (freesp < dq->q_low_space[XFS_QLOWSP_3_PCNT])
416+
if (freesp < pre->q_low_space[XFS_QLOWSP_3_PCNT])
394417
shift += 2;
395-
if (freesp < dq->q_low_space[XFS_QLOWSP_1_PCNT])
418+
if (freesp < pre->q_low_space[XFS_QLOWSP_1_PCNT])
396419
shift += 2;
397420
}
398421

fs/xfs/xfs_qm.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2178,6 +2178,8 @@ xfs_inode_near_dquot_enforcement(
21782178
xfs_dqtype_t type)
21792179
{
21802180
struct xfs_dquot *dqp;
2181+
struct xfs_dquot_res *res;
2182+
struct xfs_dquot_pre *pre;
21812183
int64_t freesp;
21822184

21832185
/* We only care for quotas that are enabled and enforced. */
@@ -2186,21 +2188,30 @@ xfs_inode_near_dquot_enforcement(
21862188
return false;
21872189

21882190
if (xfs_dquot_res_over_limits(&dqp->q_ino) ||
2191+
xfs_dquot_res_over_limits(&dqp->q_blk) ||
21892192
xfs_dquot_res_over_limits(&dqp->q_rtb))
21902193
return true;
21912194

2195+
if (XFS_IS_REALTIME_INODE(ip)) {
2196+
res = &dqp->q_rtb;
2197+
pre = &dqp->q_rtb_prealloc;
2198+
} else {
2199+
res = &dqp->q_blk;
2200+
pre = &dqp->q_blk_prealloc;
2201+
}
2202+
21922203
/* For space on the data device, check the various thresholds. */
2193-
if (!dqp->q_prealloc_hi_wmark)
2204+
if (!pre->q_prealloc_hi_wmark)
21942205
return false;
21952206

2196-
if (dqp->q_blk.reserved < dqp->q_prealloc_lo_wmark)
2207+
if (res->reserved < pre->q_prealloc_lo_wmark)
21972208
return false;
21982209

2199-
if (dqp->q_blk.reserved >= dqp->q_prealloc_hi_wmark)
2210+
if (res->reserved >= pre->q_prealloc_hi_wmark)
22002211
return true;
22012212

2202-
freesp = dqp->q_prealloc_hi_wmark - dqp->q_blk.reserved;
2203-
if (freesp < dqp->q_low_space[XFS_QLOWSP_5_PCNT])
2213+
freesp = pre->q_prealloc_hi_wmark - res->reserved;
2214+
if (freesp < pre->q_low_space[XFS_QLOWSP_5_PCNT])
22042215
return true;
22052216

22062217
return false;

0 commit comments

Comments
 (0)