]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - libxfs/xfs_bmap.c
xfs: don't rely on extent indices in xfs_bmap_collapse_extents
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_bmap.c
index a4985d39ecf422101d4cdf165c235a77d978a149..52bf4b4c30a5d522e8fb401692fcb93c41b5efae 100644 (file)
@@ -103,28 +103,21 @@ xfs_bmap_compute_maxlevels(
 STATIC int                             /* error */
 xfs_bmbt_lookup_eq(
        struct xfs_btree_cur    *cur,
-       xfs_fileoff_t           off,
-       xfs_fsblock_t           bno,
-       xfs_filblks_t           len,
+       struct xfs_bmbt_irec    *irec,
        int                     *stat)  /* success/failure */
 {
-       cur->bc_rec.b.br_startoff = off;
-       cur->bc_rec.b.br_startblock = bno;
-       cur->bc_rec.b.br_blockcount = len;
+       cur->bc_rec.b = *irec;
        return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
 }
 
 STATIC int                             /* error */
-xfs_bmbt_lookup_ge(
+xfs_bmbt_lookup_first(
        struct xfs_btree_cur    *cur,
-       xfs_fileoff_t           off,
-       xfs_fsblock_t           bno,
-       xfs_filblks_t           len,
        int                     *stat)  /* success/failure */
 {
-       cur->bc_rec.b.br_startoff = off;
-       cur->bc_rec.b.br_startblock = bno;
-       cur->bc_rec.b.br_blockcount = len;
+       cur->bc_rec.b.br_startoff = 0;
+       cur->bc_rec.b.br_startblock = 0;
+       cur->bc_rec.b.br_blockcount = 0;
        return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
 }
 
@@ -229,7 +222,6 @@ xfs_bmap_forkoff_reset(
 {
        if (whichfork == XFS_ATTR_FORK &&
            ip->i_d.di_format != XFS_DINODE_FMT_DEV &&
-           ip->i_d.di_format != XFS_DINODE_FMT_UUID &&
            ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
                uint    dfl_forkoff = xfs_default_attroffset(ip) >> 3;
 
@@ -485,31 +477,6 @@ error_norelse:
        return;
 }
 
-/*
- * Add bmap trace insert entries for all the contents of the extent records.
- */
-void
-xfs_bmap_trace_exlist(
-       xfs_inode_t     *ip,            /* incore inode pointer */
-       xfs_extnum_t    cnt,            /* count of entries in the list */
-       int             whichfork,      /* data or attr or cow fork */
-       unsigned long   caller_ip)
-{
-       xfs_extnum_t    idx;            /* extent record index */
-       xfs_ifork_t     *ifp;           /* inode fork pointer */
-       int             state = 0;
-
-       if (whichfork == XFS_ATTR_FORK)
-               state |= BMAP_ATTRFORK;
-       else if (whichfork == XFS_COW_FORK)
-               state |= BMAP_COWFORK;
-
-       ifp = XFS_IFORK_PTR(ip, whichfork);
-       ASSERT(cnt == xfs_iext_count(ifp));
-       for (idx = 0; idx < cnt; idx++)
-               trace_xfs_extlist(ip, idx, state, caller_ip);
-}
-
 /*
  * Validate that the bmbt_irecs being returned from bmapi are valid
  * given the caller's original parameters.  Specifically check the
@@ -644,8 +611,8 @@ xfs_bmap_btree_to_extents(
        cbno = be64_to_cpu(*pp);
        *logflagsp = 0;
 #ifdef DEBUG
-       if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
-               return error;
+       XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
+                       xfs_btree_check_lptr(cur, cbno, 1));
 #endif
        error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF,
                                &xfs_bmbt_buf_ops);
@@ -923,9 +890,6 @@ xfs_bmap_local_to_extents(
        rec.br_state = XFS_EXT_NORM;
        xfs_iext_insert(ip, 0, 1, &rec, 0);
 
-       trace_xfs_bmap_post_update(ip, 0,
-                       whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0,
-                       _THIS_IP_);
        XFS_IFORK_NEXT_SET(ip, whichfork, 1);
        ip->i_d.di_nblocks = 1;
        xfs_trans_mod_dquot_byino(tp, ip,
@@ -960,7 +924,8 @@ xfs_bmap_add_attrfork_btree(
                cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK);
                cur->bc_private.b.dfops = dfops;
                cur->bc_private.b.firstblock = *firstblock;
-               if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat)))
+               error = xfs_bmbt_lookup_first(cur, &stat);
+               if (error)
                        goto error0;
                /* must be at least one entry */
                XFS_WANT_CORRUPTED_GOTO(mp, stat == 1, error0);
@@ -1111,9 +1076,6 @@ xfs_bmap_add_attrfork(
        case XFS_DINODE_FMT_DEV:
                ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
                break;
-       case XFS_DINODE_FMT_UUID:
-               ip->i_d.di_forkoff = roundup(sizeof(uuid_t), 8) >> 3;
-               break;
        case XFS_DINODE_FMT_LOCAL:
        case XFS_DINODE_FMT_EXTENTS:
        case XFS_DINODE_FMT_BTREE:
@@ -1215,6 +1177,7 @@ xfs_bmap_read_extents(
        __be64                  *pp;    /* pointer to block address */
        /* REFERENCED */
        xfs_extnum_t            room;   /* number of entries there's room for */
+       int                     state = xfs_bmap_fork_to_state(whichfork);
 
        mp = ip->i_mount;
        ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -1288,6 +1251,7 @@ xfs_bmap_read_extents(
                                                 XFS_ERRLEVEL_LOW, mp);
                                goto error0;
                        }
+                       trace_xfs_read_extent(ip, i, state, _THIS_IP_);
                }
                xfs_trans_brelse(tp, bp);
                bno = nextbno;
@@ -1305,7 +1269,6 @@ xfs_bmap_read_extents(
        if (i != XFS_IFORK_NEXTENTS(ip, whichfork))
                return -EFSCORRUPTED;
        ASSERT(i == xfs_iext_count(ifp));
-       XFS_BMAP_TRACE_EXLIST(ip, i, whichfork);
        return 0;
 error0:
        xfs_trans_brelse(tp, bp);
@@ -1568,7 +1531,7 @@ xfs_bmap_add_extent_delay_real(
        xfs_bmbt_irec_t         r[3];   /* neighbor extent entries */
                                        /* left is 0, right is 1, prev is 2 */
        int                     rval=0; /* return value (logging flags) */
-       int                     state = 0;/* state bits, accessed thru macros */
+       int                     state = xfs_bmap_fork_to_state(whichfork);
        xfs_filblks_t           da_new; /* new count del alloc blocks used */
        xfs_filblks_t           da_old; /* old count del alloc blocks used */
        xfs_filblks_t           temp=0; /* value for da_new calculations */
@@ -1595,9 +1558,6 @@ xfs_bmap_add_extent_delay_real(
 #define        RIGHT           r[1]
 #define        PREV            r[2]
 
-       if (whichfork == XFS_COW_FORK)
-               state |= BMAP_COWFORK;
-
        /*
         * Set up a bunch of variables to make the tests simpler.
         */
@@ -1677,10 +1637,8 @@ xfs_bmap_add_extent_delay_real(
                 * The left and right neighbors are both contiguous with new.
                 */
                bma->idx--;
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
                LEFT.br_blockcount += PREV.br_blockcount + RIGHT.br_blockcount;
-               xfs_iext_update_extent(ifp, bma->idx, &LEFT);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx, &LEFT);
 
                xfs_iext_remove(bma->ip, bma->idx + 1, 2, state);
                (*nextents)--;
@@ -1688,9 +1646,7 @@ xfs_bmap_add_extent_delay_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff,
-                                       RIGHT.br_startblock,
-                                       RIGHT.br_blockcount, &i);
+                       error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -1716,19 +1672,15 @@ xfs_bmap_add_extent_delay_real(
                bma->idx--;
 
                old = LEFT;
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
                LEFT.br_blockcount += PREV.br_blockcount;
-               xfs_iext_update_extent(ifp, bma->idx, &LEFT);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx, &LEFT);
 
                xfs_iext_remove(bma->ip, bma->idx + 1, 1, state);
                if (bma->cur == NULL)
                        rval = XFS_ILOG_DEXT;
                else {
                        rval = 0;
-                       error = xfs_bmbt_lookup_eq(bma->cur, old.br_startoff,
-                                       old.br_startblock, old.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(bma->cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -1743,20 +1695,16 @@ xfs_bmap_add_extent_delay_real(
                 * Filling in all of a previously delayed allocation extent.
                 * The right neighbor is contiguous, the left is not.
                 */
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
                PREV.br_startblock = new->br_startblock;
                PREV.br_blockcount += RIGHT.br_blockcount;
-               xfs_iext_update_extent(ifp, bma->idx, &PREV);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV);
 
                xfs_iext_remove(bma->ip, bma->idx + 1, 1, state);
                if (bma->cur == NULL)
                        rval = XFS_ILOG_DEXT;
                else {
                        rval = 0;
-                       error = xfs_bmbt_lookup_eq(bma->cur, RIGHT.br_startoff,
-                                       RIGHT.br_startblock,
-                                       RIGHT.br_blockcount, &i);
+                       error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -1772,24 +1720,19 @@ xfs_bmap_add_extent_delay_real(
                 * Neither the left nor right neighbors are contiguous with
                 * the new one.
                 */
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
                PREV.br_startblock = new->br_startblock;
                PREV.br_state = new->br_state;
-               xfs_iext_update_extent(ifp, bma->idx, &PREV);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV);
 
                (*nextents)++;
                if (bma->cur == NULL)
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
-                                       new->br_startblock, new->br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
-                       bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
                        error = xfs_btree_insert(bma->cur, &i);
                        if (error)
                                goto done;
@@ -1807,25 +1750,19 @@ xfs_bmap_add_extent_delay_real(
                da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
                                startblockval(PREV.br_startblock));
 
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx - 1, state, _THIS_IP_);
                LEFT.br_blockcount += new->br_blockcount;
-               xfs_iext_update_extent(ifp, bma->idx - 1, &LEFT);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx - 1, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx - 1, &LEFT);
 
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
                PREV.br_blockcount = temp = PREV.br_blockcount - new->br_blockcount;
                PREV.br_startoff += new->br_blockcount;
                PREV.br_startblock = nullstartblock(da_new);
-               xfs_iext_update_extent(ifp, bma->idx, &PREV);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV);
 
                if (bma->cur == NULL)
                        rval = XFS_ILOG_DEXT;
                else {
                        rval = 0;
-                       error = xfs_bmbt_lookup_eq(bma->cur, old.br_startoff,
-                                       old.br_startblock, old.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(bma->cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -1848,13 +1785,10 @@ xfs_bmap_add_extent_delay_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
-                                       new->br_startblock, new->br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
-                       bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
                        error = xfs_btree_insert(bma->cur, &i);
                        if (error)
                                goto done;
@@ -1875,13 +1809,10 @@ xfs_bmap_add_extent_delay_real(
                        startblockval(PREV.br_startblock) -
                        (bma->cur ? bma->cur->bc_private.b.allocated : 0));
 
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
                PREV.br_startoff = new_endoff;
                PREV.br_blockcount = temp;
                PREV.br_startblock = nullstartblock(da_new);
-               xfs_iext_update_extent(ifp, bma->idx + 1, &PREV);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
-
+               xfs_iext_update_extent(bma->ip, state, bma->idx + 1, &PREV);
                break;
 
        case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
@@ -1890,20 +1821,16 @@ xfs_bmap_add_extent_delay_real(
                 * The right neighbor is contiguous with the new allocation.
                 */
                old = RIGHT;
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
                RIGHT.br_startoff = new->br_startoff;
                RIGHT.br_startblock = new->br_startblock;
                RIGHT.br_blockcount += new->br_blockcount;
-               xfs_iext_update_extent(ifp, bma->idx + 1, &RIGHT);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx + 1, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx + 1, &RIGHT);
 
                if (bma->cur == NULL)
                        rval = XFS_ILOG_DEXT;
                else {
                        rval = 0;
-                       error = xfs_bmbt_lookup_eq(bma->cur, old.br_startoff,
-                                       old.br_startblock,
-                                       old.br_blockcount, &i);
+                       error = xfs_bmbt_lookup_eq(bma->cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -1916,11 +1843,9 @@ xfs_bmap_add_extent_delay_real(
                da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp),
                        startblockval(PREV.br_startblock));
 
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
                PREV.br_blockcount = temp;
                PREV.br_startblock = nullstartblock(da_new);
-               xfs_iext_update_extent(ifp, bma->idx, &PREV);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV);
 
                bma->idx++;
                break;
@@ -1936,13 +1861,10 @@ xfs_bmap_add_extent_delay_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
-                                       new->br_startblock, new->br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
-                       bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
                        error = xfs_btree_insert(bma->cur, &i);
                        if (error)
                                goto done;
@@ -1963,11 +1885,9 @@ xfs_bmap_add_extent_delay_real(
                        startblockval(PREV.br_startblock) -
                        (bma->cur ? bma->cur->bc_private.b.allocated : 0));
 
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx, state, _THIS_IP_);
                PREV.br_startblock = nullstartblock(da_new);
                PREV.br_blockcount = temp;
-               xfs_iext_update_extent(ifp, bma->idx, &PREV);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV);
 
                bma->idx++;
                break;
@@ -2008,13 +1928,11 @@ xfs_bmap_add_extent_delay_real(
                                        RIGHT.br_blockcount));
 
                /* truncate PREV */
-               trace_xfs_bmap_pre_update(bma->ip, bma->idx, 0, _THIS_IP_);
                PREV.br_blockcount = new->br_startoff - PREV.br_startoff;
                PREV.br_startblock =
                        nullstartblock(xfs_bmap_worst_indlen(bma->ip,
                                        PREV.br_blockcount));
-               xfs_iext_update_extent(ifp, bma->idx, &PREV);
-               trace_xfs_bmap_post_update(bma->ip, bma->idx, state, _THIS_IP_);
+               xfs_iext_update_extent(bma->ip, state, bma->idx, &PREV);
 
                /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */
                xfs_iext_insert(bma->ip, bma->idx + 1, 2, &LEFT, state);
@@ -2024,13 +1942,10 @@ xfs_bmap_add_extent_delay_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(bma->cur, new->br_startoff,
-                                       new->br_startblock, new->br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(bma->cur, new, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
-                       bma->cur->bc_rec.b.br_state = XFS_EXT_NORM;
                        error = xfs_btree_insert(bma->cur, &i);
                        if (error)
                                goto done;
@@ -2127,7 +2042,7 @@ xfs_bmap_add_extent_unwritten_real(
        xfs_bmbt_irec_t         r[3];   /* neighbor extent entries */
                                        /* left is 0, right is 1, prev is 2 */
        int                     rval=0; /* return value (logging flags) */
-       int                     state = 0;/* state bits, accessed thru macros */
+       int                     state = xfs_bmap_fork_to_state(whichfork);
        struct xfs_mount        *mp = ip->i_mount;
        struct xfs_bmbt_irec    old;
 
@@ -2135,8 +2050,6 @@ xfs_bmap_add_extent_unwritten_real(
 
        cur = *curp;
        ifp = XFS_IFORK_PTR(ip, whichfork);
-       if (whichfork == XFS_COW_FORK)
-               state |= BMAP_COWFORK;
 
        ASSERT(*idx >= 0);
        ASSERT(*idx <= xfs_iext_count(ifp));
@@ -2224,10 +2137,8 @@ xfs_bmap_add_extent_unwritten_real(
                 */
                --*idx;
 
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                LEFT.br_blockcount += PREV.br_blockcount + RIGHT.br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &LEFT);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &LEFT);
 
                xfs_iext_remove(ip, *idx + 1, 2, state);
                XFS_IFORK_NEXT_SET(ip, whichfork,
@@ -2236,9 +2147,8 @@ xfs_bmap_add_extent_unwritten_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff,
-                                       RIGHT.br_startblock,
-                                       RIGHT.br_blockcount, &i)))
+                       error = xfs_bmbt_lookup_eq(cur, &RIGHT, &i);
+                       if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
                        if ((error = xfs_btree_delete(cur, &i)))
@@ -2266,10 +2176,8 @@ xfs_bmap_add_extent_unwritten_real(
                 */
                --*idx;
 
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                LEFT.br_blockcount += PREV.br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &LEFT);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &LEFT);
 
                xfs_iext_remove(ip, *idx + 1, 1, state);
                XFS_IFORK_NEXT_SET(ip, whichfork,
@@ -2278,9 +2186,8 @@ xfs_bmap_add_extent_unwritten_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       if ((error = xfs_bmbt_lookup_eq(cur, PREV.br_startoff,
-                                       PREV.br_startblock, PREV.br_blockcount,
-                                       &i)))
+                       error = xfs_bmbt_lookup_eq(cur, &PREV, &i);
+                       if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
                        if ((error = xfs_btree_delete(cur, &i)))
@@ -2300,11 +2207,9 @@ xfs_bmap_add_extent_unwritten_real(
                 * Setting all of a previous oldext extent to newext.
                 * The right neighbor is contiguous, the left is not.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                PREV.br_blockcount += RIGHT.br_blockcount;
                PREV.br_state = new->br_state;
-               xfs_iext_update_extent(ifp, *idx, &PREV);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &PREV);
 
                xfs_iext_remove(ip, *idx + 1, 1, state);
                XFS_IFORK_NEXT_SET(ip, whichfork,
@@ -2313,9 +2218,8 @@ xfs_bmap_add_extent_unwritten_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       if ((error = xfs_bmbt_lookup_eq(cur, RIGHT.br_startoff,
-                                       RIGHT.br_startblock,
-                                       RIGHT.br_blockcount, &i)))
+                       error = xfs_bmbt_lookup_eq(cur, &RIGHT, &i);
+                       if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
                        if ((error = xfs_btree_delete(cur, &i)))
@@ -2336,18 +2240,15 @@ xfs_bmap_add_extent_unwritten_real(
                 * Neither the left nor right neighbors are contiguous with
                 * the new one.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                PREV.br_state = new->br_state;
-               xfs_iext_update_extent(ifp, *idx, &PREV);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &PREV);
 
                if (cur == NULL)
                        rval = XFS_ILOG_DEXT;
                else {
                        rval = 0;
-                       if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
-                                       new->br_startblock, new->br_blockcount,
-                                       &i)))
+                       error = xfs_bmbt_lookup_eq(cur, new, &i);
+                       if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
                        error = xfs_bmbt_update(cur, &PREV);
@@ -2361,18 +2262,14 @@ xfs_bmap_add_extent_unwritten_real(
                 * Setting the first part of a previous oldext extent to newext.
                 * The left neighbor is contiguous.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx - 1, state, _THIS_IP_);
                LEFT.br_blockcount += new->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx - 1, &LEFT);
-               trace_xfs_bmap_post_update(ip, *idx - 1, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx - 1, &LEFT);
 
                old = PREV;
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                PREV.br_startoff += new->br_blockcount;
                PREV.br_startblock += new->br_blockcount;
                PREV.br_blockcount -= new->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &PREV);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &PREV);
 
                --*idx;
 
@@ -2380,9 +2277,7 @@ xfs_bmap_add_extent_unwritten_real(
                        rval = XFS_ILOG_DEXT;
                else {
                        rval = 0;
-                       error = xfs_bmbt_lookup_eq(cur, old.br_startoff,
-                                       old.br_startblock, old.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -2404,12 +2299,10 @@ xfs_bmap_add_extent_unwritten_real(
                 * The left neighbor is not contiguous.
                 */
                old = PREV;
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                PREV.br_startoff += new->br_blockcount;
                PREV.br_startblock += new->br_blockcount;
                PREV.br_blockcount -= new->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &PREV);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &PREV);
 
                xfs_iext_insert(ip, *idx, 1, new, state);
                XFS_IFORK_NEXT_SET(ip, whichfork,
@@ -2418,9 +2311,7 @@ xfs_bmap_add_extent_unwritten_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(cur, old.br_startoff,
-                                       old.br_startblock, old.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -2440,27 +2331,21 @@ xfs_bmap_add_extent_unwritten_real(
                 * The right neighbor is contiguous with the new allocation.
                 */
                old = PREV;
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                PREV.br_blockcount -= new->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &PREV);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &PREV);
 
                ++*idx;
 
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                RIGHT.br_startoff = new->br_startoff;
                RIGHT.br_startblock = new->br_startblock;
                RIGHT.br_blockcount += new->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &RIGHT);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &RIGHT);
 
                if (cur == NULL)
                        rval = XFS_ILOG_DEXT;
                else {
                        rval = 0;
-                       error = xfs_bmbt_lookup_eq(cur, old.br_startoff,
-                                       old.br_startblock, old.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -2482,10 +2367,8 @@ xfs_bmap_add_extent_unwritten_real(
                 * The right neighbor is not contiguous.
                 */
                old = PREV;
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                PREV.br_blockcount -= new->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &PREV);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &PREV);
 
                ++*idx;
                xfs_iext_insert(ip, *idx, 1, new, state);
@@ -2496,21 +2379,17 @@ xfs_bmap_add_extent_unwritten_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(cur, old.br_startoff,
-                                       old.br_startblock, old.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
                        error = xfs_bmbt_update(cur, &PREV);
                        if (error)
                                goto done;
-                       if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
-                                       new->br_startblock, new->br_blockcount,
-                                       &i)))
+                       error = xfs_bmbt_lookup_eq(cur, new, &i);
+                       if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
-                       cur->bc_rec.b.br_state = new->br_state;
                        if ((error = xfs_btree_insert(cur, &i)))
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -2524,10 +2403,8 @@ xfs_bmap_add_extent_unwritten_real(
                 * One extent becomes three extents.
                 */
                old = PREV;
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                PREV.br_blockcount = new->br_startoff - PREV.br_startoff;
-               xfs_iext_update_extent(ifp, *idx, &PREV);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &PREV);
 
                r[0] = *new;
                r[1].br_startoff = new_endoff;
@@ -2545,9 +2422,7 @@ xfs_bmap_add_extent_unwritten_real(
                        rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
                else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(cur, old.br_startoff,
-                                       old.br_startblock, old.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -2565,13 +2440,11 @@ xfs_bmap_add_extent_unwritten_real(
                         * we are about to insert as we can't trust it after
                         * the previous insert.
                         */
-                       if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
-                                       new->br_startblock, new->br_blockcount,
-                                       &i)))
+                       error = xfs_bmbt_lookup_eq(cur, new, &i);
+                       if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
                        /* new middle extent - newext */
-                       cur->bc_rec.b.br_state = new->br_state;
                        if ((error = xfs_btree_insert(cur, &i)))
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -2638,13 +2511,10 @@ xfs_bmap_add_extent_hole_delay(
        xfs_filblks_t           newlen=0;       /* new indirect size */
        xfs_filblks_t           oldlen=0;       /* old indirect size */
        xfs_bmbt_irec_t         right;  /* right neighbor extent entry */
-       int                     state;  /* state bits, accessed thru macros */
+       int                     state = xfs_bmap_fork_to_state(whichfork);
        xfs_filblks_t           temp;    /* temp for indirect calculations */
 
        ifp = XFS_IFORK_PTR(ip, whichfork);
-       state = 0;
-       if (whichfork == XFS_COW_FORK)
-               state |= BMAP_COWFORK;
        ASSERT(isnullstartblock(new->br_startblock));
 
        /*
@@ -2701,7 +2571,6 @@ xfs_bmap_add_extent_hole_delay(
                temp = left.br_blockcount + new->br_blockcount +
                        right.br_blockcount;
 
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                oldlen = startblockval(left.br_startblock) +
                        startblockval(new->br_startblock) +
                        startblockval(right.br_startblock);
@@ -2709,8 +2578,7 @@ xfs_bmap_add_extent_hole_delay(
                                         oldlen);
                left.br_startblock = nullstartblock(newlen);
                left.br_blockcount = temp;
-               xfs_iext_update_extent(ifp, *idx, &left);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &left);
 
                xfs_iext_remove(ip, *idx + 1, 1, state);
                break;
@@ -2724,15 +2592,13 @@ xfs_bmap_add_extent_hole_delay(
                --*idx;
                temp = left.br_blockcount + new->br_blockcount;
 
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                oldlen = startblockval(left.br_startblock) +
                        startblockval(new->br_startblock);
                newlen = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
                                         oldlen);
                left.br_blockcount = temp;
                left.br_startblock = nullstartblock(newlen);
-               xfs_iext_update_extent(ifp, *idx, &left);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &left);
                break;
 
        case BMAP_RIGHT_CONTIG:
@@ -2741,7 +2607,6 @@ xfs_bmap_add_extent_hole_delay(
                 * on the right.
                 * Merge the new allocation with the right neighbor.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                temp = new->br_blockcount + right.br_blockcount;
                oldlen = startblockval(new->br_startblock) +
                        startblockval(right.br_startblock);
@@ -2750,8 +2615,7 @@ xfs_bmap_add_extent_hole_delay(
                right.br_startoff = new->br_startoff;
                right.br_startblock = nullstartblock(newlen);
                right.br_blockcount = temp;
-               xfs_iext_update_extent(ifp, *idx, &right);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &right);
                break;
 
        case 0:
@@ -2797,7 +2661,7 @@ xfs_bmap_add_extent_hole_real(
        xfs_bmbt_irec_t         left;   /* left neighbor extent entry */
        xfs_bmbt_irec_t         right;  /* right neighbor extent entry */
        int                     rval=0; /* return value (logging flags) */
-       int                     state;  /* state bits, accessed thru macros */
+       int                     state = xfs_bmap_fork_to_state(whichfork);
        struct xfs_bmbt_irec    old;
 
        ASSERT(*idx >= 0);
@@ -2807,12 +2671,6 @@ xfs_bmap_add_extent_hole_real(
 
        XFS_STATS_INC(mp, xs_add_exlist);
 
-       state = 0;
-       if (whichfork == XFS_ATTR_FORK)
-               state |= BMAP_ATTRFORK;
-       if (whichfork == XFS_COW_FORK)
-               state |= BMAP_COWFORK;
-
        /*
         * Check and set flags if this segment has a left neighbor.
         */
@@ -2867,10 +2725,8 @@ xfs_bmap_add_extent_hole_real(
                 * Merge all three into a single extent record.
                 */
                --*idx;
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                left.br_blockcount += new->br_blockcount + right.br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &left);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &left);
 
                xfs_iext_remove(ip, *idx + 1, 1, state);
 
@@ -2880,9 +2736,7 @@ xfs_bmap_add_extent_hole_real(
                        rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
                } else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(cur, right.br_startoff,
-                                       right.br_startblock, right.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(cur, &right, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -2908,18 +2762,15 @@ xfs_bmap_add_extent_hole_real(
                 */
                --*idx;
                old = left;
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
+
                left.br_blockcount += new->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &left);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &left);
 
                if (cur == NULL) {
                        rval = xfs_ilog_fext(whichfork);
                } else {
                        rval = 0;
-                       error = xfs_bmbt_lookup_eq(cur, old.br_startoff,
-                                       old.br_startblock, old.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -2936,20 +2787,17 @@ xfs_bmap_add_extent_hole_real(
                 * Merge the new allocation with the right neighbor.
                 */
                old = right;
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
+
                right.br_startoff = new->br_startoff;
                right.br_startblock = new->br_startblock;
                right.br_blockcount += new->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &right);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &right);
 
                if (cur == NULL) {
                        rval = xfs_ilog_fext(whichfork);
                } else {
                        rval = 0;
-                       error = xfs_bmbt_lookup_eq(cur, old.br_startoff,
-                                       old.br_startblock, old.br_blockcount,
-                                       &i);
+                       error = xfs_bmbt_lookup_eq(cur, &old, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -2972,14 +2820,10 @@ xfs_bmap_add_extent_hole_real(
                        rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
                } else {
                        rval = XFS_ILOG_CORE;
-                       error = xfs_bmbt_lookup_eq(cur,
-                                       new->br_startoff,
-                                       new->br_startblock,
-                                       new->br_blockcount, &i);
+                       error = xfs_bmbt_lookup_eq(cur, new, &i);
                        if (error)
                                goto done;
                        XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
-                       cur->bc_rec.b.br_state = new->br_state;
                        error = xfs_btree_insert(cur, &i);
                        if (error)
                                goto done;
@@ -4795,7 +4639,8 @@ xfs_bmap_del_extent_delay(
        int64_t                 da_old, da_new, da_diff = 0;
        xfs_fileoff_t           del_endoff, got_endoff;
        xfs_filblks_t           got_indlen, new_indlen, stolen;
-       int                     error = 0, state = 0;
+       int                     state = xfs_bmap_fork_to_state(whichfork);
+       int                     error = 0;
        bool                    isrt;
 
        XFS_STATS_INC(mp, xs_del_exlist);
@@ -4831,9 +4676,6 @@ xfs_bmap_del_extent_delay(
                return error;
        ip->i_delayed_blks -= del->br_blockcount;
 
-       if (whichfork == XFS_COW_FORK)
-               state |= BMAP_COWFORK;
-
        if (got->br_startoff == del->br_startoff)
                state |= BMAP_LEFT_FILLING;
        if (got_endoff == del_endoff)
@@ -4851,26 +4693,22 @@ xfs_bmap_del_extent_delay(
                /*
                 * Deleting the first part of the extent.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                got->br_startoff = del_endoff;
                got->br_blockcount -= del->br_blockcount;
                da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip,
                                got->br_blockcount), da_old);
                got->br_startblock = nullstartblock((int)da_new);
-               xfs_iext_update_extent(ifp, *idx, got);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, got);
                break;
        case BMAP_RIGHT_FILLING:
                /*
                 * Deleting the last part of the extent.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                got->br_blockcount = got->br_blockcount - del->br_blockcount;
                da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip,
                                got->br_blockcount), da_old);
                got->br_startblock = nullstartblock((int)da_new);
-               xfs_iext_update_extent(ifp, *idx, got);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, got);
                break;
        case 0:
                /*
@@ -4882,8 +4720,6 @@ xfs_bmap_del_extent_delay(
                 * Warn if either of the new indlen reservations is zero as this
                 * can lead to delalloc problems.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
-
                got->br_blockcount = del->br_startoff - got->br_startoff;
                got_indlen = xfs_bmap_worst_indlen(ip, got->br_blockcount);
 
@@ -4895,8 +4731,7 @@ xfs_bmap_del_extent_delay(
                                                       del->br_blockcount);
 
                got->br_startblock = nullstartblock((int)got_indlen);
-               xfs_iext_update_extent(ifp, *idx, got);
-               trace_xfs_bmap_post_update(ip, *idx, 0, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, got);
 
                new.br_startoff = del_endoff;
                new.br_state = got->br_state;
@@ -4961,30 +4796,24 @@ xfs_bmap_del_extent_cow(
                /*
                 * Deleting the first part of the extent.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                got->br_startoff = del_endoff;
                got->br_blockcount -= del->br_blockcount;
                got->br_startblock = del->br_startblock + del->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, got);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, got);
                break;
        case BMAP_RIGHT_FILLING:
                /*
                 * Deleting the last part of the extent.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                got->br_blockcount -= del->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, got);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, got);
                break;
        case 0:
                /*
                 * Deleting the middle of the extent.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                got->br_blockcount = del->br_startoff - got->br_startoff;
-               xfs_iext_update_extent(ifp, *idx, got);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, got);
 
                new.br_startoff = del_endoff;
                new.br_blockcount = got_endoff - del_endoff;
@@ -5027,17 +4856,12 @@ xfs_bmap_del_extent_real(
        xfs_bmbt_irec_t         new;    /* new record to be inserted */
        /* REFERENCED */
        uint                    qfield; /* quota field to update */
-       int                     state = 0;
+       int                     state = xfs_bmap_fork_to_state(whichfork);
        struct xfs_bmbt_irec    old;
 
        mp = ip->i_mount;
        XFS_STATS_INC(mp, xs_del_exlist);
 
-       if (whichfork == XFS_ATTR_FORK)
-               state |= BMAP_ATTRFORK;
-       else if (whichfork == XFS_COW_FORK)
-               state |= BMAP_COWFORK;
-
        ifp = XFS_IFORK_PTR(ip, whichfork);
        ASSERT((*idx >= 0) && (*idx < xfs_iext_count(ifp)));
        ASSERT(del->br_blockcount > 0);
@@ -5090,8 +4914,7 @@ xfs_bmap_del_extent_real(
 
        del_endblock = del->br_startblock + del->br_blockcount;
        if (cur) {
-               error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
-                               got.br_startblock, got.br_blockcount, &i);
+               error = xfs_bmbt_lookup_eq(cur, &got, &i);
                if (error)
                        goto done;
                XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -5107,9 +4930,7 @@ xfs_bmap_del_extent_real(
                /*
                 * Matches the whole extent.  Delete the entry.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
-               xfs_iext_remove(ip, *idx, 1,
-                               whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0);
+               xfs_iext_remove(ip, *idx, 1, state);
                --*idx;
 
                XFS_IFORK_NEXT_SET(ip, whichfork,
@@ -5127,12 +4948,10 @@ xfs_bmap_del_extent_real(
                /*
                 * Deleting the first part of the extent.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                got.br_startoff = del_endoff;
                got.br_startblock = del_endblock;
                got.br_blockcount -= del->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &got);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &got);
                if (!cur) {
                        flags |= xfs_ilog_fext(whichfork);
                        break;
@@ -5145,10 +4964,8 @@ xfs_bmap_del_extent_real(
                /*
                 * Deleting the last part of the extent.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
                got.br_blockcount -= del->br_blockcount;
-               xfs_iext_update_extent(ifp, *idx, &got);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
+               xfs_iext_update_extent(ip, state, *idx, &got);
                if (!cur) {
                        flags |= xfs_ilog_fext(whichfork);
                        break;
@@ -5161,11 +4978,10 @@ xfs_bmap_del_extent_real(
                /*
                 * Deleting the middle of the extent.
                 */
-               trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
-
                old = got;
+
                got.br_blockcount = del->br_startoff - got.br_startoff;
-               xfs_iext_update_extent(ifp, *idx, &got);
+               xfs_iext_update_extent(ip, state, *idx, &got);
 
                new.br_startoff = del_endoff;
                new.br_blockcount = got_endoff - del_endoff;
@@ -5194,9 +5010,7 @@ xfs_bmap_del_extent_real(
                                 * Reset the cursor, don't trust it after any
                                 * insert operation.
                                 */
-                               error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
-                                               got.br_startblock,
-                                               got.br_blockcount, &i);
+                               error = xfs_bmbt_lookup_eq(cur, &got, &i);
                                if (error)
                                        goto done;
                                XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
@@ -5211,7 +5025,7 @@ xfs_bmap_del_extent_real(
                                 * Reset the extent record back
                                 * to the original value.
                                 */
-                               xfs_iext_update_extent(ifp, *idx, &old);
+                               xfs_iext_update_extent(ip, state, *idx, &old);
                                flags = 0;
                                error = -ENOSPC;
                                goto done;
@@ -5221,7 +5035,6 @@ xfs_bmap_del_extent_real(
                        flags |= xfs_ilog_fext(whichfork);
                XFS_IFORK_NEXT_SET(ip, whichfork,
                        XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
-               trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
                xfs_iext_insert(ip, *idx + 1, 1, &new, state);
                ++*idx;
                break;
@@ -5696,7 +5509,6 @@ xfs_bmse_merge(
        int                             *logflags,      /* output */
        struct xfs_defer_ops            *dfops)
 {
-       struct xfs_ifork                *ifp = XFS_IFORK_PTR(ip, whichfork);
        struct xfs_bmbt_irec            new;
        xfs_filblks_t                   blockcount;
        int                             error, i;
@@ -5724,8 +5536,7 @@ xfs_bmse_merge(
        }
 
        /* lookup and remove the extent to merge */
-       error = xfs_bmbt_lookup_eq(cur, got->br_startoff, got->br_startblock,
-                                  got->br_blockcount, &i);
+       error = xfs_bmbt_lookup_eq(cur, got, &i);
        if (error)
                return error;
        XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
@@ -5736,8 +5547,7 @@ xfs_bmse_merge(
        XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
 
        /* lookup and update size of the previous extent */
-       error = xfs_bmbt_lookup_eq(cur, left->br_startoff, left->br_startblock,
-                                  left->br_blockcount, &i);
+       error = xfs_bmbt_lookup_eq(cur, left, &i);
        if (error)
                return error;
        XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
@@ -5747,7 +5557,8 @@ xfs_bmse_merge(
                return error;
 
 done:
-       xfs_iext_update_extent(ifp, current_ext - 1, &new);
+       xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork),
+                       current_ext - 1, &new);
        xfs_iext_remove(ip, current_ext, 1, 0);
 
        /* update reverse mapping. rmap functions merge the rmaps for us */
@@ -5759,181 +5570,186 @@ done:
        return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &new);
 }
 
-/*
- * Shift a single extent.
- */
-STATIC int
-xfs_bmse_shift_one(
-       struct xfs_inode                *ip,
-       int                             whichfork,
-       xfs_fileoff_t                   offset_shift_fsb,
-       int                             *current_ext,
-       struct xfs_bmbt_irec            *got,
-       struct xfs_btree_cur            *cur,
-       int                             *logflags,
-       enum shift_direction            direction,
-       struct xfs_defer_ops            *dfops)
+static int
+xfs_bmap_shift_update_extent(
+       struct xfs_inode        *ip,
+       int                     whichfork,
+       xfs_extnum_t            idx,
+       struct xfs_bmbt_irec    *got,
+       struct xfs_btree_cur    *cur,
+       int                     *logflags,
+       struct xfs_defer_ops    *dfops,
+       xfs_fileoff_t           startoff)
 {
-       struct xfs_ifork                *ifp;
-       struct xfs_mount                *mp;
-       xfs_fileoff_t                   startoff;
-       struct xfs_bmbt_irec            adj_irec, new;
-       int                             error;
-       int                             i;
-       int                             total_extents;
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_bmbt_irec    prev = *got;
+       int                     error, i;
 
-       mp = ip->i_mount;
-       ifp = XFS_IFORK_PTR(ip, whichfork);
-       total_extents = xfs_iext_count(ifp);
+       *logflags |= XFS_ILOG_CORE;
 
-       /* delalloc extents should be prevented by caller */
-       XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got->br_startblock));
+       got->br_startoff = startoff;
 
-       if (direction == SHIFT_LEFT) {
-               startoff = got->br_startoff - offset_shift_fsb;
+       if (cur) {
+               error = xfs_bmbt_lookup_eq(cur, &prev, &i);
+               if (error)
+                       return error;
+               XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
 
-               /*
-                * Check for merge if we've got an extent to the left,
-                * otherwise make sure there's enough room at the start
-                * of the file for the shift.
-                */
-               if (!*current_ext) {
-                       if (got->br_startoff < offset_shift_fsb)
-                               return -EINVAL;
-                       goto update_current_ext;
-               }
+               error = xfs_bmbt_update(cur, got);
+               if (error)
+                       return error;
+       } else {
+               *logflags |= XFS_ILOG_DEXT;
+       }
 
-               /*
-                * grab the left extent and check for a large enough hole.
-                */
-               xfs_iext_get_extent(ifp, *current_ext - 1, &adj_irec);
-               if (startoff < adj_irec.br_startoff + adj_irec.br_blockcount)
-                       return -EINVAL;
+       xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), idx, got);
 
-               /* check whether to merge the extent or shift it down */
-               if (xfs_bmse_can_merge(&adj_irec, got, offset_shift_fsb)) {
-                       return xfs_bmse_merge(ip, whichfork, offset_shift_fsb,
-                                             *current_ext, got, &adj_irec,
-                                             cur, logflags, dfops);
-               }
-       } else {
-               startoff = got->br_startoff + offset_shift_fsb;
-               /* nothing to move if this is the last extent */
-               if (*current_ext >= (total_extents - 1))
-                       goto update_current_ext;
+       /* update reverse mapping */
+       error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, &prev);
+       if (error)
+               return error;
+       return xfs_rmap_map_extent(mp, dfops, ip, whichfork, got);
+}
 
-               /*
-                * If this is not the last extent in the file, make sure there
-                * is enough room between current extent and next extent for
-                * accommodating the shift.
-                */
-               xfs_iext_get_extent(ifp, *current_ext + 1, &adj_irec);
-               if (startoff + got->br_blockcount > adj_irec.br_startoff)
-                       return -EINVAL;
+int
+xfs_bmap_collapse_extents(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip,
+       xfs_fileoff_t           *next_fsb,
+       xfs_fileoff_t           offset_shift_fsb,
+       bool                    *done,
+       xfs_fileoff_t           stop_fsb,
+       xfs_fsblock_t           *firstblock,
+       struct xfs_defer_ops    *dfops)
+{
+       int                     whichfork = XFS_DATA_FORK;
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_ifork        *ifp = XFS_IFORK_PTR(ip, whichfork);
+       struct xfs_btree_cur    *cur = NULL;
+       struct xfs_bmbt_irec    got, prev;
+       xfs_extnum_t            current_ext;
+       xfs_fileoff_t           new_startoff;
+       int                     error = 0;
+       int                     logflags = 0;
 
-               /*
-                * Unlike a left shift (which involves a hole punch),
-                * a right shift does not modify extent neighbors
-                * in any way. We should never find mergeable extents
-                * in this scenario. Check anyways and warn if we
-                * encounter two extents that could be one.
-                */
-               if (xfs_bmse_can_merge(got, &adj_irec, offset_shift_fsb))
-                       WARN_ON_ONCE(1);
+       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_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
+               return -EFSCORRUPTED;
        }
 
-       /*
-        * Increment the extent index for the next iteration, update the start
-        * offset of the in-core extent and update the btree if applicable.
-        */
-update_current_ext:
-       *logflags |= XFS_ILOG_CORE;
+       if (XFS_FORCED_SHUTDOWN(mp))
+               return -EIO;
 
-       new = *got;
-       new.br_startoff = startoff;
+       ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL));
 
-       if (cur) {
-               error = xfs_bmbt_lookup_eq(cur, got->br_startoff,
-                               got->br_startblock, got->br_blockcount, &i);
+       if (!(ifp->if_flags & XFS_IFEXTENTS)) {
+               error = xfs_iread_extents(tp, ip, whichfork);
                if (error)
                        return error;
-               XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
+       }
 
-               error = xfs_bmbt_update(cur, &new);
-               if (error)
-                       return error;
-       } else {
-               *logflags |= XFS_ILOG_DEXT;
+       if (ifp->if_flags & XFS_IFBROOT) {
+               cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
+               cur->bc_private.b.firstblock = *firstblock;
+               cur->bc_private.b.dfops = dfops;
+               cur->bc_private.b.flags = 0;
        }
 
-       xfs_iext_update_extent(ifp, *current_ext, &new);
+       if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &current_ext, &got)) {
+               *done = true;
+               goto del_cursor;
+       }
+       XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got.br_startblock));
 
-       if (direction == SHIFT_LEFT)
-               (*current_ext)++;
-       else
-               (*current_ext)--;
+       new_startoff = got.br_startoff - offset_shift_fsb;
+       if (xfs_iext_get_extent(ifp, current_ext - 1, &prev)) {
+               if (new_startoff < prev.br_startoff + prev.br_blockcount) {
+                       error = -EINVAL;
+                       goto del_cursor;
+               }
 
-       /* update reverse mapping */
-       error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, got);
+               if (xfs_bmse_can_merge(&prev, &got, offset_shift_fsb)) {
+                       error = xfs_bmse_merge(ip, whichfork, offset_shift_fsb,
+                                       current_ext, &got, &prev, cur,
+                                       &logflags, dfops);
+                       if (error)
+                               goto del_cursor;
+
+                       /* update got after merge */
+                       if (!xfs_iext_get_extent(ifp, current_ext, &got)) {
+                               *done = true;
+                               goto del_cursor;
+                       }
+                       goto done;
+               }
+       } else {
+               if (got.br_startoff < offset_shift_fsb) {
+                       error = -EINVAL;
+                       goto del_cursor;
+               }
+       }
+
+       error = xfs_bmap_shift_update_extent(ip, whichfork, current_ext, &got,
+                       cur, &logflags, dfops, new_startoff);
        if (error)
-               return error;
-       return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &new);
+               goto del_cursor;
+
+       if (!xfs_iext_get_extent(ifp, ++current_ext, &got)) {
+                *done = true;
+                goto del_cursor;
+       }
+
+done:
+       *next_fsb = got.br_startoff;
+del_cursor:
+       if (cur)
+               xfs_btree_del_cursor(cur,
+                       error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
+       if (logflags)
+               xfs_trans_log_inode(tp, ip, logflags);
+       return error;
 }
 
-/*
- * Shift extent records to the left/right to cover/create a hole.
- *
- * The maximum number of extents to be shifted in a single operation is
- * @num_exts. @stop_fsb specifies the file offset at which to stop shift and the
- * file offset where we've left off is returned in @next_fsb. @offset_shift_fsb
- * is the length by which each extent is shifted. If there is no hole to shift
- * the extents into, this will be considered invalid operation and we abort
- * immediately.
- */
 int
-xfs_bmap_shift_extents(
+xfs_bmap_insert_extents(
        struct xfs_trans        *tp,
        struct xfs_inode        *ip,
        xfs_fileoff_t           *next_fsb,
        xfs_fileoff_t           offset_shift_fsb,
-       int                     *done,
+       bool                    *done,
        xfs_fileoff_t           stop_fsb,
        xfs_fsblock_t           *firstblock,
-       struct xfs_defer_ops    *dfops,
-       enum shift_direction    direction,
-       int                     num_exts)
+       struct xfs_defer_ops    *dfops)
 {
-       struct xfs_btree_cur            *cur = NULL;
-       struct xfs_bmbt_irec            got;
-       struct xfs_mount                *mp = ip->i_mount;
-       struct xfs_ifork                *ifp;
-       xfs_extnum_t                    nexts = 0;
-       xfs_extnum_t                    current_ext;
-       xfs_extnum_t                    total_extents;
-       xfs_extnum_t                    stop_extent;
-       int                             error = 0;
-       int                             whichfork = XFS_DATA_FORK;
-       int                             logflags = 0;
+       int                     whichfork = XFS_DATA_FORK;
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_ifork        *ifp = XFS_IFORK_PTR(ip, whichfork);
+       struct xfs_btree_cur    *cur = NULL;
+       struct xfs_bmbt_irec    got, next, s;
+       xfs_extnum_t            current_ext;
+       xfs_extnum_t            total_extents;
+       xfs_extnum_t            stop_extent;
+       xfs_fileoff_t           new_startoff;
+       int                     error = 0;
+       int                     logflags = 0;
 
        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_ERROR_REPORT("xfs_bmap_shift_extents",
-                                XFS_ERRLEVEL_LOW, mp);
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
                return -EFSCORRUPTED;
        }
 
        if (XFS_FORCED_SHUTDOWN(mp))
                return -EIO;
 
-       ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
-       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-       ASSERT(direction == SHIFT_LEFT || direction == SHIFT_RIGHT);
+       ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL));
 
-       ifp = XFS_IFORK_PTR(ip, whichfork);
        if (!(ifp->if_flags & XFS_IFEXTENTS)) {
-               /* Read in all the extents */
                error = xfs_iread_extents(tp, ip, whichfork);
                if (error)
                        return error;
@@ -5953,7 +5769,7 @@ xfs_bmap_shift_extents(
         */
        total_extents = xfs_iext_count(ifp);
        if (total_extents == 0) {
-               *done = 1;
+               *done = true;
                goto del_cursor;
        }
 
@@ -5961,12 +5777,10 @@ xfs_bmap_shift_extents(
         * In case of first right shift, we need to initialize next_fsb
         */
        if (*next_fsb == NULLFSBLOCK) {
-               ASSERT(direction == SHIFT_RIGHT);
-
                current_ext = total_extents - 1;
                xfs_iext_get_extent(ifp, current_ext, &got);
                if (stop_fsb > got.br_startoff) {
-                       *done = 1;
+                       *done = true;
                        goto del_cursor;
                }
                *next_fsb = got.br_startoff;
@@ -5981,64 +5795,56 @@ xfs_bmap_shift_extents(
                 */
                if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, &current_ext,
                                &got)) {
-                       *done = 1;
+                       *done = true;
                        goto del_cursor;
                }
        }
+       XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got.br_startblock));
 
        /* Lookup the extent index at which we have to stop */
-       if (direction == SHIFT_RIGHT) {
-               struct xfs_bmbt_irec s;
-
-               xfs_iext_lookup_extent(ip, ifp, stop_fsb, &stop_extent, &s);
-               /* Make stop_extent exclusive of shift range */
-               stop_extent--;
-               if (current_ext <= stop_extent) {
-                       error = -EIO;
-                       goto del_cursor;
-               }
-       } else {
-               stop_extent = total_extents;
-               if (current_ext >= stop_extent) {
-                       error = -EIO;
-                       goto del_cursor;
-               }
+       xfs_iext_lookup_extent(ip, ifp, stop_fsb, &stop_extent, &s);
+       /* Make stop_extent exclusive of shift range */
+       stop_extent--;
+       if (current_ext <= stop_extent) {
+               error = -EIO;
+               goto del_cursor;
        }
 
-       while (nexts++ < num_exts) {
-               error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb,
-                                          &current_ext, &got, cur, &logflags,
-                                          direction, dfops);
-               if (error)
+       new_startoff = got.br_startoff + offset_shift_fsb;
+       if (current_ext < total_extents - 1) {
+               xfs_iext_get_extent(ifp, current_ext + 1, &next);
+               if (new_startoff + got.br_blockcount > next.br_startoff) {
+                       error = -EINVAL;
                        goto del_cursor;
-               /*
-                * If there was an extent merge during the shift, the extent
-                * count can change. Update the total and grade the next record.
-                */
-               if (direction == SHIFT_LEFT) {
-                       total_extents = xfs_iext_count(ifp);
-                       stop_extent = total_extents;
                }
 
-               if (current_ext == stop_extent) {
-                       *done = 1;
-                       *next_fsb = NULLFSBLOCK;
-                       break;
-               }
-               xfs_iext_get_extent(ifp, current_ext, &got);
+               /*
+                * Unlike a left shift (which involves a hole punch), a right
+                * shift does not modify extent neighbors in any way.  We should
+                * never find mergeable extents in this scenario.  Check anyways
+                * and warn if we encounter two extents that could be one.
+                */
+               if (xfs_bmse_can_merge(&got, &next, offset_shift_fsb))
+                       WARN_ON_ONCE(1);
        }
 
-       if (!*done)
-               *next_fsb = got.br_startoff;
+       error = xfs_bmap_shift_update_extent(ip, whichfork, current_ext, &got,
+                       cur, &logflags, dfops, new_startoff);
+       if (error)
+               goto del_cursor;
+       if (--current_ext == stop_extent) {
+               *done = true;
+               goto del_cursor;
+       }
+       xfs_iext_get_extent(ifp, current_ext, &got);
 
+       *next_fsb = got.br_startoff;
 del_cursor:
        if (cur)
                xfs_btree_del_cursor(cur,
                        error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
-
        if (logflags)
                xfs_trans_log_inode(tp, ip, logflags);
-
        return error;
 }
 
@@ -6106,17 +5912,15 @@ xfs_bmap_split_extent_at(
                cur->bc_private.b.firstblock = *firstfsb;
                cur->bc_private.b.dfops = dfops;
                cur->bc_private.b.flags = 0;
-               error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
-                               got.br_startblock,
-                               got.br_blockcount,
-                               &i);
+               error = xfs_bmbt_lookup_eq(cur, &got, &i);
                if (error)
                        goto del_cursor;
                XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor);
        }
 
        got.br_blockcount = gotblkcnt;
-       xfs_iext_update_extent(ifp, current_ext, &got);
+       xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork),
+                       current_ext, &got);
 
        logflags = XFS_ILOG_CORE;
        if (cur) {
@@ -6133,14 +5937,10 @@ xfs_bmap_split_extent_at(
                           XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
 
        if (cur) {
-               error = xfs_bmbt_lookup_eq(cur, new.br_startoff,
-                               new.br_startblock, new.br_blockcount,
-                               &i);
+               error = xfs_bmbt_lookup_eq(cur, &new, &i);
                if (error)
                        goto del_cursor;
                XFS_WANT_CORRUPTED_GOTO(mp, i == 0, del_cursor);
-               cur->bc_rec.b.br_state = new.br_state;
-
                error = xfs_btree_insert(cur, &i);
                if (error)
                        goto del_cursor;