xfs: merge xfs_ag.h into xfs_format.h
[firefly-linux-kernel-4.4.55.git] / fs / xfs / xfs_iomap.c
index 6d3ec2b6ee294c7ec38e28fd32376162276f1005..7ab365a960172aaacaed19244219fdc91cab8cc6 100644 (file)
@@ -22,7 +22,6 @@
 #include "xfs_log_format.h"
 #include "xfs_trans_resv.h"
 #include "xfs_sb.h"
-#include "xfs_ag.h"
 #include "xfs_mount.h"
 #include "xfs_inode.h"
 #include "xfs_btree.h"
@@ -38,7 +37,6 @@
 #include "xfs_quota.h"
 #include "xfs_dquot_item.h"
 #include "xfs_dquot.h"
-#include "xfs_dinode.h"
 
 
 #define XFS_WRITEIO_ALIGN(mp,off)      (((off) >> mp->m_writeio_log) \
@@ -110,7 +108,7 @@ xfs_alert_fsblock_zero(
                (unsigned long long)imap->br_startoff,
                (unsigned long long)imap->br_blockcount,
                imap->br_state);
-       return EFSCORRUPTED;
+       return -EFSCORRUPTED;
 }
 
 int
@@ -138,7 +136,7 @@ xfs_iomap_write_direct(
 
        error = xfs_qm_dqattach(ip, 0);
        if (error)
-               return XFS_ERROR(error);
+               return error;
 
        rt = XFS_IS_REALTIME_INODE(ip);
        extsz = xfs_get_extsz_hint(ip);
@@ -148,7 +146,7 @@ xfs_iomap_write_direct(
        if ((offset + count) > XFS_ISIZE(ip)) {
                error = xfs_iomap_eof_align_last_fsb(mp, ip, extsz, &last_fsb);
                if (error)
-                       return XFS_ERROR(error);
+                       return error;
        } else {
                if (nmaps && (imap->br_startblock == HOLESTARTBLOCK))
                        last_fsb = MIN(last_fsb, (xfs_fileoff_t)
@@ -188,7 +186,7 @@ xfs_iomap_write_direct(
         */
        if (error) {
                xfs_trans_cancel(tp, 0);
-               return XFS_ERROR(error);
+               return error;
        }
 
        xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -225,7 +223,7 @@ xfs_iomap_write_direct(
         * Copy any maps to caller's array and return any error.
         */
        if (nimaps == 0) {
-               error = XFS_ERROR(ENOSPC);
+               error = -ENOSPC;
                goto out_unlock;
        }
 
@@ -397,15 +395,17 @@ 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;
        struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
 
-       /* over hi wmark, squash the prealloc completely */
-       if (dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
+       /* no dq, or over hi wmark, squash the prealloc completely */
+       if (!dq || dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
                *qblocks = 0;
+               *qfreesp = 0;
                return;
        }
 
@@ -418,6 +418,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 +479,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
@@ -552,7 +558,7 @@ xfs_iomap_write_delay(
         */
        error = xfs_qm_dqattach_locked(ip, 0);
        if (error)
-               return XFS_ERROR(error);
+               return error;
 
        extsz = xfs_get_extsz_hint(ip);
        offset_fsb = XFS_B_TO_FSBT(mp, offset);
@@ -596,11 +602,11 @@ retry:
                                imap, &nimaps, XFS_BMAPI_ENTIRE);
        switch (error) {
        case 0:
-       case ENOSPC:
-       case EDQUOT:
+       case -ENOSPC:
+       case -EDQUOT:
                break;
        default:
-               return XFS_ERROR(error);
+               return error;
        }
 
        /*
@@ -614,7 +620,7 @@ retry:
                        error = 0;
                        goto retry;
                }
-               return XFS_ERROR(error ? error : ENOSPC);
+               return error ? error : -ENOSPC;
        }
 
        if (!(imap[0].br_startblock || XFS_IS_REALTIME_INODE(ip)))
@@ -663,7 +669,7 @@ xfs_iomap_write_allocate(
         */
        error = xfs_qm_dqattach(ip, 0);
        if (error)
-               return XFS_ERROR(error);
+               return error;
 
        offset_fsb = XFS_B_TO_FSBT(mp, offset);
        count_fsb = imap->br_blockcount;
@@ -690,7 +696,7 @@ xfs_iomap_write_allocate(
                                                  nres, 0);
                        if (error) {
                                xfs_trans_cancel(tp, 0);
-                               return XFS_ERROR(error);
+                               return error;
                        }
                        xfs_ilock(ip, XFS_ILOCK_EXCL);
                        xfs_trans_ijoin(tp, ip, 0);
@@ -739,7 +745,7 @@ xfs_iomap_write_allocate(
                        if ((map_start_fsb + count_fsb) > last_block) {
                                count_fsb = last_block - map_start_fsb;
                                if (count_fsb == 0) {
-                                       error = EAGAIN;
+                                       error = -EAGAIN;
                                        goto trans_cancel;
                                }
                        }
@@ -793,7 +799,7 @@ trans_cancel:
        xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
 error0:
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
-       return XFS_ERROR(error);
+       return error;
 }
 
 int
@@ -853,7 +859,7 @@ xfs_iomap_write_unwritten(
                                          resblks, 0);
                if (error) {
                        xfs_trans_cancel(tp, 0);
-                       return XFS_ERROR(error);
+                       return error;
                }
 
                xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -892,7 +898,7 @@ xfs_iomap_write_unwritten(
                error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
                if (error)
-                       return XFS_ERROR(error);
+                       return error;
 
                if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip)))
                        return xfs_alert_fsblock_zero(ip, &imap);
@@ -915,5 +921,5 @@ error_on_bmapi_transaction:
        xfs_bmap_cancel(&free_list);
        xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT));
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
-       return XFS_ERROR(error);
+       return error;
 }