]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - libxfs/xfs_bmap.c
xfs: remove unneeded parameter from XFS_TEST_ERROR
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_bmap.c
index 61a9f72daf77fbb72325f5f571de6dd2b757d825..d44a4e9e720d95a2409f4c8e14e54e4cc3c8e5a3 100644 (file)
@@ -1222,7 +1222,6 @@ xfs_bmap_read_extents(
        xfs_fsblock_t           bno;    /* block # of "block" */
        xfs_buf_t               *bp;    /* buffer for "block" */
        int                     error;  /* error return value */
-       xfs_exntfmt_t           exntf;  /* XFS_EXTFMT_NOSTATE, if checking */
        xfs_extnum_t            i, j;   /* index into the extents list */
        xfs_ifork_t             *ifp;   /* fork structure */
        int                     level;  /* btree level, for checking */
@@ -1233,8 +1232,6 @@ xfs_bmap_read_extents(
 
        mp = ip->i_mount;
        ifp = XFS_IFORK_PTR(ip, whichfork);
-       exntf = (whichfork != XFS_DATA_FORK) ? XFS_EXTFMT_NOSTATE :
-                                       XFS_EXTFMT_INODE(ip);
        block = ifp->if_broot;
        /*
         * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out.
@@ -1274,7 +1271,6 @@ xfs_bmap_read_extents(
                xfs_bmbt_rec_t  *frp;
                xfs_fsblock_t   nextbno;
                xfs_extnum_t    num_recs;
-               xfs_extnum_t    start;
 
                num_recs = xfs_btree_get_numrecs(block);
                if (unlikely(i + num_recs > room)) {
@@ -1297,23 +1293,13 @@ xfs_bmap_read_extents(
                 * Copy records into the extent records.
                 */
                frp = XFS_BMBT_REC_ADDR(mp, block, 1);
-               start = i;
                for (j = 0; j < num_recs; j++, i++, frp++) {
                        xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i);
                        trp->l0 = be64_to_cpu(frp->l0);
                        trp->l1 = be64_to_cpu(frp->l1);
-               }
-               if (exntf == XFS_EXTFMT_NOSTATE) {
-                       /*
-                        * Check all attribute bmap btree records and
-                        * any "older" data bmap btree records for a
-                        * set bit in the "extent flag" position.
-                        */
-                       if (unlikely(xfs_check_nostate_extents(ifp,
-                                       start, num_recs))) {
+                       if (!xfs_bmbt_validate_extent(mp, whichfork, trp)) {
                                XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
-                                                XFS_ERRLEVEL_LOW,
-                                                ip->i_mount);
+                                                XFS_ERRLEVEL_LOW, mp);
                                goto error0;
                        }
                }
@@ -2068,8 +2054,10 @@ xfs_bmap_add_extent_delay_real(
                }
                temp = xfs_bmap_worst_indlen(bma->ip, temp);
                temp2 = xfs_bmap_worst_indlen(bma->ip, temp2);
-               diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) -
-                       (bma->cur ? bma->cur->bc_private.b.allocated : 0));
+               diff = (int)(temp + temp2 -
+                            (startblockval(PREV.br_startblock) -
+                             (bma->cur ?
+                              bma->cur->bc_private.b.allocated : 0)));
                if (diff > 0) {
                        error = xfs_mod_fdblocks(bma->ip->i_mount,
                                                 -((int64_t)diff), false);
@@ -2126,7 +2114,6 @@ xfs_bmap_add_extent_delay_real(
                temp = da_new;
                if (bma->cur)
                        temp += bma->cur->bc_private.b.allocated;
-               ASSERT(temp <= da_old);
                if (temp < da_old)
                        xfs_mod_fdblocks(bma->ip->i_mount,
                                        (int64_t)(da_old - temp), false);
@@ -3996,7 +3983,7 @@ xfs_bmapi_read(
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
             XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
-            mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
+            mp, XFS_ERRTAG_BMAPIFORMAT))) {
                XFS_ERROR_REPORT("xfs_bmapi_read", XFS_ERRLEVEL_LOW, mp);
                return -EFSCORRUPTED;
        }
@@ -4477,7 +4464,7 @@ xfs_bmapi_write(
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
             XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
-            mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
+            mp, XFS_ERRTAG_BMAPIFORMAT))) {
                XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp);
                return -EFSCORRUPTED;
        }
@@ -4698,7 +4685,7 @@ xfs_bmapi_remap(
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS &&
             XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_BTREE),
-            mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
+            mp, XFS_ERRTAG_BMAPIFORMAT))) {
                XFS_ERROR_REPORT("xfs_bmapi_remap", XFS_ERRLEVEL_LOW, mp);
                return -EFSCORRUPTED;
        }
