Merge tag 'irq-core-2021-02-15' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / fs / xfs / xfs_bmap_util.c
index 7371a7f..e7d6831 100644 (file)
@@ -727,11 +727,9 @@ xfs_alloc_file_space(
        xfs_fileoff_t           startoffset_fsb;
        xfs_fileoff_t           endoffset_fsb;
        int                     nimaps;
-       int                     quota_flag;
        int                     rt;
        xfs_trans_t             *tp;
        xfs_bmbt_irec_t         imaps[1], *imapp;
-       uint                    qblocks, resblks, resrtextents;
        int                     error;
 
        trace_xfs_alloc_file_space(ip);
@@ -761,6 +759,7 @@ xfs_alloc_file_space(
         */
        while (allocatesize_fsb && !error) {
                xfs_fileoff_t   s, e;
+               unsigned int    dblocks, rblocks, resblks;
 
                /*
                 * Determine space reservations for data/realtime.
@@ -790,45 +789,31 @@ xfs_alloc_file_space(
                 */
                resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps));
                if (unlikely(rt)) {
-                       resrtextents = qblocks = resblks;
-                       resrtextents /= mp->m_sb.sb_rextsize;
-                       resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
-                       quota_flag = XFS_QMOPT_RES_RTBLKS;
+                       dblocks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
+                       rblocks = resblks;
                } else {
-                       resrtextents = 0;
-                       resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks);
-                       quota_flag = XFS_QMOPT_RES_REGBLKS;
+                       dblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks);
+                       rblocks = 0;
                }
 
                /*
                 * Allocate and setup the transaction.
                 */
-               error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks,
-                               resrtextents, 0, &tp);
-
-               /*
-                * Check for running out of space
-                */
-               if (error) {
-                       /*
-                        * Free the transaction structure.
-                        */
-                       ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
-                       break;
-               }
-               xfs_ilock(ip, XFS_ILOCK_EXCL);
-               error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks,
-                                                     0, quota_flag);
+               error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write,
+                               dblocks, rblocks, false, &tp);
                if (error)
-                       goto error1;
+                       break;
 
-               xfs_trans_ijoin(tp, ip, 0);
+               error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
+                               XFS_IEXT_ADD_NOSPLIT_CNT);
+               if (error)
+                       goto error;
 
                error = xfs_bmapi_write(tp, ip, startoffset_fsb,
                                        allocatesize_fsb, alloc_type, 0, imapp,
                                        &nimaps);
                if (error)
-                       goto error0;
+                       goto error;
 
                /*
                 * Complete the transaction
@@ -851,10 +836,7 @@ xfs_alloc_file_space(
 
        return error;
 
-error0:        /* unlock inode, unreserve quota blocks, cancel trans */
-       xfs_trans_unreserve_quota_nblks(tp, ip, (long)qblocks, 0, quota_flag);
-
-error1:        /* Just cancel transaction */
+error:
        xfs_trans_cancel(tp);
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
        return error;
@@ -872,20 +854,16 @@ xfs_unmap_extent(
        uint                    resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
        int                     error;
 
-       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
-       if (error) {
-               ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
+       error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write, resblks, 0,
+                       false, &tp);
+       if (error)
                return error;
-       }
 
-       xfs_ilock(ip, XFS_ILOCK_EXCL);
-       error = xfs_trans_reserve_quota(tp, mp, ip->i_udquot, ip->i_gdquot,
-                       ip->i_pdquot, resblks, 0, XFS_QMOPT_RES_REGBLKS);
+       error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
+                       XFS_IEXT_PUNCH_HOLE_CNT);
        if (error)
                goto out_trans_cancel;
 
-       xfs_trans_ijoin(tp, ip, 0);
-
        error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, done);
        if (error)
                goto out_trans_cancel;
@@ -1163,6 +1141,11 @@ xfs_insert_file_space(
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        xfs_trans_ijoin(tp, ip, 0);
 
+       error = xfs_iext_count_may_overflow(ip, XFS_DATA_FORK,
+                       XFS_IEXT_PUNCH_HOLE_CNT);
+       if (error)
+               goto out_trans_cancel;
+
        /*
         * The extent shifting code works on extent granularity. So, if stop_fsb
         * is not the starting block of extent, we need to split the extent at
@@ -1384,6 +1367,22 @@ xfs_swap_extent_rmap(
                                        irec.br_blockcount);
                        trace_xfs_swap_extent_rmap_remap_piece(tip, &uirec);
 
+                       if (xfs_bmap_is_real_extent(&uirec)) {
+                               error = xfs_iext_count_may_overflow(ip,
+                                               XFS_DATA_FORK,
+                                               XFS_IEXT_SWAP_RMAP_CNT);
+                               if (error)
+                                       goto out;
+                       }
+
+                       if (xfs_bmap_is_real_extent(&irec)) {
+                               error = xfs_iext_count_may_overflow(tip,
+                                               XFS_DATA_FORK,
+                                               XFS_IEXT_SWAP_RMAP_CNT);
+                               if (error)
+                                       goto out;
+                       }
+
                        /* Remove the mapping from the donor file. */
                        xfs_bmap_unmap_extent(tp, tip, &uirec);