Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f074051f authored by Brian Foster's avatar Brian Foster Committed by Dave Chinner
Browse files

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: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent dc06f398
Loading
Loading
Loading
Loading
+14 −6
Original line number Original line Diff line number Diff line
@@ -397,7 +397,8 @@ xfs_quota_calc_throttle(
	struct xfs_inode *ip,
	struct xfs_inode *ip,
	int type,
	int type,
	xfs_fsblock_t *qblocks,
	xfs_fsblock_t *qblocks,
	int *qshift)
	int *qshift,
	int64_t	*qfreesp)
{
{
	int64_t freesp;
	int64_t freesp;
	int shift = 0;
	int shift = 0;
@@ -406,6 +407,7 @@ xfs_quota_calc_throttle(
	/* over hi wmark, squash the prealloc completely */
	/* over hi wmark, squash the prealloc completely */
	if (dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
	if (dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
		*qblocks = 0;
		*qblocks = 0;
		*qfreesp = 0;
		return;
		return;
	}
	}


@@ -418,6 +420,9 @@ xfs_quota_calc_throttle(
			shift += 2;
			shift += 2;
	}
	}


	if (freesp < *qfreesp)
		*qfreesp = freesp;

	/* only overwrite the throttle values if we are more aggressive */
	/* only overwrite the throttle values if we are more aggressive */
	if ((freesp >> shift) < (*qblocks >> *qshift)) {
	if ((freesp >> shift) < (*qblocks >> *qshift)) {
		*qblocks = freesp;
		*qblocks = freesp;
@@ -476,15 +481,18 @@ xfs_iomap_prealloc_size(
	}
	}


	/*
	/*
	 * Check each quota to cap the prealloc size and provide a shift
	 * Check each quota to cap the prealloc size, provide a shift value to
	 * value to throttle with.
	 * throttle with and adjust amount of available space.
	 */
	 */
	if (xfs_quota_need_throttle(ip, XFS_DQ_USER, alloc_blocks))
	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))
	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))
	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
	 * The final prealloc size is set to the minimum of free space available