@@ -4878,7 +4865,7 @@ xfs_bmap_del_extent_delay(
        ASSERT(got_endoff >= del_endoff);
 
        if (isrt) {
-               int64_t rtexts = XFS_FSB_TO_B(mp, del->br_blockcount);
+               uint64_t rtexts = XFS_FSB_TO_B(mp, del->br_blockcount);
 
                do_div(rtexts, mp->m_sb.sb_rextsize);
                xfs_mod_frextents(mp, rtexts);
@@ -5438,6 +5425,7 @@ __xfs_bunmapi(
        int                     whichfork;      /* data or attribute fork */
        xfs_fsblock_t           sum;
        xfs_filblks_t           len = *rlen;    /* length to unmap in file */
+       xfs_fileoff_t           max_len;
 
        trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_);
 
@@ -5459,6 +5447,16 @@ __xfs_bunmapi(
        ASSERT(len > 0);
        ASSERT(nexts >= 0);
 
+       /*
+        * Guesstimate how many blocks we can unmap without running the risk of
+        * blowing out the transaction with a mix of EFIs and reflink
+        * adjustments.
+        */
+       if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK)
+               max_len = min(len, xfs_refcount_max_unmap(tp->t_log_res));
+       else
+               max_len = len;
+
        if (!(ifp->if_flags & XFS_IFEXTENTS) &&
            (error = xfs_iread_extents(tp, ip, whichfork)))
                return error;
@@ -5503,7 +5501,7 @@ __xfs_bunmapi(
 
        extno = 0;
        while (bno != (xfs_fileoff_t)-1 && bno >= start && lastx >= 0 &&
-              (nexts == 0 || extno < nexts)) {
+              (nexts == 0 || extno < nexts) && max_len > 0) {
                /*
                 * Is the found extent after a hole in which bno lives?
                 * Just back up to the previous extent, if so.
@@ -5535,6 +5533,15 @@ __xfs_bunmapi(
                }
                if (del.br_startoff + del.br_blockcount > bno + 1)
                        del.br_blockcount = bno + 1 - del.br_startoff;
+
+               /* How much can we safely unmap? */
+               if (max_len < del.br_blockcount) {
+                       del.br_startoff += del.br_blockcount - max_len;
+                       if (!wasdel)
+                               del.br_startblock += del.br_blockcount - max_len;
+                       del.br_blockcount = max_len;
+               }
+
                sum = del.br_startblock + del.br_blockcount;
                if (isrt &&
                    (mod = do_mod(sum, mp->m_sb.sb_rextsize))) {
@@ -5711,6 +5718,7 @@ __xfs_bunmapi(
                if (!isrt && wasdel)
                        xfs_mod_fdblocks(mp, (int64_t)del.br_blockcount, false);
 
+               max_len -= del.br_blockcount;
                bno = del.br_startoff - 1;
 nodelete:
                /*
@@ -6081,7 +6089,7 @@ xfs_bmap_shift_extents(
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
             XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
-            mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
+            mp, XFS_ERRTAG_BMAPIFORMAT))) {
                XFS_ERROR_REPORT("xfs_bmap_shift_extents",
                                 XFS_ERRLEVEL_LOW, mp);
                return -EFSCORRUPTED;
@@ -6233,7 +6241,7 @@ xfs_bmap_split_extent_at(
        if (unlikely(XFS_TEST_ERROR(
            (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
             XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE),
-            mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
+            mp, XFS_ERRTAG_BMAPIFORMAT))) {
                XFS_ERROR_REPORT("xfs_bmap_split_extent_at",
                                 XFS_ERRLEVEL_LOW, mp);
                return -EFSCORRUPTED;
@@ -6476,33 +6484,33 @@ xfs_bmap_finish_one(
        int                             whichfork,
        xfs_fileoff_t                   startoff,
        xfs_fsblock_t                   startblock,
-       xfs_filblks_t                   blockcount,
+       xfs_filblks_t                   *blockcount,
        xfs_exntst_t                    state)
 {
-       int                             error = 0, done;
+       xfs_fsblock_t                   firstfsb;
+       int                             error = 0;
 
        trace_xfs_bmap_deferred(tp->t_mountp,
                        XFS_FSB_TO_AGNO(tp->t_mountp, startblock), type,
                        XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
-                       ip->i_ino, whichfork, startoff, blockcount, state);
+                       ip->i_ino, whichfork, startoff, *blockcount, state);
 
        if (WARN_ON_ONCE(whichfork != XFS_DATA_FORK))
                return -EFSCORRUPTED;
 
        if (XFS_TEST_ERROR(false, tp->t_mountp,
-                       XFS_ERRTAG_BMAP_FINISH_ONE,
-                       XFS_RANDOM_BMAP_FINISH_ONE))
+                       XFS_ERRTAG_BMAP_FINISH_ONE))
                return -EIO;
 
        switch (type) {
        case XFS_BMAP_MAP:
-               error = xfs_bmapi_remap(tp, ip, startoff, blockcount,
+               error = xfs_bmapi_remap(tp, ip, startoff, *blockcount,
                                startblock, dfops);
+               *blockcount = 0;
                break;
        case XFS_BMAP_UNMAP:
-               error = xfs_bunmapi(tp, ip, startoff, blockcount,
-                               XFS_BMAPI_REMAP, 1, &startblock, dfops, &done);
-               ASSERT(done);
+               error = __xfs_bunmapi(tp, ip, startoff, blockcount,
+                               XFS_BMAPI_REMAP, 1, &firstfsb, dfops);
                break;
        default:
                ASSERT(0);