xfs: squash prealloc while over quota free space as well

From: Brian Foster <bfoster@redhat.com>

Commit 4d559a3b introduced heavy prealloc. squashing to catch the case
of requesting too large a prealloc on smaller filesystems, leading to
repeated flush and retry cycles that occur on ENOSPC. Now that we issue
eofblocks scans on EDQUOT/ENOSPC, squash the prealloc against the
minimum available free space across all applicable quotas as well to
avoid a similar problem of repeated eofblocks scans.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
Brian Foster 2014-07-24 19:56:08 +10:00 committed by Dave Chinner
parent dc06f398f0
commit f074051ff5

View file

@ -397,7 +397,8 @@ xfs_quota_calc_throttle(
struct xfs_inode *ip,
int type,
xfs_fsblock_t *qblocks,
int *qshift)
int *qshift,
int64_t *qfreesp)
{
int64_t freesp;
int shift = 0;
@ -406,6 +407,7 @@ xfs_quota_calc_throttle(
/* over hi wmark, squash the prealloc completely */
if (dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
*qblocks = 0;
*qfreesp = 0;
return;
}
@ -418,6 +420,9 @@ xfs_quota_calc_throttle(
shift += 2;
}
if (freesp < *qfreesp)
*qfreesp = freesp;
/* only overwrite the throttle values if we are more aggressive */
if ((freesp >> shift) < (*qblocks >> *qshift)) {
*qblocks = freesp;
@ -476,15 +481,18 @@ xfs_iomap_prealloc_size(
}
/*
* Check each quota to cap the prealloc size and provide a shift
* value to throttle with.
* Check each quota to cap the prealloc size, provide a shift value to
* throttle with and adjust amount of available space.
*/
if (xfs_quota_need_throttle(ip, XFS_DQ_USER, alloc_blocks))
xfs_quota_calc_throttle(ip, XFS_DQ_USER, &qblocks, &qshift);
xfs_quota_calc_throttle(ip, XFS_DQ_USER, &qblocks, &qshift,
&freesp);
if (xfs_quota_need_throttle(ip, XFS_DQ_GROUP, alloc_blocks))
xfs_quota_calc_throttle(ip, XFS_DQ_GROUP, &qblocks, &qshift);
xfs_quota_calc_throttle(ip, XFS_DQ_GROUP, &qblocks, &qshift,
&freesp);
if (xfs_quota_need_throttle(ip, XFS_DQ_PROJ, alloc_blocks))
xfs_quota_calc_throttle(ip, XFS_DQ_PROJ, &qblocks, &qshift);
xfs_quota_calc_throttle(ip, XFS_DQ_PROJ, &qblocks, &qshift,
&freesp);
/*
* The final prealloc size is set to the minimum of free space available