xfs
[Top] [All Lists]

[PATCH 5/5] xfs: squash prealloc while over quota free space as well

To: xfs@xxxxxxxxxxx
Subject: [PATCH 5/5] xfs: squash prealloc while over quota free space as well
From: Brian Foster <bfoster@xxxxxxxxxx>
Date: Fri, 28 Mar 2014 09:16:03 -0400
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1396012563-60973-1-git-send-email-bfoster@xxxxxxxxxx>
References: <1396012563-60973-1-git-send-email-bfoster@xxxxxxxxxx>
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 (with a selective flush in the case of
project quotas), 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@xxxxxxxxxx>
---
 fs/xfs/xfs_iomap.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 22d1cbe..934983a 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -401,7 +401,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;
@@ -410,6 +411,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;
        }
 
@@ -422,6 +424,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;
@@ -480,15 +485,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
-- 
1.8.3.1

<Prev in Thread] Current Thread [Next in Thread>