aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_iomap.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 9072794e3a42..0a530853b53d 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -42,6 +42,8 @@
42#include "xfs_iomap.h" 42#include "xfs_iomap.h"
43#include "xfs_trace.h" 43#include "xfs_trace.h"
44#include "xfs_icache.h" 44#include "xfs_icache.h"
45#include "xfs_dquot_item.h"
46#include "xfs_dquot.h"
45 47
46 48
47#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \ 49#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
@@ -366,6 +368,61 @@ xfs_iomap_eof_prealloc_initial_size(
366 return XFS_B_TO_FSB(mp, offset); 368 return XFS_B_TO_FSB(mp, offset);
367} 369}
368 370
371STATIC bool
372xfs_quota_need_throttle(
373 struct xfs_inode *ip,
374 int type,
375 xfs_fsblock_t alloc_blocks)
376{
377 struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
378
379 if (!dq || !xfs_this_quota_on(ip->i_mount, type))
380 return false;
381
382 /* no hi watermark, no throttle */
383 if (!dq->q_prealloc_hi_wmark)
384 return false;
385
386 /* under the lo watermark, no throttle */
387 if (dq->q_res_bcount + alloc_blocks < dq->q_prealloc_lo_wmark)
388 return false;
389
390 return true;
391}
392
393STATIC void
394xfs_quota_calc_throttle(
395 struct xfs_inode *ip,
396 int type,
397 xfs_fsblock_t *qblocks,
398 int *qshift)
399{
400 int64_t freesp;
401 int shift = 0;
402 struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
403
404 /* over hi wmark, squash the prealloc completely */
405 if (dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
406 *qblocks = 0;
407 return;
408 }
409
410 freesp = dq->q_prealloc_hi_wmark - dq->q_res_bcount;
411 if (freesp < dq->q_low_space[XFS_QLOWSP_5_PCNT]) {
412 shift = 2;
413 if (freesp < dq->q_low_space[XFS_QLOWSP_3_PCNT])
414 shift += 2;
415 if (freesp < dq->q_low_space[XFS_QLOWSP_1_PCNT])
416 shift += 2;
417 }
418
419 /* only overwrite the throttle values if we are more aggressive */
420 if ((freesp >> shift) < (*qblocks >> *qshift)) {
421 *qblocks = freesp;
422 *qshift = shift;
423 }
424}
425
369/* 426/*
370 * If we don't have a user specified preallocation size, dynamically increase 427 * If we don't have a user specified preallocation size, dynamically increase
371 * the preallocation size as the size of the file grows. Cap the maximum size 428 * the preallocation size as the size of the file grows. Cap the maximum size
@@ -383,11 +440,14 @@ xfs_iomap_prealloc_size(
383 xfs_fsblock_t alloc_blocks = 0; 440 xfs_fsblock_t alloc_blocks = 0;
384 int shift = 0; 441 int shift = 0;
385 int64_t freesp; 442 int64_t freesp;
443 xfs_fsblock_t qblocks;
444 int qshift = 0;
386 445
387 alloc_blocks = xfs_iomap_eof_prealloc_initial_size(mp, ip, offset, 446 alloc_blocks = xfs_iomap_eof_prealloc_initial_size(mp, ip, offset,
388 imap, nimaps); 447 imap, nimaps);
389 if (!alloc_blocks) 448 if (!alloc_blocks)
390 goto check_writeio; 449 goto check_writeio;
450 qblocks = alloc_blocks;
391 451
392 /* 452 /*
393 * MAXEXTLEN is not a power of two value but we round the prealloc down 453 * MAXEXTLEN is not a power of two value but we round the prealloc down
@@ -412,6 +472,28 @@ xfs_iomap_prealloc_size(
412 if (freesp < mp->m_low_space[XFS_LOWSP_1_PCNT]) 472 if (freesp < mp->m_low_space[XFS_LOWSP_1_PCNT])
413 shift++; 473 shift++;
414 } 474 }
475
476 /*
477 * Check each quota to cap the prealloc size and provide a shift
478 * value to throttle with.
479 */
480 if (xfs_quota_need_throttle(ip, XFS_DQ_USER, alloc_blocks))
481 xfs_quota_calc_throttle(ip, XFS_DQ_USER, &qblocks, &qshift);
482 if (xfs_quota_need_throttle(ip, XFS_DQ_GROUP, alloc_blocks))
483 xfs_quota_calc_throttle(ip, XFS_DQ_GROUP, &qblocks, &qshift);
484 if (xfs_quota_need_throttle(ip, XFS_DQ_PROJ, alloc_blocks))
485 xfs_quota_calc_throttle(ip, XFS_DQ_PROJ, &qblocks, &qshift);
486
487 /*
488 * The final prealloc size is set to the minimum of free space available
489 * in each of the quotas and the overall filesystem.
490 *
491 * The shift throttle value is set to the maximum value as determined by
492 * the global low free space values and per-quota low free space values.
493 */
494 alloc_blocks = MIN(alloc_blocks, qblocks);
495 shift = MAX(shift, qshift);
496
415 if (shift) 497 if (shift)
416 alloc_blocks >>= shift; 498 alloc_blocks >>= shift;
417 /* 499 /*